This is the start of the stable review cycle for the 5.15.121 release. There are 532 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 Sun, 23 Jul 2023 16:04:40 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.121-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 5.15.121-rc1
Pedro Tammela pctammela@mojatatu.com net/sched: sch_qfq: reintroduce lmax bound check for MTU
Thomas Bogendoerfer tsbogend@alpha.franken.de MIPS: kvm: Fix build error with KVM_MIPS_DEBUG_COP0_COUNTERS enabled
Manish Rangankar mrangankar@marvell.com scsi: qla2xxx: Remove unused nvme_ls_waitq wait queue
Shreyas Deodhar sdeodhar@marvell.com scsi: qla2xxx: Pointer may be dereferenced
Bikash Hazarika bhazarika@marvell.com scsi: qla2xxx: Correct the index of array
Nilesh Javali njavali@marvell.com scsi: qla2xxx: Check valid rport returned by fc_bsg_to_rport()
Bikash Hazarika bhazarika@marvell.com scsi: qla2xxx: Fix potential NULL pointer dereference
Quinn Tran qutran@marvell.com scsi: qla2xxx: Fix buffer overrun
Nilesh Javali njavali@marvell.com scsi: qla2xxx: Avoid fcport pointer dereference
Nilesh Javali njavali@marvell.com scsi: qla2xxx: Array index may go out of bound
Quinn Tran qutran@marvell.com scsi: qla2xxx: Wait for io return on terminate rport
Masami Hiramatsu (Google) mhiramat@kernel.org tracing/probes: Fix to update dynamic data counter if fetcharg uses it
Masami Hiramatsu (Google) mhiramat@kernel.org tracing/probes: Fix not to count error code to total length
Matthieu Baerts matthieu.baerts@tessares.net selftests: mptcp: depend on SYN_COOKIES
Matthieu Baerts matthieu.baerts@tessares.net selftests: mptcp: sockopt: return error if wrong mark
Mateusz Stachyra m.stachyra@samsung.com tracing: Fix null pointer dereference in tracing_err_log_open()
Max Filippov jcmvbkbc@gmail.com xtensa: ISS: fix call to split_if_spec
Zheng Yejian zhengyejian1@huawei.com ftrace: Fix possible warning on checking all pages used in ftrace_process_locs()
Zheng Yejian zhengyejian1@huawei.com ring-buffer: Fix deadloop issue on reading trace_pipe
Krister Johansen kjlx@templeofstupid.com net: ena: fix shift-out-of-bounds in exponential backoff
Florent Revest revest@chromium.org samples: ftrace: Save required argument registers in sample trampolines
Zheng Yejian zhengyejian1@huawei.com tracing: Fix memory leak of iter->temp when reading trace_pipe
Mohamed Khalfella mkhalfella@purestorage.com tracing/histograms: Add histograms to hist_vars if they have referenced variables
Heiko Carstens hca@linux.ibm.com s390/decompressor: fix misaligned symbol build error
Jonas Gorski jonas.gorski@gmail.com bus: ixp4xx: fix IXP4XX_EXP_T1_MASK
Jiaqing Zhao jiaqing.zhao@linux.intel.com Revert "8250: add support for ASIX devices with a FIFO bug"
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org soundwire: qcom: fix storing port config out-of-bounds
Stephan Gerhold stephan.gerhold@kernkonzept.com opp: Fix use-after-free in lazy_opp_tables after probe deferral
George Stark gnstark@sberdevices.ru meson saradc: fix clock divider mask length
Weitao Wang WeitaoWang-oc@zhaoxin.com xhci: Show ZHAOXIN xHCI root hub speed correctly
Weitao Wang WeitaoWang-oc@zhaoxin.com xhci: Fix TRB prefetch issue of ZHAOXIN hosts
Weitao Wang WeitaoWang-oc@zhaoxin.com xhci: Fix resume issue of some ZHAOXIN hosts
Xiubo Li xiubli@redhat.com ceph: don't let check_caps skip sending responses for revoke msgs
Ilya Dryomov idryomov@gmail.com libceph: harden msgr2.1 frame segment length checks
Christophe JAILLET christophe.jaillet@wanadoo.fr firmware: stratix10-svc: Fix a potential resource leak in svc_create_memory_pool()
Martin Fuzzey martin.fuzzey@flowbird.group tty: serial: imx: fix rs485 rx after tx
Christophe JAILLET christophe.jaillet@wanadoo.fr tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() when iterating clk
Christophe JAILLET christophe.jaillet@wanadoo.fr tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() in case of error
Dan Carpenter dan.carpenter@linaro.org serial: atmel: don't enable IRQs prematurely
Christian König christian.koenig@amd.com drm/ttm: never consider pinned BOs for eviction&swap
Thomas Hellström thomas.hellstrom@linux.intel.com drm/ttm: Don't leak a resource on swapout move error
gaba gaba@amd.com drm/amdgpu: avoid restore process run into dead loop.
Mario Limonciello mario.limonciello@amd.com drm/amd/display: Correct `DMUB_FW_VERSION` macro
Samuel Pitoiset samuel.pitoiset@gmail.com drm/amdgpu: fix clearing mappings for BOs that are always valid in VM
Brian Norris briannorris@chromium.org drm/rockchip: vop: Leave vblank enabled in self-refresh
Brian Norris briannorris@chromium.org drm/atomic: Allow vblank-enabled + self-refresh "disable"
Alexander Aring aahringo@redhat.com fs: dlm: return positive pid value for F_GETLK
Peter Korsgaard peter@korsgaard.com dm init: add dm-mod.waitfor to wait for asynchronously probed block devices
Jason Baron jbaron@akamai.com md/raid0: add discard support for the 'original' layout
Johan Hovold johan+linaro@kernel.org mfd: pm8008: Fix module autoloading
Damien Le Moal dlemoal@kernel.org misc: pci_endpoint_test: Re-init completion for every test
Damien Le Moal dlemoal@kernel.org misc: pci_endpoint_test: Free IRQs before removing the device
Damien Le Moal dlemoal@kernel.org PCI: rockchip: Set address alignment for endpoint mode
Rick Wertenbroek rick.wertenbroek@gmail.com PCI: rockchip: Use u32 variable to access 32-bit registers
Rick Wertenbroek rick.wertenbroek@gmail.com PCI: rockchip: Fix legacy IRQ generation for RK3399 PCIe endpoint core
Rick Wertenbroek rick.wertenbroek@gmail.com PCI: rockchip: Add poll and timeout to wait for PHY PLLs to be locked
Rick Wertenbroek rick.wertenbroek@gmail.com PCI: rockchip: Write PCI Device ID to correct register
Rick Wertenbroek rick.wertenbroek@gmail.com PCI: rockchip: Assert PCI Configuration Enable bit after probe
Manivannan Sadhasivam mani@kernel.org PCI: qcom: Disable write access to read only registers for IP v2.3.3
Igor Mammedov imammedo@redhat.com PCI: acpiphp: Reassign resources on bridge if necessary
Robin Murphy robin.murphy@arm.com PCI: Add function 1 DMA alias quirk for Marvell 88SE9235
Ondrej Zary linux@zary.sk PCI/PM: Avoid putting EloPOS E2/S2/H2 PCIe Ports in D3cold
Mikulas Patocka mpatocka@redhat.com dm integrity: reduce vmalloc space footprint on 32-bit architectures
Martin Kaiser martin@kaiser.cx hwrng: imx-rngc - fix the timeout for init and self check
Siddh Raman Pant code@siddh.me jfs: jfs_dmap: Validate db_l2nbperpage while mounting
Baokun Li libaokun1@huawei.com ext4: only update i_reserved_data_blocks on successful block allocation
Baokun Li libaokun1@huawei.com ext4: turn quotas off if mount failed after enabling quotas
Chao Yu chao@kernel.org ext4: fix to check return value of freeze_bdev() in ext4_shutdown()
Kemeng Shi shikemeng@huaweicloud.com ext4: fix wrong unit use in ext4_mb_new_blocks
Kemeng Shi shikemeng@huaweicloud.com ext4: get block from bh in ext4_free_blocks for fast commit replay
Kemeng Shi shikemeng@huaweicloud.com ext4: fix wrong unit use in ext4_mb_clear_bb
Zhihao Cheng chengzhihao1@huawei.com ext4: Fix reusing stale buffer heads from last failed mounting
Huacai Chen chenhuacai@kernel.org MIPS: KVM: Fix NULL pointer dereference
Huacai Chen chenhuacai@kernel.org MIPS: Loongson: Fix cpu_probe_loongson() again
Gao Xiang hsiangkao@linux.alibaba.com erofs: fix compact 4B support for 16k block size
Suzuki K Poulose suzuki.poulose@arm.com arm64: errata: Add detection for TRBE overwrite in FILL mode
Michael Ellerman mpe@ellerman.id.au powerpc/security: Fix Speculation_Store_Bypass reporting on Power10
Ekansh Gupta quic_ekangupt@quicinc.com misc: fastrpc: Create fastrpc scalar with correct buffer count
Naveen N Rao naveen@kernel.org powerpc: Fail build if using recordmcount with binutils v2.37
Ryan Roberts ryan.roberts@arm.com mm/damon/ops-common: atomically test and clear young on ptes and pmds
Florian Fainelli florian.fainelli@broadcom.com net: bcmgenet: Ensure MDIO unregistration has clocks enabled
Arseniy Krasnov AVKrasnov@sberdevices.ru mtd: rawnand: meson: fix unaligned DMA buffers handling
Jarkko Sakkinen jarkko.sakkinen@tuni.fi tpm: tpm_vtpm_proxy: fix a race condition in /dev/vtpmx creation
Mario Limonciello mario.limonciello@amd.com pinctrl: amd: Only use special debounce behavior for GPIO 0
Kornel Dulęba korneld@chromium.org pinctrl: amd: Detect and mask spurious interrupts
Mario Limonciello mario.limonciello@amd.com pinctrl: amd: Detect internal GPIO0 debounce handling
Mario Limonciello mario.limonciello@amd.com pinctrl: amd: Fix mistake in handling clearing pins at startup
Chao Yu chao@kernel.org f2fs: fix to avoid NULL pointer dereference f2fs_write_end_io()
Konstantin Komarov almaz.alexandrovich@paragon-software.com fs/ntfs3: Check fields while reading
Ming Lei ming.lei@redhat.com nvme-pci: fix DMA direction of unmapping integrity data
Keith Busch kbusch@kernel.org nvme-pci: remove nvme_queue from nvme_iod
Pedro Tammela pctammela@mojatatu.com net/sched: sch_qfq: account for stab overhead in qfq_enqueue
Pedro Tammela pctammela@mojatatu.com net/sched: sch_qfq: refactor parsing of netlink parameters
Pedro Tammela pctammela@mojatatu.com net/sched: make psched_mtu() RTNL-less safe
Dan Carpenter dan.carpenter@linaro.org netdevsim: fix uninitialized data in nsim_dev_trap_fa_cookie_write()
Jisheng Zhang jszhang@kernel.org riscv: mm: fix truncation warning on RV32
Ido Schimmel idosch@nvidia.com net/sched: flower: Ensure both minimum and maximum ports are specified
Pu Lehui pulehui@huawei.com bpf: cpumap: Fix memory leak in cpu_map_update_elem
Randy Dunlap rdunlap@infradead.org wifi: airo: avoid uninitialized warning in airo_get_rate()
Xin Yin yinxin.x@bytedance.com erofs: fix fsdax unavailability for chunk-based regular files
Gao Xiang hsiangkao@linux.alibaba.com erofs: decouple basic mount options from fs_context
Chunhai Guo guochunhai@vivo.com erofs: avoid infinite loop in z_erofs_do_read_page() when reading beyond EOF
Suman Ghosh sumang@marvell.com octeontx2-pf: Add additional check for MCAM rules
Tvrtko Ursulin tvrtko.ursulin@intel.com drm/i915: Fix one wrong caching mode enum usage
Björn Töpel bjorn@rivosinc.com riscv, bpf: Fix inconsistent JIT image generation
Pu Lehui pulehui@huawei.com bpf, riscv: Support riscv jit to provide bpf_line_info
Florian Kauer florian.kauer@linutronix.de igc: Fix inserting of empty frame for launchtime
Florian Kauer florian.kauer@linutronix.de igc: Fix launchtime before start of cycle
Tzvetomir Stoyanov (VMware) tz.stoyanov@gmail.com kernel/trace: Fix cleanup logic of enable_trace_eprobe
Andy Shevchenko andriy.shevchenko@linux.intel.com platform/x86: wmi: Break possible infinite loop when parsing GUID
Barnabás Pőcze pobrn@protonmail.com platform/x86: wmi: move variables
Barnabás Pőcze pobrn@protonmail.com platform/x86: wmi: use guid_t and guid_equal()
Barnabás Pőcze pobrn@protonmail.com platform/x86: wmi: remove unnecessary argument
Ziyang Xuan william.xuanziyang@huawei.com ipv6/addrconf: fix a potential refcount underflow for idev
Jiasheng Jiang jiasheng@iscas.ac.cn NTB: ntb_tool: Add check for devm_kcalloc
Yang Yingliang yangyingliang@huawei.com NTB: ntb_transport: fix possible memory leak while device_register() fails
Yuan Can yuancan@huawei.com ntb: intel: Fix error handling in intel_ntb_pci_driver_init()
Yuan Can yuancan@huawei.com NTB: amd: Fix error handling in amd_ntb_pci_driver_init()
Yuan Can yuancan@huawei.com ntb: idt: Fix error handling in idt_pci_driver_init()
Eric Dumazet edumazet@google.com udp6: fix udp6_ehashfn() typo
Kuniyuki Iwashima kuniyu@amazon.com icmp6: Fix null-ptr-deref of ip6_null_entry->rt6i_idev in icmp6_dev().
Paolo Abeni pabeni@redhat.com net: prevent skb corruption on frag list segmentation
Rafał Miłecki rafal@milecki.pl net: bgmac: postpone turning IRQs off to avoid SoC hangs
Nitya Sunkad nitya.sunkad@amd.com ionic: remove WARN_ON to prevent panic_on_warn
Junfeng Guo junfeng.guo@intel.com gve: Set default duplex configuration to full
M A Ramdhan ramdhan@starlabs.sg net/sched: cls_fw: Fix improper refcount update leads to use-after-free
Klaus Kudielka klaus.kudielka@gmail.com net: mvneta: fix txq_map in case of txq_number==1
Kumar Kartikeya Dwivedi memxor@gmail.com bpf: Fix max stack depth check for async callbacks
Dan Carpenter dan.carpenter@linaro.org scsi: qla2xxx: Fix error code in qla2x00_start_sp()
Aravindhan Gunasekaran aravindhan.gunasekaran@intel.com igc: Handle PPS start time programming for past time values
Prasad Koya prasad@arista.com igc: set TP bit in 'supported' and 'advertising' fields of ethtool_link_ksettings
Vlad Buslov vladbu@nvidia.com net/mlx5e: Check for NOT_READY flag state after locking
Zhengchao Shao shaozhengchao@huawei.com net/mlx5e: fix memory leak in mlx5e_ptp_open
Zhengchao Shao shaozhengchao@huawei.com net/mlx5e: fix double free in mlx5e_destroy_flow_table
Muhammad Husaini Zulkifli muhammad.husaini.zulkifli@intel.com igc: Remove delay during TX ring configuration
Marek Vasut marex@denx.de drm/panel: simple: Add Powertip PH800480T013 drm_display_mode flags
Douglas Anderson dianders@chromium.org drm/bridge: ti-sn65dsi86: Fix auxiliary bus lifetime
Fabio Estevam festevam@denx.de drm/panel: simple: Add connector_type for innolux_at043tn24
Namjae Jeon linkinjeon@kernel.org ksmbd: validate session id and tree id in the compound request
Namjae Jeon linkinjeon@kernel.org ksmbd: fix out-of-bound read in smb2_write
Namjae Jeon linkinjeon@kernel.org ksmbd: validate command payload size
Ralph Boehme slow@samba.org ksmbd: use ksmbd_req_buf_next() in ksmbd_smb2_check_message()
Linus Torvalds torvalds@linux-foundation.org workqueue: clean up WORK_* constant types, clarify masking
Moritz Fischer moritzf@google.com net: lan743x: Don't sleep in atomic context
Jens Axboe axboe@kernel.dk io_uring: add reschedule point to handle_tw_list()
Andres Freund andres@anarazel.de io_uring: Use io_schedule* in cqring wait
Michael Schmitz schmitzmic@gmail.com block/partition: fix signedness issue for Amiga partitions
Sherry Sun sherry.sun@nxp.com tty: serial: fsl_lpuart: add earlycon for imx8ulp platform
Jason A. Donenfeld Jason@zx2c4.com wireguard: netlink: send staged packets when setting initial private key
Jason A. Donenfeld Jason@zx2c4.com wireguard: queueing: use saner cpu selection wrapping
Thadeu Lima de Souza Cascardo cascardo@canonical.com netfilter: nf_tables: prevent OOB access in nft_byteorder_eval
Thadeu Lima de Souza Cascardo cascardo@canonical.com netfilter: nf_tables: do not ignore genmask when looking up chain by id
Florent Revest revest@chromium.org netfilter: conntrack: Avoid nf_ct_helper_hash uses after free
Pablo Neira Ayuso pablo@netfilter.org netfilter: nf_tables: unbind non-anonymous set if rule construction fails
Amir Goldstein amir73il@gmail.com fanotify: disallow mount/sb marks on kernel internal pseudo fs
Zhihao Cheng chengzhihao1@huawei.com ovl: fix null pointer dereference in ovl_get_acl_rcu()
Jan Kara jack@suse.cz fs: no need to check source
Christian Marangi ansuelsmth@gmail.com leds: trigger: netdev: Recheck NETDEV_LED_MODE_LINKUP on dev rename
Arnd Bergmann arnd@arndb.de ARM: orion5x: fix d2net gpio initialization
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: qcom: ipq4019: fix broken NAND controller properties override
Ricardo Ribalda Delgado ribalda@chromium.org ASoC: mediatek: mt8173: Fix snd_soc_component_initialize error path
Ricardo Ribalda Delgado ribalda@chromium.org ASoC: mediatek: mt8173: Fix irq error path
Filipe Manana fdmanana@suse.com btrfs: do not BUG_ON() on tree mod log failure at __btrfs_cow_block()
Filipe Manana fdmanana@suse.com btrfs: fix extent buffer leak after tree mod log failure at split_node()
Filipe Manana fdmanana@suse.com btrfs: fix race when deleting quota root from the dirty cow roots list
Naohiro Aota naota@elisp.net btrfs: reinsert BGs failed to reclaim
Naohiro Aota naota@elisp.net btrfs: bail out reclaim process if filesystem is read-only
Naohiro Aota naota@elisp.net btrfs: delete unused BGs while reclaiming BGs
Matt Corallo blnxfsl@bluematt.me btrfs: add handling for RAID1C23/DUP to btrfs_reduce_alloc_profile
Thomas Weißschuh linux@weissschuh.net fs: avoid empty option when generating legacy mount string
Fabian Frederick fabf@skynet.be jffs2: reduce stack usage in jffs2_build_xattr_subsystem()
Abhijeet Rastogi abhijeet.1989@gmail.com ipvs: increase ip_vs_conn_tab_bits range for 64BIT
Jan Kara jack@suse.cz fs: Lock moved directories
Jan Kara jack@suse.cz fs: Establish locking order for unrelated directories
Jan Kara jack@suse.cz Revert "f2fs: fix potential corruption when moving a directory"
Jan Kara jack@suse.cz ext4: Remove ext4 locking of moved directory
Roberto Sassu roberto.sassu@huawei.com shmem: use ramfs_kill_sb() for kill_sb method of ramfs-based tmpfs
Arnd Bergmann arnd@arndb.de autofs: use flexible array in ioctl structure
Tianjia Zhang tianjia.zhang@linux.alibaba.com integrity: Fix possible multiple allocation in integrity_inode_get()
Kees Cook keescook@chromium.org um: Use HOST_DIR for mrproper
Zheng Wang zyytlz.wz@163.com bcache: Fix __bch_btree_node_alloc to make the failure behavior consistent
Zheng Wang zyytlz.wz@163.com bcache: Remove unnecessary NULL point check in node allocations
Mingzhe Zou mingzhe.zou@easystack.cn bcache: fixup btree_cache_wait list damage
Chevron Li chevron.li@bayhubtech.com mmc: sdhci: fix DMA configure compatibility issue when 64bit DMA mode is used.
Ulf Hansson ulf.hansson@linaro.org mmc: mmci: Set PROBE_PREFER_ASYNCHRONOUS
Robert Marko robimarko@gmail.com mmc: core: disable TRIM on Micron MTFC4GACAJCN-1M
Robert Marko robimarko@gmail.com mmc: core: disable TRIM on Kingston EMMC04G-M627
Jens Axboe axboe@kernel.dk io_uring: wait interruptibly for request completions on exit
Dai Ngo dai.ngo@oracle.com NFSD: add encoding of op_recall flag for write delegation
Shuai Jiang d202180596@hust.edu.cn i2c: qup: Add missing unwind goto in qup_i2c_probe()
Filipe Manana fdmanana@suse.com btrfs: do not BUG_ON() on tree mod log failure at balance_level()
Uwe Kleine-König u.kleine-koenig@pengutronix.de extcon: usbc-tusb320: Convert to i2c's .probe_new()
Robert Hancock robert.hancock@calian.com i2c: xiic: Don't try to handle more interrupt events after error
Marek Vasut marex@denx.de i2c: xiic: Defer xiic_wakeup() and __xiic_start_xfer() in xiic_process()
Danila Chernetsov listdansp@mail.ru apparmor: fix missing error check for rhashtable_insert_fast
Artur Rojek contact@artur-rojek.eu sh: dma: Fix DMA channel offset calculation
Thorsten Winkler twinkler@linux.ibm.com s390/qeth: Fix vipa deletion
Hariprasad Kelam hkelam@marvell.com octeontx-af: fix hardware timestamp configuration
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: tag_sja1105: fix MAC DA patching from meta frames
Guillaume Nault gnault@redhat.com pptp: Fix fib lookup calls.
Woody Zhang woodylab@foxmail.com riscv: move memblock_allow_resize() after linear mapping is ready
Lin Ma linma@zju.edu.cn net/sched: act_pedit: Add size check for TCA_PEDIT_PARMS_EX
Ilya Maximets i.maximets@ovn.org xsk: Honor SO_BINDTODEVICE on bind
Eric Dumazet edumazet@google.com tcp: annotate data races in __tcp_oow_rate_limited()
Vladimir Oltean vladimir.oltean@nxp.com net: bridge: keep ports without IFF_UNICAST_FLT in BR_PROMISC mode
Randy Dunlap rdunlap@infradead.org powerpc: allow PPC_EARLY_DEBUG_CPM only when SERIAL_CPM=y
Zeng Heng zengheng4@huawei.com ntfs: Fix panic about slab-out-of-bounds caused by ntfs_listxattr()
Hariprasad Kelam hkelam@marvell.com octeontx2-af: Add validation before accessing cgx and lmac
Hariprasad Kelam hkelam@marvell.com octeontx2-af: Fix mapping for NIX block from CGX connection
Chao Yu chao@kernel.org f2fs: fix error path handling in truncate_dnode()
Nishanth Menon nm@ti.com mailbox: ti-msgmgr: Fill non-message tx data fields with 0x0
Jonas Gorski jonas.gorski@gmail.com spi: bcm-qspi: return error if neither hif_mspi nor mspi is available
Pawel Dembicki paweldembicki@gmail.com net: dsa: vsc73xx: fix MTU configuration
Nick Child nnac123@linux.ibm.com ibmvnic: Do not reset dql stats on NON_FATAL err
Tobias Heider me@tobhe.de Add MODULE_FIRMWARE() for FIRMWARE_TG357766.
Florian Westphal fw@strlen.de net/sched: act_ipt: add sanity checks on table name and hook locations
Chengfeng Ye dg573847474@gmail.com sctp: fix potential deadlock on &net->sctp.addr_wq_lock
Randy Dunlap rdunlap@infradead.org media: cec: i2c: ch7322: also select REGMAP
Jouni Högander jouni.hogander@intel.com drm/i915/psr: Use hw.adjusted mode when calculating io/fast wake times
Christophe JAILLET christophe.jaillet@wanadoo.fr rtc: st-lpc: Release some resources in st_rtc_probe() in case of error
Li Nan linan122@huawei.com md/raid10: fix the condition to call bio_end_io_acct()
Shuijing Li shuijing.li@mediatek.com pwm: mtk_disp: Fix the disable flow of disp_pwm
Dan Carpenter dan.carpenter@linaro.org pwm: ab8500: Fix error code in probe()
Marek Vasut marex@denx.de pwm: sysfs: Do not apply state to already disabled PWMs
Fancy Fang chen.fang@nxp.com pwm: imx-tpm: force 'real_period' to be zero in suspend
Claudiu Beznea claudiu.beznea@microchip.com phy: tegra: xusb: check return value of devm_kzalloc()
Christophe JAILLET christophe.jaillet@wanadoo.fr mfd: stmpe: Only disable the regulators if they are enabled
Christian Borntraeger borntraeger@linux.ibm.com KVM: s390/diag: fix racy access of physical cpu number in diag 9c handler
Pierre Morel pmorel@linux.ibm.com KVM: s390: vsie: fix the length of APCB bitmap
Amelie Delaunay amelie.delaunay@foss.st.com mfd: stmfx: Nullify stmfx->vdd in case of error
Amelie Delaunay amelie.delaunay@foss.st.com mfd: stmfx: Fix error path in stmfx_chip_init
Phil Elwell phil@raspberrypi.com nvmem: rmem: Use NVMEM_DEVID_AUTO
Mirsad Goran Todorovac mirsad.todorovac@alu.unizg.hr test_firmware: return ENOMEM instead of ENOSPC on failed memory allocation
Tony Lindgren tony@atomide.com serial: 8250_omap: Use force_suspend and resume for system suspend
Greg Kroah-Hartman gregkh@linuxfoundation.org Revert "usb: common: usb-conn-gpio: Set last role to unknown before initial detection"
Jiasheng Jiang jiasheng@iscas.ac.cn mfd: intel-lpss: Add missing check for platform_get_resource
Christophe JAILLET christophe.jaillet@wanadoo.fr usb: dwc3-meson-g12a: Fix an error handling path in dwc3_meson_g12a_probe()
Prashanth K quic_prashk@quicinc.com usb: common: usb-conn-gpio: Set last role to unknown before initial detection
Christophe JAILLET christophe.jaillet@wanadoo.fr usb: dwc3: qcom: Fix an error handling path in dwc3_qcom_probe()
Christophe JAILLET christophe.jaillet@wanadoo.fr usb: dwc3: qcom: Release the correct resources in dwc3_qcom_remove()
Nico Boehr nrb@linux.ibm.com KVM: s390: fix KVM_S390_GET_CMMA_BITS for GFNs in memslot holes
Dan Carpenter dan.carpenter@linaro.org media: atomisp: gmin_platform: fix out_len in gmin_get_config_dsm_var()
Rikard Falkeborn rikard.falkeborn@gmail.com media: venus: helpers: Fix ALIGN() of non power of two
Stephan Gerhold stephan@gerhold.net mfd: rt5033: Drop rt5033-battery sub-device
James Clark james.clark@arm.com coresight: Fix loss of connection info when a module is unloaded
Muchun Song songmuchun@bytedance.com kernfs: fix missing kernfs_idr_lock to remove an ID from the IDR
John Ogness john.ogness@linutronix.de serial: 8250: lock port for UART_IER access in omap8250_irq()
John Ogness john.ogness@linutronix.de serial: 8250: lock port for stop_rx() in omap8250_irq()
Arnd Bergmann arnd@arndb.de usb: hide unused usbfs_notify_suspend/resume functions
Li Yang lidaxian@hust.edu.cn usb: phy: phy-tahvo: fix memory leak in tahvo_usb_probe()
Andy Shevchenko andriy.shevchenko@linux.intel.com extcon: Fix kernel doc of property capability fields to avoid warnings
Andy Shevchenko andriy.shevchenko@linux.intel.com extcon: Fix kernel doc of property fields to avoid warnings
Prashanth K quic_prashk@quicinc.com usb: gadget: u_serial: Add null pointer check in gserial_suspend
Vladislav Efanov VEfanov@ispras.ru usb: dwc3: qcom: Fix potential memory leak
Robert Marko robimarko@gmail.com clk: qcom: ipq6018: fix networking resets
Robert Marko robimarko@gmail.com clk: qcom: reset: support resetting multiple bits
Stephan Gerhold stephan.gerhold@kernkonzept.com clk: qcom: reset: Allow specifying custom reset delay
Daniel Scally dan.scally@ideasonboard.com media: i2c: Correct format propagation for st-mipid02
Duoming Zhou duoming@zju.edu.cn media: usb: siano: Fix warning due to null work_func_t function pointer
Marek Vasut marex@denx.de media: videodev2.h: Fix struct v4l2_input tuner index comment
Daniil Dulov d.dulov@aladdin.ru media: usb: Check az6007_read() return value
Mantas Pucka mantas@8devices.com clk: qcom: gcc-ipq6018: Use floor ops for sdcc clocks
Taniya Das quic_tdas@quicinc.com clk: qcom: camcc-sc7180: Add parent dependency to all camera GDSCs
Tony Lindgren tony@atomide.com serial: 8250: omap: Fix freeing of resources on failed register
Christophe JAILLET christophe.jaillet@wanadoo.fr usb: dwc2: Fix some error handling paths
Uwe Kleine-König u.kleine-koenig@pengutronix.de usb: dwc2: platform: Improve error reporting for problems during .remove()
John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de sh: j2: Use ioremap() to translate device tree address into kernel memory
Dan Carpenter dan.carpenter@oracle.com w1: fix loop in w1_fini()
Stefan Wahren stefan.wahren@i2se.com w1: w1_therm: fix locking behavior in convert_t
Ding Hui dinghui@sangfor.com.cn SUNRPC: Fix UAF in svc_tcp_listen_data_ready()
Demi Marie Obenour demi@invisiblethingslab.com block: increment diskseq on all media change events
Michael Schmitz schmitzmic@gmail.com block: change all __u32 annotations to __be32 in affs_hardblocks.h
Michael Schmitz schmitzmic@gmail.com block: add overflow checks for Amiga partition support
Michael Schmitz schmitzmic@gmail.com block: fix signed int overflow in Amiga partition support
Takashi Iwai tiwai@suse.de ALSA: jack: Fix mutex call in snd_jack_report()
Werner Sembach wse@tuxedocomputers.com ALSA: hda/realtek: Add quirk for Clevo NPx0SNx
Sean Nyekjaer sean@geanix.com iio: accel: fxls8962af: fixup buffer scan element type
Sean Nyekjaer sean@geanix.com iio: accel: fxls8962af: errata bug only applicable for FXLS8962AF
Fabrizio Lamarque fl.scratchpad@gmail.com iio: adc: ad7192: Fix internal/external clock selection
Fabrizio Lamarque fl.scratchpad@gmail.com iio: adc: ad7192: Fix null ad7192_state pointer access
EJ Hsu ejh@nvidia.com phy: tegra: xusb: Clear the driver reference in usb-phy dev
Krishna Kurapati quic_kriskura@quicinc.com usb: dwc3: gadget: Propagate core init errors to UDC during pullup
Davide Tronchin davide.tronchin.94@gmail.com USB: serial: option: add LARA-R6 01B PIDs
Jens Axboe axboe@kernel.dk io_uring: ensure IOPOLL locks around deferred work
Liu Shixin liushixin2@huawei.com bootmem: remove the vmemmap pages from kmemleak in free_bootmem_page
Kiran K kiran.k@intel.com ACPI: utils: Fix acpi_evaluate_dsm_typed() redefinition error
Arnd Bergmann arnd@arndb.de ksmbd: avoid field overflow warning
Ard Biesheuvel ardb@kernel.org efi/libstub: Disable PCI DMA before grabbing the EFI memory map
Sami Tolvanen samitolvanen@google.com kbuild: Disable GCOV for *.mod.o
Martin Kaiser martin@kaiser.cx hwrng: st - keep clock enabled while hwrng is registered
Tarun Sahu tsahu@linux.ibm.com dax/kmem: Pass valid argument to memory_group_register_static
Dan Williams dan.j.williams@intel.com dax: Introduce alloc_dev_dax_id()
Dan Williams dan.j.williams@intel.com dax: Fix dax_mapping_release() use after free
Bharath SM bharathsm@microsoft.com SMB3: Do not send lease break acknowledgment if all file handles have been closed
Olga Kornievskaia kolga@netapp.com NFSv4.1: freeze the session table upon receiving NFS4ERR_BADSESSION
Hareshx Sankar Raj hareshx.sankar.raj@intel.com crypto: qat - unmap buffers before free for RSA
Hareshx Sankar Raj hareshx.sankar.raj@intel.com crypto: qat - unmap buffer before free for DH
Herbert Xu herbert@gondor.apana.org.au crypto: qat - Use helper to set reqsize
Herbert Xu herbert@gondor.apana.org.au crypto: kpp - Add helper to set reqsize
Damian Muszynski damian.muszynski@intel.com crypto: qat - use reference to structure in dma_map_single()
Andre Przywara andre.przywara@arm.com crypto: qat - replace get_current_node() with numa_node_id()
Giovanni Cabiddu giovanni.cabiddu@intel.com crypto: qat - honor CRYPTO_TFM_REQ_MAY_SLEEP flag
Masahiro Yamada masahiroy@kernel.org ARC: define ASM_NL and __ALIGN(_STR) outside #ifdef __ASSEMBLY__ guard
Dan Carpenter dan.carpenter@linaro.org modpost: fix off by one in is_executable_section()
Arnd Bergmann arnd@arndb.de crypto: marvell/cesa - Fix type mismatch warning
Masahiro Yamada masahiroy@kernel.org modpost: fix section mismatch message for R_ARM_{PC24,CALL,JUMP24}
Masahiro Yamada masahiroy@kernel.org modpost: fix section mismatch message for R_ARM_ABS32
Randy Dunlap rdunlap@infradead.org crypto: nx - fix build warnings when DEBUG_FS is not enabled
Masahiro Yamada masahiroy@kernel.org modpost: remove broken calculation of exception_table_entry size
Herbert Xu herbert@gondor.apana.org.au hwrng: virtio - Fix race on data_avail and actual data
Laurent Vivier lvivier@redhat.com hwrng: virtio - always add a pending request
Laurent Vivier lvivier@redhat.com hwrng: virtio - don't waste entropy
Laurent Vivier lvivier@redhat.com hwrng: virtio - don't wait on cleanup
Laurent Vivier lvivier@redhat.com hwrng: virtio - add an internal buffer
Aneesh Kumar K.V aneesh.kumar@linux.ibm.com powerpc/mm/dax: Fix the condition when checking if altmap vmemap can cross-boundary
Aneesh Kumar K.V aneesh.kumar@linux.ibm.com powerpc/book3s64/mm: Fix DirectMap stats in /proc/meminfo
Tiezhu Yang yangtiezhu@loongson.cn riscv: uprobes: Restore thread.bad_cause
Aditya Gupta adityag@linux.ibm.com powerpc: update ppc_save_regs to save current r1 in pt_regs
Nicholas Piggin npiggin@gmail.com powerpc: simplify ppc_save_regs
Colin Ian King colin.i.king@gmail.com powerpc/powernv/sriov: perform null check on iov before dereferencing iov
Claudiu Beznea claudiu.beznea@microchip.com pinctrl: at91-pio4: check return value of devm_kasprintf()
Claudiu Beznea claudiu.beznea@microchip.com pinctrl: microchip-sgpio: check return value of devm_kasprintf()
Nicholas Piggin npiggin@gmail.com powerpc/64s: Fix VAS mm use after free
Namhyung Kim namhyung@kernel.org perf dwarf-aux: Fix off-by-one in die_get_varname()
Arnaldo Carvalho de Melo acme@redhat.com perf script: Fix allocation of evsel->priv related to per-event dump files
Christophe Leroy christophe.leroy@csgroup.eu powerpc/signal32: Force inlining of __unsafe_save_user_regs() and save_tm_user_regs_unsafe()
Christophe Leroy christophe.leroy@csgroup.eu powerpc/interrupt: Don't read MSR from interrupt_exit_kernel_prepare()
Christophe Leroy christophe.leroy@csgroup.eu kcsan: Don't expect 64 bits atomic builtins from 32 bits architectures
Andy Shevchenko andriy.shevchenko@linux.intel.com pinctrl: cherryview: Return correct value if pin in push-pull mode
Arnaldo Carvalho de Melo acme@redhat.com perf bench: Add missing setlocale() call to allow usage of %'d style formatting
Sohaib Mohamed sohaib.amhmd@gmail.com perf bench: Use unbuffered output when pipe/tee'ing to a file
Sui Jingfeng suijingfeng@loongson.cn PCI: Add pci_clear_master() stub for non-CONFIG_PCI
Junyan Ye yejunyan@hust.edu.cn PCI: ftpci100: Release the clock resources
Rongguang Wei weirongguang@kylinos.cn PCI: pciehp: Cancel bringup sequence if card is not present
Yuchen Yang u202114568@hust.edu.cn scsi: 3w-xxxx: Add error handling for initialization failure in tw_probe()
Ding Hui dinghui@sangfor.com.cn PCI/ASPM: Disable ASPM on MFD function removal to avoid use-after-free
Christophe JAILLET christophe.jaillet@wanadoo.fr pinctrl: bcm2835: Handle gpiochip_add_pin_range() errors
Jinhong Zhu jinhongzhu@hust.edu.cn scsi: qedf: Fix NULL dereference in error handling
Nirmal Patel nirmal.patel@linux.intel.com PCI: vmd: Reset VMD config register between soft reboots
Siddharth Vadapalli s-vadapalli@ti.com PCI: cadence: Fix Gen2 Link Retraining process
Fei Shao fshao@chromium.org clk: Fix memory leak in devm_clk_notifier_register()
Claudiu Beznea claudiu.beznea@microchip.com ASoC: imx-audmix: check return value of devm_kasprintf()
Amir Goldstein amir73il@gmail.com ovl: update of dentry revalidate flags after copy up
Alexey Romanov avromanov@sberdevices.ru drivers: meson: secure-pwrc: always enable DMA domain
Claudiu Beznea claudiu.beznea@microchip.com clk: ti: clkctrl: check return value of kasprintf()
Claudiu Beznea claudiu.beznea@microchip.com clk: keystone: sci-clk: check return value of kasprintf()
Claudiu Beznea claudiu.beznea@microchip.com clk: si5341: free unused memory on probe failure
Claudiu Beznea claudiu.beznea@microchip.com clk: si5341: check return value of {devm_}kasprintf()
Claudiu Beznea claudiu.beznea@microchip.com clk: si5341: return error if one synth clock registration fails
Claudiu Beznea claudiu.beznea@microchip.com clk: cdce925: check return value of kasprintf()
Claudiu Beznea claudiu.beznea@microchip.com clk: vc5: check memory returned by kasprintf()
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/dpu: correct MERGE_3D length
Nícolas F. R. A. Prado nfraprado@collabora.com arm64: dts: mediatek: mt8192: Fix CPUs capacity-dmips-mhz
Allen-KH Cheng allen-kh.cheng@mediatek.com arm64: dts: mediatek: Add cpufreq nodes for MT8192
Bjorn Andersson quic_bjorande@quicinc.com drm/msm/dp: Free resources after unregistering them
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/dpu: do not enable color-management if DSPPs are not available
Su Hui suhui@nfschina.com ALSA: ac97: Fix possible NULL dereference in snd_ac97_mixer
Yuan Can yuancan@huawei.com clk: tegra: tegra124-emc: Fix potential memory leak
Dan Carpenter dan.carpenter@linaro.org clk: clocking-wizard: Fix Oops in clk_wzrd_register_divider()
Marijn Suijten marijn.suijten@somainline.org arm64: dts: qcom: sm8250-edo: Panel framebuffer is 2.5k instead of 4k
Yuxing Liu lyx2022@hust.edu.cn clk: imx: clk-imx8mp: improve error handling in imx8mp_clocks_probe()
Hao Luo m202171776@hust.edu.cn clk: imx: clk-imx8mn: fix memory leak in imx8mn_clocks_probe
Kashyap Desai kashyap.desai@broadcom.com RDMA/bnxt_re: Avoid calling wake_up threads from spin_lock context
Kashyap Desai kashyap.desai@broadcom.com RDMA/bnxt_re: wraparound mbox producer index
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/a5xx: really check for A510 in a5xx_gpu_init
Chia-I Wu olvaffe@gmail.com amdgpu: validate offset_in_bo of drm_amdgpu_gem_va
Nikita Zhandarovich n.zhandarovich@fintech.ru drm/radeon: fix possible division-by-zero errors
Aurabindo Pillai aurabindo.pillai@amd.com drm/amd/display: Fix artifacting on eDP panels when engaging freesync video mode
Daniil Dulov d.dulov@aladdin.ru drm/amdkfd: Fix potential deallocation of previously deallocated memory.
Christian Lamparter chunkeey@gmail.com ARM: dts: BCM5301X: fix duplex-full => full-duplex
Guenter Roeck linux@roeck-us.net hwmon: (pmbus/adm1275) Fix problems with temperature monitoring on ADM1272
Potin Lai potin.lai@quantatw.com hwmon: (adm1275) Allow setting sample averaging
Tim Harvey tharvey@gateworks.com hwmon: (gsc-hwmon) fix fan pwm temperature scaling
Olivier Moysan olivier.moysan@foss.st.com ARM: dts: stm32: fix i2s endpoint format property for stm32mp15xx-dkx
Marek Vasut marex@denx.de ARM: dts: stm32: Fix audio routing on STM32MP15xx DHCOM PDK2
Keerthy j-keerthy@ti.com arm64: dts: ti: k3-j7200: Fix physical address of pin
Christophe JAILLET christophe.jaillet@wanadoo.fr fbdev: omapfb: lcd_mipid: Fix an error handling path in mipid_spi_probe()
Wolfram Sang wsa+renesas@sang-engineering.com arm64: dts: renesas: ulcb-kf: Remove flow control for SCIF1
Geert Uytterhoeven geert+renesas@glider.be ARM: dts: iwg20d-q7-common: Fix backlight pwm specifier
Chengchang Tang tangchengchang@huawei.com RDMA/hns: Fix hns_roce_table_get return value
Brendan Cunningham bcunningham@cornelisnetworks.com IB/hfi1: Fix wrong mmu_node used for user SDMA packet after invalidate
Christophe JAILLET christophe.jaillet@wanadoo.fr IB/hfi1: Use bitmap_zalloc() when applicable
Arnd Bergmann arnd@arndb.de RDMA/irdma: avoid fortify-string warning in irdma_clr_wqes
Randy Dunlap rdunlap@infradead.org soc/fsl/qe: fix usb.c build errors
Martin Blumenstingl martin.blumenstingl@googlemail.com ARM: dts: meson8: correct uart_B and uart_C clock references
Cristian Ciocaltea cristian.ciocaltea@collabora.com ASoC: es8316: Do not set rate constraints for unsupported MCLKs
Cristian Ciocaltea cristian.ciocaltea@collabora.com ASoC: es8316: Increment max value for ALC Capture Target Volume control
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org memory: brcmstb_dpfe: fix testing array offset after use
Marek Vasut marex@denx.de ARM: dts: stm32: Shorten the AV96 HDMI sound card name
Douglas Anderson dianders@chromium.org arm64: dts: mediatek: mt8183: Add mediatek,broken-save-restore-fw to kukui
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: apq8096: fix fixed regulator name property
Arnd Bergmann arnd@arndb.de ARM: omap2: fix missing tick_broadcast() prototype
Arnd Bergmann arnd@arndb.de ARM: ep93xx: fix missing-prototype warnings
Dario Binacchi dario.binacchi@amarulasolutions.com drm/panel: simple: fix active size for Ampire AM-480272H3TMQW-T01H
Stephan Gerhold stephan@gerhold.net arm64: dts: qcom: apq8016-sbc: Fix 1.8V power rail on LS expansion
Stephan Gerhold stephan@gerhold.net arm64: dts: qcom: apq8016-sbc: Fix regulator constraints
Stephan Gerhold stephan@gerhold.net arm64: dts: qcom: Drop unneeded extra device-specific includes
Dmitry Baryshkov dmitry.baryshkov@linaro.org arm64: dts: qcom: apq8016-sbc: fix mpps state names
Stephan Gerhold stephan@gerhold.net arm64: dts: qcom: apq8016-sbc: Clarify firmware-names
Bjorn Andersson bjorn.andersson@linaro.org arm64: dts: qcom: apq8016-sbc: Update modem and WiFi firmware path
Yassine Oudjana y.oudjana@protonmail.com arm64: dts: qcom: db820c: Move blsp1_uart2 pin states to msm8996.dtsi
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: sdm845: correct camss unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: sdm630: correct camss unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: msm8996: correct camss unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: msm8994: correct SPMI unit address
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: msm8916: correct camss unit address
Tony Lindgren tony@atomide.com ARM: dts: gta04: Move model property out of pinctrl node
Konrad Dybcio konrad.dybcio@linaro.org drm/msm/dpu: Set DPU_DATA_HCTL_EN for in INTF_SC7180_MASK
Vinod Polimera quic_vpolimer@quicinc.com drm/msm/disp/dpu: get timing engine status from intf status register
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/dsi: don't allow enabling 14nm VCO with unprogrammed rate
Kalesh AP kalesh-anakkur.purayil@broadcom.com RDMA/bnxt_re: Fix to remove an unnecessary log
Kalesh AP kalesh-anakkur.purayil@broadcom.com RDMA/bnxt_re: Remove a redundant check inside bnxt_re_update_gid
Kalesh AP kalesh-anakkur.purayil@broadcom.com RDMA/bnxt_re: Use unique names while registering interrupts
Kalesh AP kalesh-anakkur.purayil@broadcom.com RDMA/bnxt_re: Fix to remove unnecessary return labels
Selvin Xavier selvin.xavier@broadcom.com RDMA/bnxt_re: Disable/kill tasklet only if it is enabled
Dan Carpenter dan.carpenter@linaro.org clk: imx: scu: use _safe list iterator to avoid a use after free
Robert Marko robert.marko@sartura.hr arm64: dts: microchip: sparx5: do not use PSCI on reference boards
Tony Lindgren tony@atomide.com bus: ti-sysc: Fix dispc quirk masking bool variables
Marek Vasut marex@denx.de ARM: dts: stm32: Move ethernet MAC EEPROM from SoM to carrier boards
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/panel: sharp-ls043t1le01: adjust mode settings
XuDong Liu m202071377@hust.edu.cn drm: sun4i_tcon: use devm_clk_get_enabled in `sun4i_tcon_init_clocks`
Marek Vasut marex@denx.de Input: adxl34x - do not hardcode interrupt trigger type
hfdevel@gmx.net hfdevel@gmx.net ARM: dts: meson8b: correct uart_B and uart_C clock references
Rafał Miłecki rafal@milecki.pl ARM: dts: BCM5301X: Drop "clock-names" from the SPI node
Luc Ma luc@sietium.com drm/vram-helper: fix function names in vram helper doc
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix THS_TRAILCNT computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix TXTAGOCNT computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix THS_ZEROCNT computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix TCLK_TRAILCNT computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: Add atomic_get_input_bus_fmts() implementation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix TCLK_ZEROCNT computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix PLL target frequency
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: fix PLL parameters computation
Francesco Dolcini francesco.dolcini@toradex.com drm/bridge: tc358768: always enable HS video mode
Luca Weiss luca@z3ntu.xyz Input: drv260x - sleep between polling GO bit
Nicholas Kazlauskas nicholas.kazlauskas@amd.com drm/amd/display: Explicitly specify update type per plane info change
Nikita Zhandarovich n.zhandarovich@fintech.ru radeon: avoid double free in ci_dpm_init()
Wesley Chalmers Wesley.Chalmers@amd.com drm/amd/display: Add logging for display MALL refresh setting
Kuniyuki Iwashima kuniyu@amazon.com netlink: Add __sock_i_ino() for __netlink_diag_dump().
Cambda Zhu cambda@linux.alibaba.com ipvlan: Fix return value of ipvlan_queue_xmit()
Ilia.Gavrilov Ilia.Gavrilov@infotecs.ru netfilter: nf_conntrack_sip: fix the ct_sip_parse_numerical_param() return value.
Florian Westphal fw@strlen.de netfilter: conntrack: dccp: copy entire header to stack buffer, not just basic one
Jeremy Sowden jeremy@azazel.net lib/ts_bm: reset initial match offset for every block of text
Lin Ma linma@zju.edu.cn net: nfc: Fix use-after-free caused by nfc_llcp_find_local
Krzysztof Kozlowski krzysztof.kozlowski@canonical.com nfc: llcp: simplify llcp_sock_connect() error paths
Edward Cree ecree.xilinx@gmail.com sfc: fix crash when reading stats while NIC is resetting
Maxim Kochetkov fido_max@inbox.ru net: axienet: Move reset before 64-bit DMA detection
Kuniyuki Iwashima kuniyu@amazon.com gtp: Fix use-after-free in __gtp_encap_destroy().
Sabrina Dubroca sd@queasysnail.net selftests: rtnetlink: remove netdevsim device after ipsec offload test
Eric Dumazet edumazet@google.com bonding: do not assume skb mac_header is set
Eric Dumazet edumazet@google.com netlink: do not hard code device address lenth in fdb dumps
Eric Dumazet edumazet@google.com netlink: fix potential deadlock in netlink_set_err()
Bartosz Golaszewski bartosz.golaszewski@linaro.org net: stmmac: fix double serdes powerdown
Vinicius Costa Gomes vinicius.gomes@intel.com igc: Fix race condition in PTP tx code
Vincent Mailhol mailhol.vincent@wanadoo.fr can: length: fix bitstuffing count
Gilad Sever gilad9366@gmail.com bpf: Fix bpf socket lookup from tc/xdp to respect socket VRF bindings
Gilad Sever gilad9366@gmail.com bpf: Call __bpf_sk_lookup()/__bpf_skc_lookup() directly via TC hookpoint
Gilad Sever gilad9366@gmail.com bpf: Factor out socket lookup functions for the TC hookpoint.
Tobias Klauser tklauser@distanz.ch bpf: Omit superfluous address family check in __bpf_skc_lookup
Dmitry Antipov dmantipov@yandex.ru wifi: ath9k: convert msecs to jiffies where needed
Johannes Berg johannes.berg@intel.com wifi: iwlwifi: mvm: indicate HW decrypt for beacon protection
Benjamin Berg benjamin.berg@intel.com wifi: cfg80211: rewrite merging of inherited elements
Anjaneyulu pagadala.yesu.anjaneyulu@intel.com wifi: iwlwifi: pcie: fix NULL pointer dereference in iwl_pcie_irq_rx_msix_handler()
Emmanuel Grumbach emmanuel.grumbach@intel.com iwlwifi: don't dump_stack() when we get an unexpected interrupt
Johannes Berg johannes.berg@intel.com wifi: iwlwifi: pull from TXQs with softirqs disabled
Edwin Peer edwin.peer@broadcom.com rtnetlink: extend RTEXT_FILTER_SKIP_STATS to IFLA_VF_INFO
Remi Pommarel repk@triplefau.lt wifi: ath9k: Fix possible stall on ath9k_txq_list_has_key()
Arnd Bergmann arnd@arndb.de memstick r592: make memstick_debug_get_tpc_name() static
Zhen Lei thunder.leizhen@huawei.com kexec: fix a memory leak in crash_shrink_memory()
Douglas Anderson dianders@chromium.org watchdog/perf: more properly prevent false positives with turbo modes
Douglas Anderson dianders@chromium.org watchdog/perf: define dummy watchdog_update_hrtimer_threshold() on correct config
Marek Vasut marex@denx.de wifi: rsi: Do not set MMC_PM_KEEP_POWER in shutdown
Marek Vasut marex@denx.de wifi: rsi: Do not configure WoWlan in shutdown hook if not enabled
Jesper Dangaard Brouer brouer@redhat.com selftests/bpf: Fix check_mtu using wrong variable type
Fedor Pchelkin pchelkin@ispras.ru wifi: ath9k: don't allow to overwrite ENDPOINT0 attributes
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: ray_cs: Fix an error handling path in ray_probe()
Andy Shevchenko andriy.shevchenko@linux.intel.com wifi: ray_cs: Drop useless status variable in parse_addr()
Andy Shevchenko andriy.shevchenko@linux.intel.com wifi: ray_cs: Utilize strnlen() in parse_addr()
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: wl3501_cs: Fix an error handling path in wl3501_probe()
Jakub Kicinski kuba@kernel.org wl3501_cs: use eth_hw_addr_set()
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: atmel: Fix an error handling path in atmel_probe()
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: orinoco: Fix an error handling path in orinoco_cs_probe()
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: orinoco: Fix an error handling path in spectrum_cs_probe()
Geert Uytterhoeven geert+renesas@glider.be regulator: core: Streamline debugfs operations
Geert Uytterhoeven geert+renesas@glider.be regulator: core: Fix more error checking for debugfs_create_dir()
Alan Maguire alan.maguire@oracle.com bpftool: JIT limited misreported as negative value on aarch64
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org nfc: llcp: fix possible use of uninitialized variable in nfc_llcp_send_connect()
Joy Chakraborty joychakr@google.com spi: dw: Round of n_bytes to power of 2
Stanislav Fomichev sdf@google.com bpf: Don't EFAULT for {g,s}setsockopt with wrong optlen
Andrii Nakryiko andrii@kernel.org libbpf: fix offsetof() and container_of() to work with CO-RE
Alexander Mikhalitsyn aleksandr.mikhalitsyn@canonical.com sctp: add bpf_bypass_getsockopt proto callback
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: mwifiex: Fix the size of a memory allocation in mwifiex_ret_802_11_scan()
Amisha Patel amisha.patel@microchip.com wifi: wilc1000: fix for absent RSN capabilities WFA testcase
Vijaya Krishna Nivarthi quic_vnivarth@quicinc.com spi: spi-geni-qcom: Correct CS_TOGGLE bit in SPI_TRANS_CFG
Pengcheng Yang yangpc@wangsu.com samples/bpf: Fix buffer overflow in tcp_basertt
Martin KaFai Lau martin.lau@kernel.org libbpf: btf_dump_type_data_check_overflow needs to consider BTF_MEMBER_BITFIELD_SIZE
Fedor Pchelkin pchelkin@ispras.ru wifi: ath9k: avoid referencing uninit memory in ath9k_wmi_ctrl_rx
Peter Seiderer ps.report@gmx.net wifi: ath9k: fix AR9003 mac hardware hang check register offset calculation
Jesper Dangaard Brouer brouer@redhat.com igc: Enable and fix RX hash usage by netstack
Jiasheng Jiang jiasheng@iscas.ac.cn pstore/ram: Add check for kstrdup
Roberto Sassu roberto.sassu@huawei.com ima: Fix build warnings
Roberto Sassu roberto.sassu@huawei.com evm: Fix build warnings
Roberto Sassu roberto.sassu@huawei.com evm: Complete description of evm_inode_setattr()
Mark Rutland mark.rutland@arm.com locking/atomic: arm: fix sync ops
Juergen Gross jgross@suse.com x86/mm: Fix __swp_entry_to_pte() for Xen PV guests
Ravi Bangoria ravi.bangoria@amd.com perf/ibs: Fix interface via core pmu events
Colin Ian King colin.i.king@gmail.com kselftest: vDSO: Fix accumulation of uninitialized ret when CLOCK_REALTIME is undefined
Qiuxu Zhuo qiuxu.zhuo@intel.com rcu/rcuscale: Stop kfree_scale_thread thread(s) after unloading rcuscale
Qiuxu Zhuo qiuxu.zhuo@intel.com rcu/rcuscale: Move rcu_scale_*() after kfree_scale_cleanup()
Paul E. McKenney paulmck@kernel.org rcuscale: Move shutdown from wait_event() to wait_event_idle()
Li Zhijian zhijianx.li@intel.com rcuscale: Always log error message
Paul E. McKenney paulmck@kernel.org rcutorture: Correct name of use_softirq module parameter
Christophe JAILLET christophe.jaillet@wanadoo.fr thermal/drivers/sun8i: Fix some error handling paths in sun8i_ths_probe()
Tero Kristo tero.kristo@linux.intel.com cpufreq: intel_pstate: Fix energy_performance_preference for passive
Arnd Bergmann arnd@arndb.de ARM: 9303/1: kprobes: avoid missing-declaration warnings
Zhang Rui rui.zhang@intel.com powercap: RAPL: Fix CONFIG_IOSF_MBI dependency
Robin Murphy robin.murphy@arm.com perf/arm-cmn: Fix DTC reset
Nikita Zhandarovich n.zhandarovich@fintech.ru PM: domains: fix integer overflow issues in genpd_parse_state()
Feng Mingxi m202271825@hust.edu.cn clocksource/drivers/cadence-ttc: Fix memory leak in ttc_timer_probe
Sebastian Andrzej Siewior bigeasy@linutronix.de tracing/timer: Add missing hrtimer modes to decode_hrtimer_mode().
Thomas Gleixner tglx@linutronix.de posix-timers: Prevent RT livelock in itimer_delete()
Chuck Lever chuck.lever@oracle.com svcrdma: Prevent page release when nothing was received
John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de irqchip/jcore-aic: Fix missing allocation of IRQ descriptors
Li Nan linan122@huawei.com md/raid10: fix io loss while replacement replace rdev
Li Nan linan122@huawei.com md/raid10: fix null-ptr-deref of mreplace in raid10_sync_request
Li Nan linan122@huawei.com md/raid10: fix wrong setting of max_corr_read_errors
Li Nan linan122@huawei.com md/raid10: fix overflow of md/safe_mode_delay
Li Nan linan122@huawei.com md/raid10: check slab-out-of-bounds in md_bitmap_get_counter
Li Nan linan122@huawei.com blk-iocost: use spin_lock_irqsave in adjust_inuse_and_calc_cost
Shawn Wang shawnwang@linux.alibaba.com x86/resctrl: Only show tasks' pid in current pid namespace
Arnd Bergmann arnd@arndb.de fs: pipe: reveal missing function protoypes
Pablo Neira Ayuso pablo@netfilter.org netfilter: nf_tables: drop map element references from preparation phase
-------------
Diffstat:
.../admin-guide/device-mapper/dm-init.rst | 8 + Documentation/arm64/silicon-errata.rst | 4 + Documentation/filesystems/autofs-mount-control.rst | 2 +- Documentation/filesystems/autofs.rst | 2 +- Documentation/filesystems/directory-locking.rst | 26 +- Documentation/networking/af_xdp.rst | 9 + Makefile | 4 +- arch/arc/include/asm/linkage.h | 8 +- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 +- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 +- arch/arm/boot/dts/bcm5301x.dtsi | 1 - arch/arm/boot/dts/iwg20d-q7-common.dtsi | 2 +- arch/arm/boot/dts/meson8.dtsi | 4 +- arch/arm/boot/dts/meson8b.dtsi | 4 +- arch/arm/boot/dts/omap3-gta04a5one.dts | 4 +- arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1-c1.dts | 8 +- arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi | 10 +- arch/arm/boot/dts/qcom-ipq4019-ap.dk07.1.dtsi | 12 +- arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi | 11 +- arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 8 +- arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi | 6 - arch/arm/boot/dts/stm32mp15xx-dkx.dtsi | 2 +- arch/arm/include/asm/assembler.h | 17 + arch/arm/include/asm/sync_bitops.h | 29 +- arch/arm/lib/bitops.h | 14 +- arch/arm/lib/testchangebit.S | 4 + arch/arm/lib/testclearbit.S | 4 + arch/arm/lib/testsetbit.S | 4 + arch/arm/mach-ep93xx/timer-ep93xx.c | 3 +- arch/arm/mach-omap2/board-generic.c | 1 + arch/arm/mach-orion5x/board-dt.c | 3 + arch/arm/mach-orion5x/common.h | 6 + arch/arm/probes/kprobes/checkers-common.c | 2 +- arch/arm/probes/kprobes/core.c | 2 +- arch/arm/probes/kprobes/opt-arm.c | 2 - arch/arm/probes/kprobes/test-core.c | 2 +- arch/arm/probes/kprobes/test-core.h | 4 + arch/arm64/Kconfig | 41 + arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 4 + arch/arm64/boot/dts/mediatek/mt8192.dtsi | 22 +- arch/arm64/boot/dts/microchip/sparx5.dtsi | 2 +- .../boot/dts/microchip/sparx5_pcb_common.dtsi | 12 + arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 840 ++++++++++++++- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 826 --------------- arch/arm64/boot/dts/qcom/apq8096-db820c.dts | 1070 ++++++++++++++++++- arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi | 1105 -------------------- arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts | 4 +- arch/arm64/boot/dts/qcom/msm8916-mtp.dts | 15 +- arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi | 21 - arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 +- arch/arm64/boot/dts/qcom/msm8994.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8996-mtp.dts | 24 +- arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi | 30 - arch/arm64/boot/dts/qcom/msm8996.dtsi | 19 +- arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 +- arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +- .../boot/dts/qcom/sm8250-sony-xperia-edo.dtsi | 7 +- arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 3 +- .../boot/dts/ti/k3-j7200-common-proc-board.dts | 28 +- arch/arm64/kernel/cpu_errata.c | 26 + arch/arm64/tools/cpucaps | 1 + arch/mips/include/asm/kvm_host.h | 6 +- arch/mips/kernel/cpu-probe.c | 9 +- arch/mips/kvm/emulate.c | 22 +- arch/mips/kvm/mips.c | 16 +- arch/mips/kvm/stats.c | 4 +- arch/mips/kvm/trace.h | 8 +- arch/mips/kvm/vz.c | 20 +- arch/powerpc/Kconfig.debug | 2 +- arch/powerpc/Makefile | 8 + arch/powerpc/kernel/interrupt.c | 3 +- arch/powerpc/kernel/ppc_save_regs.S | 61 +- arch/powerpc/kernel/security.c | 37 +- arch/powerpc/kernel/signal_32.c | 15 +- arch/powerpc/mm/book3s64/radix_pgtable.c | 34 +- arch/powerpc/mm/init_64.c | 2 +- arch/powerpc/platforms/powernv/pci-sriov.c | 6 +- arch/powerpc/platforms/powernv/vas-window.c | 2 +- arch/powerpc/platforms/pseries/vas.c | 2 +- arch/riscv/kernel/probes/uprobes.c | 2 + arch/riscv/mm/init.c | 6 +- arch/riscv/net/bpf_jit.h | 5 +- arch/riscv/net/bpf_jit_core.c | 15 +- arch/s390/Makefile | 1 + arch/s390/kvm/diag.c | 8 +- arch/s390/kvm/kvm-s390.c | 4 + arch/s390/kvm/vsie.c | 6 +- arch/sh/drivers/dma/dma-sh.c | 37 +- arch/sh/kernel/cpu/sh2/probe.c | 2 +- arch/um/Makefile | 2 +- arch/x86/events/amd/core.c | 2 +- arch/x86/events/amd/ibs.c | 53 +- arch/x86/include/asm/perf_event.h | 2 + arch/x86/include/asm/pgtable_64.h | 4 +- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 8 +- arch/xtensa/platforms/iss/network.c | 2 +- block/blk-iocost.c | 7 +- block/disk-events.c | 1 + block/partitions/amiga.c | 104 +- drivers/base/power/domain.c | 6 +- drivers/bus/intel-ixp4xx-eb.c | 2 +- drivers/bus/ti-sysc.c | 4 +- drivers/char/hw_random/imx-rngc.c | 6 +- drivers/char/hw_random/st-rng.c | 21 +- drivers/char/hw_random/virtio-rng.c | 88 +- drivers/char/tpm/tpm_vtpm_proxy.c | 30 +- drivers/clk/clk-cdce925.c | 12 + drivers/clk/clk-si5341.c | 38 +- drivers/clk/clk-versaclock5.c | 29 + drivers/clk/clk.c | 1 + drivers/clk/imx/clk-imx8mn.c | 8 +- drivers/clk/imx/clk-imx8mp.c | 24 +- drivers/clk/imx/clk-scu.c | 4 +- drivers/clk/keystone/sci-clk.c | 2 + drivers/clk/qcom/camcc-sc7180.c | 19 +- drivers/clk/qcom/gcc-ipq6018.c | 34 +- drivers/clk/qcom/reset.c | 8 +- drivers/clk/qcom/reset.h | 2 + drivers/clk/tegra/clk-tegra124-emc.c | 2 + drivers/clk/ti/clkctrl.c | 7 + drivers/clocksource/timer-cadence-ttc.c | 19 +- drivers/cpufreq/intel_pstate.c | 2 + drivers/crypto/marvell/cesa/cipher.c | 2 +- drivers/crypto/nx/Makefile | 2 +- drivers/crypto/nx/nx.h | 4 +- drivers/crypto/qat/qat_common/adf_common_drv.h | 5 - drivers/crypto/qat/qat_common/qat_algs.c | 23 +- drivers/crypto/qat/qat_common/qat_asym_algs.c | 53 +- drivers/crypto/qat/qat_common/qat_crypto.h | 5 + drivers/dax/bus.c | 61 +- drivers/dax/dax-private.h | 4 +- drivers/dax/kmem.c | 2 +- drivers/extcon/extcon-usbc-tusb320.c | 5 +- drivers/extcon/extcon.c | 8 + drivers/firmware/efi/libstub/efi-stub-helper.c | 7 +- drivers/firmware/stratix10-svc.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 3 + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 28 +- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 13 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 + .../dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c | 3 + drivers/gpu/drm/amd/display/dc/core/dc.c | 3 - drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 2 +- drivers/gpu/drm/bridge/tc358768.c | 93 +- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 33 +- drivers/gpu/drm/drm_atomic_helper.c | 11 +- drivers/gpu/drm/drm_gem_vram_helper.c | 6 +- drivers/gpu/drm/i915/display/intel_psr.c | 4 +- drivers/gpu/drm/i915/gt/intel_gtt.c | 2 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 12 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 8 +- drivers/gpu/drm/msm/dp/dp_display.c | 2 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 3 + drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 11 +- drivers/gpu/drm/panel/panel-simple.c | 6 +- drivers/gpu/drm/radeon/ci_dpm.c | 28 +- drivers/gpu/drm/radeon/cypress_dpm.c | 8 +- drivers/gpu/drm/radeon/ni_dpm.c | 8 +- drivers/gpu/drm/radeon/rv740_dpm.c | 8 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 8 +- drivers/gpu/drm/sun4i/sun4i_tcon.c | 19 +- drivers/gpu/drm/ttm/ttm_bo.c | 7 + drivers/hwmon/gsc-hwmon.c | 6 +- drivers/hwmon/pmbus/adm1275.c | 90 +- drivers/hwtracing/coresight/coresight-core.c | 9 +- drivers/i2c/busses/i2c-qup.c | 21 +- drivers/i2c/busses/i2c-xiic.c | 39 +- drivers/iio/accel/fxls8962af-core.c | 8 +- drivers/iio/adc/ad7192.c | 8 +- drivers/iio/adc/meson_saradc.c | 2 +- drivers/infiniband/hw/bnxt_re/main.c | 20 +- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 40 +- drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 +- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 46 +- drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 1 + drivers/infiniband/hw/hfi1/ipoib_tx.c | 4 +- drivers/infiniband/hw/hfi1/mmu_rb.c | 101 +- drivers/infiniband/hw/hfi1/mmu_rb.h | 3 + drivers/infiniband/hw/hfi1/sdma.c | 23 +- drivers/infiniband/hw/hfi1/sdma.h | 47 +- drivers/infiniband/hw/hfi1/sdma_txreq.h | 2 + drivers/infiniband/hw/hfi1/user_sdma.c | 145 +-- drivers/infiniband/hw/hfi1/user_sdma.h | 1 - drivers/infiniband/hw/hfi1/vnic_sdma.c | 4 +- drivers/infiniband/hw/hns/hns_roce_hem.c | 7 +- drivers/infiniband/hw/irdma/uk.c | 10 +- drivers/input/misc/adxl34x.c | 3 +- drivers/input/misc/drv260x.c | 1 + drivers/irqchip/irq-jcore-aic.c | 7 + drivers/leds/trigger/ledtrig-netdev.c | 3 + drivers/mailbox/ti-msgmgr.c | 12 +- drivers/md/bcache/btree.c | 25 +- drivers/md/bcache/btree.h | 1 + drivers/md/bcache/super.c | 4 +- drivers/md/bcache/writeback.c | 10 + drivers/md/dm-init.c | 22 +- drivers/md/dm-integrity.c | 4 +- drivers/md/md-bitmap.c | 17 +- drivers/md/md.c | 9 +- drivers/md/raid0.c | 62 +- drivers/md/raid0.h | 1 + drivers/md/raid10.c | 38 +- drivers/media/cec/i2c/Kconfig | 1 + drivers/media/i2c/st-mipid02.c | 9 +- drivers/media/platform/qcom/venus/helpers.c | 4 +- drivers/media/usb/dvb-usb-v2/az6007.c | 3 +- drivers/media/usb/siano/smsusb.c | 3 +- drivers/memory/brcmstb_dpfe.c | 4 +- drivers/memstick/host/r592.c | 4 +- drivers/mfd/intel-lpss-acpi.c | 3 + drivers/mfd/qcom-pm8008.c | 1 + drivers/mfd/rt5033.c | 3 - drivers/mfd/stmfx.c | 7 +- drivers/mfd/stmpe.c | 4 +- drivers/misc/fastrpc.c | 2 +- drivers/misc/pci_endpoint_test.c | 10 +- drivers/mmc/core/quirks.h | 14 + drivers/mmc/host/mmci.c | 1 + drivers/mmc/host/sdhci.c | 4 +- drivers/mtd/nand/raw/meson_nand.c | 4 + drivers/net/bonding/bond_main.c | 2 +- drivers/net/dsa/vitesse-vsc73xx-core.c | 6 +- drivers/net/ethernet/amazon/ena/ena_com.c | 3 + drivers/net/ethernet/broadcom/bgmac.c | 4 +- drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 + drivers/net/ethernet/broadcom/tg3.c | 1 + drivers/net/ethernet/google/gve/gve_ethtool.c | 3 + drivers/net/ethernet/ibm/ibmvnic.c | 9 +- drivers/net/ethernet/intel/igc/igc.h | 33 +- drivers/net/ethernet/intel/igc/igc_ethtool.c | 2 + drivers/net/ethernet/intel/igc/igc_main.c | 45 +- drivers/net/ethernet/intel/igc/igc_ptp.c | 82 +- drivers/net/ethernet/marvell/mvneta.c | 4 +- drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 7 + drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 11 + .../net/ethernet/marvell/octeontx2/af/rvu_cgx.c | 4 +- .../ethernet/marvell/octeontx2/nic/otx2_flows.c | 8 + .../net/ethernet/marvell/octeontx2/nic/otx2_tc.c | 15 + drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c | 6 +- .../ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c | 1 + drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 6 +- drivers/net/ethernet/microchip/lan743x_main.c | 21 +- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 5 - drivers/net/ethernet/sfc/ef10.c | 13 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 - drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 +- drivers/net/gtp.c | 2 + drivers/net/ipvlan/ipvlan_core.c | 9 +- drivers/net/netdevsim/dev.c | 9 +- drivers/net/ppp/pptp.c | 31 +- drivers/net/wireguard/netlink.c | 14 +- drivers/net/wireguard/queueing.c | 1 + drivers/net/wireguard/queueing.h | 25 +- drivers/net/wireguard/receive.c | 2 +- drivers/net/wireguard/send.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 27 +- drivers/net/wireless/ath/ath9k/htc_hst.c | 8 +- drivers/net/wireless/ath/ath9k/main.c | 11 +- drivers/net/wireless/ath/ath9k/wmi.c | 4 + drivers/net/wireless/atmel/atmel_cs.c | 13 +- drivers/net/wireless/cisco/airo.c | 5 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 +- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 9 +- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 12 +- drivers/net/wireless/intersil/orinoco/orinoco_cs.c | 13 +- .../net/wireless/intersil/orinoco/spectrum_cs.c | 13 +- drivers/net/wireless/marvell/mwifiex/scan.c | 6 +- drivers/net/wireless/microchip/wilc1000/hif.c | 8 +- drivers/net/wireless/ray_cs.c | 36 +- drivers/net/wireless/rsi/rsi_91x_sdio.c | 9 +- drivers/net/wireless/wl3501_cs.c | 19 +- drivers/ntb/hw/amd/ntb_hw_amd.c | 7 +- drivers/ntb/hw/idt/ntb_hw_idt.c | 7 +- drivers/ntb/hw/intel/ntb_hw_gen1.c | 7 +- drivers/ntb/ntb_transport.c | 2 +- drivers/ntb/test/ntb_tool.c | 2 + drivers/nvme/host/pci.c | 30 +- drivers/nvmem/rmem.c | 1 + drivers/opp/core.c | 3 + drivers/pci/controller/cadence/pcie-cadence-host.c | 27 + drivers/pci/controller/dwc/pcie-qcom.c | 2 + drivers/pci/controller/pci-ftpci100.c | 14 +- drivers/pci/controller/pcie-rockchip-ep.c | 65 +- drivers/pci/controller/pcie-rockchip.c | 17 + drivers/pci/controller/pcie-rockchip.h | 11 +- drivers/pci/controller/vmd.c | 8 + drivers/pci/hotplug/acpiphp_glue.c | 5 +- drivers/pci/hotplug/pciehp_ctrl.c | 8 + drivers/pci/pci.c | 10 +- drivers/pci/pcie/aspm.c | 21 +- drivers/pci/quirks.c | 2 + drivers/perf/arm-cmn.c | 7 +- drivers/phy/tegra/xusb.c | 4 + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 6 +- drivers/pinctrl/intel/pinctrl-cherryview.c | 15 +- drivers/pinctrl/pinctrl-amd.c | 25 +- drivers/pinctrl/pinctrl-amd.h | 1 + drivers/pinctrl/pinctrl-at91-pio4.c | 2 + drivers/pinctrl/pinctrl-microchip-sgpio.c | 3 + drivers/platform/x86/wmi.c | 64 +- drivers/powercap/Kconfig | 4 +- drivers/powercap/intel_rapl_msr.c | 1 - drivers/pwm/pwm-ab8500.c | 2 +- drivers/pwm/pwm-imx-tpm.c | 7 + drivers/pwm/pwm-mtk-disp.c | 13 +- drivers/pwm/sysfs.c | 17 + drivers/regulator/core.c | 30 +- drivers/rtc/rtc-st-lpc.c | 2 +- drivers/s390/net/qeth_l3_sys.c | 2 +- drivers/scsi/3w-xxxx.c | 4 +- drivers/scsi/qedf/qedf_main.c | 3 +- drivers/scsi/qla2xxx/qla_attr.c | 13 + drivers/scsi/qla2xxx/qla_bsg.c | 6 + drivers/scsi/qla2xxx/qla_def.h | 1 - drivers/scsi/qla2xxx/qla_edif.c | 4 +- drivers/scsi/qla2xxx/qla_init.c | 2 +- drivers/scsi/qla2xxx/qla_inline.h | 5 +- drivers/scsi/qla2xxx/qla_iocb.c | 5 +- drivers/scsi/qla2xxx/qla_nvme.c | 3 - drivers/scsi/qla2xxx/qla_os.c | 3 +- drivers/soc/amlogic/meson-secure-pwrc.c | 2 +- drivers/soc/fsl/qe/Kconfig | 1 + drivers/soundwire/qcom.c | 3 +- drivers/spi/spi-bcm-qspi.c | 10 +- drivers/spi/spi-dw-core.c | 5 +- drivers/spi/spi-geni-qcom.c | 2 +- .../clocking-wizard/clk-xlnx-clock-wizard.c | 2 +- .../media/atomisp/pci/atomisp_gmin_platform.c | 2 +- drivers/thermal/sun8i_thermal.c | 55 +- drivers/tty/serial/8250/8250.h | 1 - drivers/tty/serial/8250/8250_omap.c | 25 +- drivers/tty/serial/8250/8250_pci.c | 19 - drivers/tty/serial/8250/8250_port.c | 11 +- drivers/tty/serial/atmel_serial.c | 4 +- drivers/tty/serial/fsl_lpuart.c | 1 + drivers/tty/serial/imx.c | 18 +- drivers/tty/serial/samsung_tty.c | 14 +- drivers/usb/core/devio.c | 2 + drivers/usb/dwc2/platform.c | 18 +- drivers/usb/dwc3/dwc3-meson-g12a.c | 5 +- drivers/usb/dwc3/dwc3-qcom.c | 17 +- drivers/usb/dwc3/gadget.c | 4 +- drivers/usb/gadget/function/u_serial.c | 13 +- drivers/usb/host/xhci-mem.c | 39 +- drivers/usb/host/xhci-pci.c | 12 + drivers/usb/host/xhci.h | 2 + drivers/usb/phy/phy-tahvo.c | 2 +- drivers/usb/serial/option.c | 4 + drivers/video/fbdev/omap/lcd_mipid.c | 6 +- drivers/w1/slaves/w1_therm.c | 31 +- drivers/w1/w1.c | 4 +- fs/btrfs/block-group.c | 36 +- fs/btrfs/ctree.c | 28 +- fs/btrfs/qgroup.c | 2 + fs/ceph/caps.c | 9 + fs/cifs/file.c | 25 +- fs/dlm/plock.c | 4 +- fs/erofs/inode.c | 5 +- fs/erofs/internal.h | 16 +- fs/erofs/super.c | 58 +- fs/erofs/xattr.c | 4 +- fs/erofs/zdata.c | 10 +- fs/erofs/zmap.c | 6 +- fs/ext4/indirect.c | 8 + fs/ext4/inode.c | 10 - fs/ext4/ioctl.c | 5 +- fs/ext4/mballoc.c | 17 +- fs/ext4/namei.c | 17 +- fs/ext4/super.c | 19 +- fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 2 +- fs/f2fs/gc.c | 21 +- fs/f2fs/namei.c | 16 +- fs/f2fs/node.c | 4 +- fs/fs_context.c | 3 +- fs/inode.c | 42 + fs/internal.h | 2 + fs/jffs2/build.c | 5 +- fs/jffs2/xattr.c | 13 +- fs/jffs2/xattr.h | 4 +- fs/jfs/jfs_dmap.c | 6 + fs/jfs/jfs_filsys.h | 2 + fs/kernfs/dir.c | 2 + fs/ksmbd/server.c | 33 +- fs/ksmbd/smb2misc.c | 38 +- fs/ksmbd/smb2pdu.c | 44 +- fs/ksmbd/smb_common.c | 2 +- fs/namei.c | 25 +- fs/nfs/nfs4proc.c | 1 + fs/nfsd/nfs4xdr.c | 2 +- fs/notify/fanotify/fanotify_user.c | 22 +- fs/ntfs3/index.c | 84 +- fs/ntfs3/inode.c | 18 +- fs/ntfs3/ntfs_fs.h | 4 +- fs/ntfs3/run.c | 7 +- fs/ntfs3/xattr.c | 112 +- fs/overlayfs/copy_up.c | 2 + fs/overlayfs/dir.c | 3 +- fs/overlayfs/export.c | 3 +- fs/overlayfs/inode.c | 10 +- fs/overlayfs/namei.c | 3 +- fs/overlayfs/overlayfs.h | 6 +- fs/overlayfs/super.c | 2 +- fs/overlayfs/util.c | 24 +- fs/pstore/ram_core.c | 2 + fs/ramfs/inode.c | 2 +- include/acpi/acpi_bus.h | 3 +- include/crypto/internal/kpp.h | 6 + include/linux/bootmem_info.h | 2 + include/linux/can/length.h | 14 +- include/linux/netdevice.h | 9 + include/linux/nmi.h | 2 +- include/linux/pci.h | 1 + include/linux/pipe_fs_i.h | 4 - include/linux/ramfs.h | 1 + include/linux/serial_8250.h | 1 - include/linux/workqueue.h | 15 +- include/net/netfilter/nf_tables.h | 5 +- include/net/pkt_sched.h | 2 +- include/net/sock.h | 1 + include/trace/events/timer.h | 6 +- include/uapi/linux/affs_hardblocks.h | 68 +- include/uapi/linux/auto_dev-ioctl.h | 2 +- include/uapi/linux/videodev2.h | 2 +- io_uring/io_uring.c | 66 +- kernel/bpf/cgroup.c | 15 + kernel/bpf/cpumap.c | 40 +- kernel/bpf/verifier.c | 5 +- kernel/kcsan/core.c | 2 + kernel/kexec_core.c | 5 +- kernel/rcu/rcuscale.c | 212 ++-- kernel/time/posix-timers.c | 43 +- kernel/trace/ftrace.c | 45 +- kernel/trace/ring_buffer.c | 24 +- kernel/trace/trace.c | 3 +- kernel/trace/trace_eprobe.c | 18 +- kernel/trace/trace_events_hist.c | 8 +- kernel/trace/trace_probe_tmpl.h | 14 +- kernel/watchdog_hld.c | 6 +- kernel/workqueue.c | 13 +- lib/test_firmware.c | 12 +- lib/ts_bm.c | 4 +- mm/damon/vaddr.c | 20 +- mm/shmem.c | 2 +- net/bridge/br_if.c | 5 +- net/ceph/messenger_v2.c | 41 +- net/core/filter.c | 131 ++- net/core/rtnetlink.c | 104 +- net/core/skbuff.c | 5 + net/core/sock.c | 17 +- net/dsa/tag_sja1105.c | 4 +- net/ipv4/tcp_input.c | 12 +- net/ipv6/addrconf.c | 3 +- net/ipv6/icmp.c | 5 +- net/ipv6/udp.c | 2 +- net/netfilter/ipvs/Kconfig | 27 +- net/netfilter/ipvs/ip_vs_conn.c | 4 +- net/netfilter/nf_conntrack_helper.c | 4 + net/netfilter/nf_conntrack_proto_dccp.c | 52 +- net/netfilter/nf_conntrack_sip.c | 2 +- net/netfilter/nf_tables_api.c | 158 ++- net/netfilter/nft_byteorder.c | 14 +- net/netfilter/nft_set_bitmap.c | 5 +- net/netfilter/nft_set_hash.c | 23 +- net/netfilter/nft_set_pipapo.c | 14 +- net/netfilter/nft_set_rbtree.c | 5 +- net/netlink/af_netlink.c | 5 +- net/netlink/diag.c | 7 +- net/nfc/llcp.h | 1 - net/nfc/llcp_commands.c | 15 +- net/nfc/llcp_core.c | 49 +- net/nfc/llcp_sock.c | 21 +- net/nfc/netlink.c | 20 +- net/nfc/nfc.h | 1 + net/sched/act_ipt.c | 27 +- net/sched/act_pedit.c | 1 + net/sched/cls_flower.c | 10 + net/sched/cls_fw.c | 10 +- net/sched/sch_qfq.c | 41 +- net/sctp/socket.c | 22 +- net/sunrpc/svcsock.c | 23 +- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 12 +- net/wireless/scan.c | 213 ++-- net/xdp/xsk.c | 5 + samples/bpf/tcp_basertt_kern.c | 2 +- samples/ftrace/ftrace-direct-too.c | 14 +- scripts/Makefile.modfinal | 2 +- scripts/mod/modpost.c | 86 +- security/apparmor/policy_unpack.c | 9 +- security/integrity/evm/evm_crypto.c | 2 +- security/integrity/evm/evm_main.c | 4 +- security/integrity/iint.c | 15 +- security/integrity/ima/ima_modsig.c | 3 + security/integrity/ima/ima_policy.c | 3 +- sound/core/jack.c | 15 +- sound/pci/ac97/ac97_codec.c | 4 +- sound/pci/hda/patch_realtek.c | 1 + sound/soc/codecs/es8316.c | 23 +- sound/soc/fsl/imx-audmix.c | 9 + sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 13 +- tools/bpf/bpftool/feature.c | 24 +- tools/lib/bpf/bpf_helpers.h | 15 +- tools/lib/bpf/btf_dump.c | 22 +- tools/perf/builtin-bench.c | 7 +- tools/perf/builtin-script.c | 16 +- tools/perf/tests/builtin-test.c | 3 + tools/perf/util/dwarf-aux.c | 2 +- tools/testing/selftests/bpf/prog_tests/check_mtu.c | 2 +- tools/testing/selftests/net/mptcp/config | 1 + tools/testing/selftests/net/mptcp/mptcp_sockopt.sh | 9 +- tools/testing/selftests/net/rtnetlink.sh | 1 + .../rcutorture/configs/rcu/BUSTED-BOOST.boot | 2 +- .../selftests/rcutorture/configs/rcu/TREE03.boot | 2 +- .../selftests/vDSO/vdso_test_clock_getres.c | 4 +- tools/testing/selftests/wireguard/netns.sh | 30 +- 518 files changed, 6687 insertions(+), 4483 deletions(-)
From: Pablo Neira Ayuso pablo@netfilter.org
commit 628bd3e49cba1c066228e23d71a852c23e26da73 upstream.
set .destroy callback releases the references to other objects in maps. This is very late and it results in spurious EBUSY errors. Drop refcount from the preparation phase instead, update set backend not to drop reference counter from set .destroy path.
Exceptions: NFT_TRANS_PREPARE_ERROR does not require to drop the reference counter because the transaction abort path releases the map references for each element since the set is unbound. The abort path also deals with releasing reference counter for new elements added to unbound sets.
Fixes: 591054469b3e ("netfilter: nf_tables: revisit chain/object refcounting from elements") Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/net/netfilter/nf_tables.h | 5 + net/netfilter/nf_tables_api.c | 145 +++++++++++++++++++++++++++++++++----- net/netfilter/nft_set_bitmap.c | 5 - net/netfilter/nft_set_hash.c | 23 ++++-- net/netfilter/nft_set_pipapo.c | 14 ++- net/netfilter/nft_set_rbtree.c | 5 - 6 files changed, 166 insertions(+), 31 deletions(-)
--- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -437,7 +437,8 @@ struct nft_set_ops { int (*init)(const struct nft_set *set, const struct nft_set_desc *desc, const struct nlattr * const nla[]); - void (*destroy)(const struct nft_set *set); + void (*destroy)(const struct nft_ctx *ctx, + const struct nft_set *set); void (*gc_init)(const struct nft_set *set);
unsigned int elemsize; @@ -772,6 +773,8 @@ int nft_set_elem_expr_clone(const struct struct nft_expr *expr_array[]); void nft_set_elem_destroy(const struct nft_set *set, void *elem, bool destroy_expr); +void nf_tables_set_elem_destroy(const struct nft_ctx *ctx, + const struct nft_set *set, void *elem);
/** * struct nft_set_gc_batch_head - nf_tables set garbage collection batch --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -581,6 +581,58 @@ static int nft_trans_set_add(const struc return __nft_trans_set_add(ctx, msg_type, set, NULL); }
+static void nft_setelem_data_deactivate(const struct net *net, + const struct nft_set *set, + struct nft_set_elem *elem); + +static int nft_mapelem_deactivate(const struct nft_ctx *ctx, + struct nft_set *set, + const struct nft_set_iter *iter, + struct nft_set_elem *elem) +{ + nft_setelem_data_deactivate(ctx->net, set, elem); + + return 0; +} + +struct nft_set_elem_catchall { + struct list_head list; + struct rcu_head rcu; + void *elem; +}; + +static void nft_map_catchall_deactivate(const struct nft_ctx *ctx, + struct nft_set *set) +{ + u8 genmask = nft_genmask_next(ctx->net); + struct nft_set_elem_catchall *catchall; + struct nft_set_elem elem; + struct nft_set_ext *ext; + + list_for_each_entry(catchall, &set->catchall_list, list) { + ext = nft_set_elem_ext(set, catchall->elem); + if (!nft_set_elem_active(ext, genmask)) + continue; + + elem.priv = catchall->elem; + nft_setelem_data_deactivate(ctx->net, set, &elem); + break; + } +} + +static void nft_map_deactivate(const struct nft_ctx *ctx, struct nft_set *set) +{ + struct nft_set_iter iter = { + .genmask = nft_genmask_next(ctx->net), + .fn = nft_mapelem_deactivate, + }; + + set->ops->walk(ctx, set, &iter); + WARN_ON_ONCE(iter.err); + + nft_map_catchall_deactivate(ctx, set); +} + static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set) { int err; @@ -589,6 +641,9 @@ static int nft_delset(const struct nft_c if (err < 0) return err;
+ if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT)) + nft_map_deactivate(ctx, set); + nft_deactivate_next(ctx->net, set); ctx->table->use--;
@@ -3407,12 +3462,6 @@ int nft_setelem_validate(const struct nf return 0; }
-struct nft_set_elem_catchall { - struct list_head list; - struct rcu_head rcu; - void *elem; -}; - int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set) { u8 genmask = nft_genmask_next(ctx->net); @@ -4734,7 +4783,7 @@ err_set_expr_alloc: for (i = 0; i < set->num_exprs; i++) nft_expr_destroy(&ctx, set->exprs[i]); err_set_destroy: - ops->destroy(set); + ops->destroy(&ctx, set); err_set_init: kfree(set->name); err_set_name: @@ -4749,7 +4798,7 @@ static void nft_set_catchall_destroy(con
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) { list_del_rcu(&catchall->list); - nft_set_elem_destroy(set, catchall->elem, true); + nf_tables_set_elem_destroy(ctx, set, catchall->elem); kfree_rcu(catchall, rcu); } } @@ -4764,7 +4813,7 @@ static void nft_set_destroy(const struct for (i = 0; i < set->num_exprs; i++) nft_expr_destroy(ctx, set->exprs[i]);
- set->ops->destroy(set); + set->ops->destroy(ctx, set); nft_set_catchall_destroy(ctx, set); kfree(set->name); kvfree(set); @@ -4925,10 +4974,60 @@ static void nf_tables_unbind_set(const s } }
+static void nft_setelem_data_activate(const struct net *net, + const struct nft_set *set, + struct nft_set_elem *elem); + +static int nft_mapelem_activate(const struct nft_ctx *ctx, + struct nft_set *set, + const struct nft_set_iter *iter, + struct nft_set_elem *elem) +{ + nft_setelem_data_activate(ctx->net, set, elem); + + return 0; +} + +static void nft_map_catchall_activate(const struct nft_ctx *ctx, + struct nft_set *set) +{ + u8 genmask = nft_genmask_next(ctx->net); + struct nft_set_elem_catchall *catchall; + struct nft_set_elem elem; + struct nft_set_ext *ext; + + list_for_each_entry(catchall, &set->catchall_list, list) { + ext = nft_set_elem_ext(set, catchall->elem); + if (!nft_set_elem_active(ext, genmask)) + continue; + + elem.priv = catchall->elem; + nft_setelem_data_activate(ctx->net, set, &elem); + break; + } +} + +static void nft_map_activate(const struct nft_ctx *ctx, struct nft_set *set) +{ + struct nft_set_iter iter = { + .genmask = nft_genmask_next(ctx->net), + .fn = nft_mapelem_activate, + }; + + set->ops->walk(ctx, set, &iter); + WARN_ON_ONCE(iter.err); + + nft_map_catchall_activate(ctx, set); +} + void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set) { - if (nft_set_is_anonymous(set)) + if (nft_set_is_anonymous(set)) { + if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT)) + nft_map_activate(ctx, set); + nft_clear(ctx->net, set); + }
set->use++; } @@ -4947,13 +5046,20 @@ void nf_tables_deactivate_set(const stru set->use--; break; case NFT_TRANS_PREPARE: - if (nft_set_is_anonymous(set)) - nft_deactivate_next(ctx->net, set); + if (nft_set_is_anonymous(set)) { + if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT)) + nft_map_deactivate(ctx, set);
+ nft_deactivate_next(ctx->net, set); + } set->use--; return; case NFT_TRANS_ABORT: case NFT_TRANS_RELEASE: + if (nft_set_is_anonymous(set) && + set->flags & (NFT_SET_MAP | NFT_SET_OBJECT)) + nft_map_deactivate(ctx, set); + set->use--; fallthrough; default: @@ -5669,6 +5775,7 @@ static void nft_set_elem_expr_destroy(co __nft_set_elem_expr_destroy(ctx, expr); }
+/* Drop references and destroy. Called from gc, dynset and abort path. */ void nft_set_elem_destroy(const struct nft_set *set, void *elem, bool destroy_expr) { @@ -5690,11 +5797,11 @@ void nft_set_elem_destroy(const struct n } EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
-/* Only called from commit path, nft_setelem_data_deactivate() already deals - * with the refcounting from the preparation phase. +/* Destroy element. References have been already dropped in the preparation + * path via nft_setelem_data_deactivate(). */ -static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx, - const struct nft_set *set, void *elem) +void nf_tables_set_elem_destroy(const struct nft_ctx *ctx, + const struct nft_set *set, void *elem) { struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
@@ -9323,6 +9430,9 @@ static int __nf_tables_abort(struct net case NFT_MSG_DELSET: trans->ctx.table->use++; nft_clear(trans->ctx.net, nft_trans_set(trans)); + if (nft_trans_set(trans)->flags & (NFT_SET_MAP | NFT_SET_OBJECT)) + nft_map_activate(&trans->ctx, nft_trans_set(trans)); + nft_trans_destroy(trans); break; case NFT_MSG_NEWSETELEM: @@ -10089,6 +10199,9 @@ static void __nft_release_table(struct n list_for_each_entry_safe(set, ns, &table->sets, list) { list_del(&set->list); table->use--; + if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT)) + nft_map_deactivate(&ctx, set); + nft_set_destroy(&ctx, set); } list_for_each_entry_safe(obj, ne, &table->objects, list) { --- a/net/netfilter/nft_set_bitmap.c +++ b/net/netfilter/nft_set_bitmap.c @@ -271,13 +271,14 @@ static int nft_bitmap_init(const struct return 0; }
-static void nft_bitmap_destroy(const struct nft_set *set) +static void nft_bitmap_destroy(const struct nft_ctx *ctx, + const struct nft_set *set) { struct nft_bitmap *priv = nft_set_priv(set); struct nft_bitmap_elem *be, *n;
list_for_each_entry_safe(be, n, &priv->list, head) - nft_set_elem_destroy(set, be, true); + nf_tables_set_elem_destroy(ctx, set, be); }
static bool nft_bitmap_estimate(const struct nft_set_desc *desc, u32 features, --- a/net/netfilter/nft_set_hash.c +++ b/net/netfilter/nft_set_hash.c @@ -400,19 +400,31 @@ static int nft_rhash_init(const struct n return 0; }
+struct nft_rhash_ctx { + const struct nft_ctx ctx; + const struct nft_set *set; +}; + static void nft_rhash_elem_destroy(void *ptr, void *arg) { - nft_set_elem_destroy(arg, ptr, true); + struct nft_rhash_ctx *rhash_ctx = arg; + + nf_tables_set_elem_destroy(&rhash_ctx->ctx, rhash_ctx->set, ptr); }
-static void nft_rhash_destroy(const struct nft_set *set) +static void nft_rhash_destroy(const struct nft_ctx *ctx, + const struct nft_set *set) { struct nft_rhash *priv = nft_set_priv(set); + struct nft_rhash_ctx rhash_ctx = { + .ctx = *ctx, + .set = set, + };
cancel_delayed_work_sync(&priv->gc_work); rcu_barrier(); rhashtable_free_and_destroy(&priv->ht, nft_rhash_elem_destroy, - (void *)set); + (void *)&rhash_ctx); }
/* Number of buckets is stored in u32, so cap our result to 1U<<31 */ @@ -643,7 +655,8 @@ static int nft_hash_init(const struct nf return 0; }
-static void nft_hash_destroy(const struct nft_set *set) +static void nft_hash_destroy(const struct nft_ctx *ctx, + const struct nft_set *set) { struct nft_hash *priv = nft_set_priv(set); struct nft_hash_elem *he; @@ -653,7 +666,7 @@ static void nft_hash_destroy(const struc for (i = 0; i < priv->buckets; i++) { hlist_for_each_entry_safe(he, next, &priv->table[i], node) { hlist_del_rcu(&he->node); - nft_set_elem_destroy(set, he, true); + nf_tables_set_elem_destroy(ctx, set, he); } } } --- a/net/netfilter/nft_set_pipapo.c +++ b/net/netfilter/nft_set_pipapo.c @@ -2152,10 +2152,12 @@ out_scratch:
/** * nft_set_pipapo_match_destroy() - Destroy elements from key mapping array + * @ctx: context * @set: nftables API set representation * @m: matching data pointing to key mapping array */ -static void nft_set_pipapo_match_destroy(const struct nft_set *set, +static void nft_set_pipapo_match_destroy(const struct nft_ctx *ctx, + const struct nft_set *set, struct nft_pipapo_match *m) { struct nft_pipapo_field *f; @@ -2172,15 +2174,17 @@ static void nft_set_pipapo_match_destroy
e = f->mt[r].e;
- nft_set_elem_destroy(set, e, true); + nf_tables_set_elem_destroy(ctx, set, e); } }
/** * nft_pipapo_destroy() - Free private data for set and all committed elements + * @ctx: context * @set: nftables API set representation */ -static void nft_pipapo_destroy(const struct nft_set *set) +static void nft_pipapo_destroy(const struct nft_ctx *ctx, + const struct nft_set *set) { struct nft_pipapo *priv = nft_set_priv(set); struct nft_pipapo_match *m; @@ -2190,7 +2194,7 @@ static void nft_pipapo_destroy(const str if (m) { rcu_barrier();
- nft_set_pipapo_match_destroy(set, m); + nft_set_pipapo_match_destroy(ctx, set, m);
#ifdef NFT_PIPAPO_ALIGN free_percpu(m->scratch_aligned); @@ -2207,7 +2211,7 @@ static void nft_pipapo_destroy(const str m = priv->clone;
if (priv->dirty) - nft_set_pipapo_match_destroy(set, m); + nft_set_pipapo_match_destroy(ctx, set, m);
#ifdef NFT_PIPAPO_ALIGN free_percpu(priv->clone->scratch_aligned); --- a/net/netfilter/nft_set_rbtree.c +++ b/net/netfilter/nft_set_rbtree.c @@ -664,7 +664,8 @@ static int nft_rbtree_init(const struct return 0; }
-static void nft_rbtree_destroy(const struct nft_set *set) +static void nft_rbtree_destroy(const struct nft_ctx *ctx, + const struct nft_set *set) { struct nft_rbtree *priv = nft_set_priv(set); struct nft_rbtree_elem *rbe; @@ -675,7 +676,7 @@ static void nft_rbtree_destroy(const str while ((node = priv->root.rb_node) != NULL) { rb_erase(node, &priv->root); rbe = rb_entry(node, struct nft_rbtree_elem, node); - nft_set_elem_destroy(set, rbe, true); + nf_tables_set_elem_destroy(ctx, set, rbe); } }
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 247c8d2f9837a3e29e3b6b7a4aa9c36c37659dd4 ]
A couple of functions from fs/pipe.c are used both internally and for the watch queue code, but the declaration is only visible when the latter is enabled:
fs/pipe.c:1254:5: error: no previous prototype for 'pipe_resize_ring' fs/pipe.c:758:15: error: no previous prototype for 'account_pipe_buffers' fs/pipe.c:764:6: error: no previous prototype for 'too_many_pipe_buffers_soft' fs/pipe.c:771:6: error: no previous prototype for 'too_many_pipe_buffers_hard' fs/pipe.c:777:6: error: no previous prototype for 'pipe_is_unprivileged_user'
Make the visible unconditionally to avoid these warnings.
Fixes: c73be61cede5 ("pipe: Add general notification queue support") Signed-off-by: Arnd Bergmann arnd@arndb.de Message-Id: 20230516195629.551602-1-arnd@kernel.org Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/pipe_fs_i.h | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 18dcca51829e2..d15190b3e0326 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -265,18 +265,14 @@ void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
extern const struct pipe_buf_operations nosteal_pipe_buf_ops;
-#ifdef CONFIG_WATCH_QUEUE unsigned long account_pipe_buffers(struct user_struct *user, unsigned long old, unsigned long new); bool too_many_pipe_buffers_soft(unsigned long user_bufs); bool too_many_pipe_buffers_hard(unsigned long user_bufs); bool pipe_is_unprivileged_user(void); -#endif
/* for F_SETPIPE_SZ and F_GETPIPE_SZ */ -#ifdef CONFIG_WATCH_QUEUE int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots); -#endif long pipe_fcntl(struct file *, unsigned int, unsigned long arg); struct pipe_inode_info *get_pipe_info(struct file *file, bool for_splice);
From: Shawn Wang shawnwang@linux.alibaba.com
[ Upstream commit 2997d94b5dd0e8b10076f5e0b6f18410c73e28bd ]
When writing a task id to the "tasks" file in an rdtgroup, rdtgroup_tasks_write() treats the pid as a number in the current pid namespace. But when reading the "tasks" file, rdtgroup_tasks_show() shows the list of global pids from the init namespace, which is confusing and incorrect.
To be more robust, let the "tasks" file only show pids in the current pid namespace.
Fixes: e02737d5b826 ("x86/intel_rdt: Add tasks files") Signed-off-by: Shawn Wang shawnwang@linux.alibaba.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Acked-by: Reinette Chatre reinette.chatre@intel.com Acked-by: Fenghua Yu fenghua.yu@intel.com Tested-by: Reinette Chatre reinette.chatre@intel.com Link: https://lore.kernel.org/all/20230116071246.97717-1-shawnwang@linux.alibaba.c... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index 421d31718fbd8..2ec16477eb3e1 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -731,11 +731,15 @@ static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of, static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s) { struct task_struct *p, *t; + pid_t pid;
rcu_read_lock(); for_each_process_thread(p, t) { - if (is_closid_match(t, r) || is_rmid_match(t, r)) - seq_printf(s, "%d\n", t->pid); + if (is_closid_match(t, r) || is_rmid_match(t, r)) { + pid = task_pid_vnr(t); + if (pid) + seq_printf(s, "%d\n", pid); + } } rcu_read_unlock(); }
From: Li Nan linan122@huawei.com
[ Upstream commit 8d211554679d0b23702bd32ba04aeac0c1c4f660 ]
adjust_inuse_and_calc_cost() use spin_lock_irq() and IRQ will be enabled when unlock. DEADLOCK might happen if we have held other locks and disabled IRQ before invoking it.
Fix it by using spin_lock_irqsave() instead, which can keep IRQ state consistent with before when unlock.
================================ WARNING: inconsistent lock state 5.10.0-02758-g8e5f91fd772f #26 Not tainted -------------------------------- inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. kworker/2:3/388 [HC0[0]:SC0[0]:HE0:SE1] takes: ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: spin_lock_irq ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: bfq_bio_merge+0x141/0x390 {IN-HARDIRQ-W} state was registered at: __lock_acquire+0x3d7/0x1070 lock_acquire+0x197/0x4a0 __raw_spin_lock_irqsave _raw_spin_lock_irqsave+0x3b/0x60 bfq_idle_slice_timer_body bfq_idle_slice_timer+0x53/0x1d0 __run_hrtimer+0x477/0xa70 __hrtimer_run_queues+0x1c6/0x2d0 hrtimer_interrupt+0x302/0x9e0 local_apic_timer_interrupt __sysvec_apic_timer_interrupt+0xfd/0x420 run_sysvec_on_irqstack_cond sysvec_apic_timer_interrupt+0x46/0xa0 asm_sysvec_apic_timer_interrupt+0x12/0x20 irq event stamp: 837522 hardirqs last enabled at (837521): [<ffffffff84b9419d>] __raw_spin_unlock_irqrestore hardirqs last enabled at (837521): [<ffffffff84b9419d>] _raw_spin_unlock_irqrestore+0x3d/0x40 hardirqs last disabled at (837522): [<ffffffff84b93fa3>] __raw_spin_lock_irq hardirqs last disabled at (837522): [<ffffffff84b93fa3>] _raw_spin_lock_irq+0x43/0x50 softirqs last enabled at (835852): [<ffffffff84e00558>] __do_softirq+0x558/0x8ec softirqs last disabled at (835845): [<ffffffff84c010ff>] asm_call_irq_on_stack+0xf/0x20
other info that might help us debug this: Possible unsafe locking scenario:
CPU0 ---- lock(&bfqd->lock); <Interrupt> lock(&bfqd->lock);
*** DEADLOCK ***
3 locks held by kworker/2:3/388: #0: ffff888107af0f38 ((wq_completion)kthrotld){+.+.}-{0:0}, at: process_one_work+0x742/0x13f0 #1: ffff8881176bfdd8 ((work_completion)(&td->dispatch_work)){+.+.}-{0:0}, at: process_one_work+0x777/0x13f0 #2: ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: spin_lock_irq #2: ffff888118c00c28 (&bfqd->lock){?.-.}-{2:2}, at: bfq_bio_merge+0x141/0x390
stack backtrace: CPU: 2 PID: 388 Comm: kworker/2:3 Not tainted 5.10.0-02758-g8e5f91fd772f #26 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 Workqueue: kthrotld blk_throtl_dispatch_work_fn Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x107/0x167 print_usage_bug valid_state mark_lock_irq.cold+0x32/0x3a mark_lock+0x693/0xbc0 mark_held_locks+0x9e/0xe0 __trace_hardirqs_on_caller lockdep_hardirqs_on_prepare.part.0+0x151/0x360 trace_hardirqs_on+0x5b/0x180 __raw_spin_unlock_irq _raw_spin_unlock_irq+0x24/0x40 spin_unlock_irq adjust_inuse_and_calc_cost+0x4fb/0x970 ioc_rqos_merge+0x277/0x740 __rq_qos_merge+0x62/0xb0 rq_qos_merge bio_attempt_back_merge+0x12c/0x4a0 blk_mq_sched_try_merge+0x1b6/0x4d0 bfq_bio_merge+0x24a/0x390 __blk_mq_sched_bio_merge+0xa6/0x460 blk_mq_sched_bio_merge blk_mq_submit_bio+0x2e7/0x1ee0 __submit_bio_noacct_mq+0x175/0x3b0 submit_bio_noacct+0x1fb/0x270 blk_throtl_dispatch_work_fn+0x1ef/0x2b0 process_one_work+0x83e/0x13f0 process_scheduled_works worker_thread+0x7e3/0xd80 kthread+0x353/0x470 ret_from_fork+0x1f/0x30
Fixes: b0853ab4a238 ("blk-iocost: revamp in-period donation snapbacks") Signed-off-by: Li Nan linan122@huawei.com Acked-by: Tejun Heo tj@kernel.org Reviewed-by: Yu Kuai yukuai3@huawei.com Link: https://lore.kernel.org/r/20230527091904.3001833-1-linan666@huaweicloud.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-iocost.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 43cf04966c745..f95feabb3ca88 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -2448,6 +2448,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime, u32 hwi, adj_step; s64 margin; u64 cost, new_inuse; + unsigned long flags;
current_hweight(iocg, NULL, &hwi); old_hwi = hwi; @@ -2466,11 +2467,11 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime, iocg->inuse == iocg->active) return cost;
- spin_lock_irq(&ioc->lock); + spin_lock_irqsave(&ioc->lock, flags);
/* we own inuse only when @iocg is in the normal active state */ if (iocg->abs_vdebt || list_empty(&iocg->active_list)) { - spin_unlock_irq(&ioc->lock); + spin_unlock_irqrestore(&ioc->lock, flags); return cost; }
@@ -2491,7 +2492,7 @@ static u64 adjust_inuse_and_calc_cost(struct ioc_gq *iocg, u64 vtime, } while (time_after64(vtime + cost, now->vnow) && iocg->inuse != iocg->active);
- spin_unlock_irq(&ioc->lock); + spin_unlock_irqrestore(&ioc->lock, flags);
TRACE_IOCG_PATH(inuse_adjust, iocg, now, old_inuse, iocg->inuse, old_hwi, hwi);
From: Li Nan linan122@huawei.com
[ Upstream commit 301867b1c16805aebbc306aafa6ecdc68b73c7e5 ]
If we write a large number to md/bitmap_set_bits, md_bitmap_checkpage() will return -EINVAL because 'page >= bitmap->pages', but the return value was not checked immediately in md_bitmap_get_counter() in order to set *blocks value and slab-out-of-bounds occurs.
Move check of 'page >= bitmap->pages' to md_bitmap_get_counter() and return directly if true.
Fixes: ef4256733506 ("md/bitmap: optimise scanning of empty bitmaps.") Signed-off-by: Li Nan linan122@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230515134808.3936750-2-linan666@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/md-bitmap.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 062142559caa3..adada558a1b09 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -54,14 +54,7 @@ __acquires(bitmap->lock) { unsigned char *mappage;
- if (page >= bitmap->pages) { - /* This can happen if bitmap_start_sync goes beyond - * End-of-device while looking for a whole page. - * It is harmless. - */ - return -EINVAL; - } - + WARN_ON_ONCE(page >= bitmap->pages); if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */ return 0;
@@ -1365,6 +1358,14 @@ __acquires(bitmap->lock) sector_t csize; int err;
+ if (page >= bitmap->pages) { + /* + * This can happen if bitmap_start_sync goes beyond + * End-of-device while looking for a whole page or + * user set a huge number to sysfs bitmap_set_bits. + */ + return NULL; + } err = md_bitmap_checkpage(bitmap, page, create, 0);
if (bitmap->bp[page].hijacked ||
From: Li Nan linan122@huawei.com
[ Upstream commit 6beb489b2eed25978523f379a605073f99240c50 ]
There is no input check when echo md/safe_mode_delay in safe_delay_store(). And msec might also overflow when HZ < 1000 in safe_delay_show(), Fix it by checking overflow in safe_delay_store() and use unsigned long conversion in safe_delay_show().
Fixes: 72e02075a33f ("md: factor out parsing of fixed-point numbers") Signed-off-by: Li Nan linan122@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230522072535.1523740-2-linan666@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/md.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c index bd0c9dfac9815..9648801e7910a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3872,8 +3872,9 @@ int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale) static ssize_t safe_delay_show(struct mddev *mddev, char *page) { - int msec = (mddev->safemode_delay*1000)/HZ; - return sprintf(page, "%d.%03d\n", msec/1000, msec%1000); + unsigned int msec = ((unsigned long)mddev->safemode_delay*1000)/HZ; + + return sprintf(page, "%u.%03u\n", msec/1000, msec%1000); } static ssize_t safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len) @@ -3885,7 +3886,7 @@ safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len) return -EINVAL; }
- if (strict_strtoul_scaled(cbuf, &msec, 3) < 0) + if (strict_strtoul_scaled(cbuf, &msec, 3) < 0 || msec > UINT_MAX / HZ) return -EINVAL; if (msec == 0) mddev->safemode_delay = 0;
From: Li Nan linan122@huawei.com
[ Upstream commit f8b20a405428803bd9881881d8242c9d72c6b2b2 ]
There is no input check when echo md/max_read_errors and overflow might occur. Add check of input number.
Fixes: 1e50915fe0bb ("raid: improve MD/raid10 handling of correctable read errors.") Signed-off-by: Li Nan linan122@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230522072535.1523740-3-linan666@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/md.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/md/md.c b/drivers/md/md.c index 9648801e7910a..5a21aeedc1ba7 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4556,6 +4556,8 @@ max_corrected_read_errors_store(struct mddev *mddev, const char *buf, size_t len rv = kstrtouint(buf, 10, &n); if (rv < 0) return rv; + if (n > INT_MAX) + return -EINVAL; atomic_set(&mddev->max_corr_read_errors, n); return len; }
From: Li Nan linan122@huawei.com
[ Upstream commit 34817a2441747b48e444cb0e05d84e14bc9443da ]
There are two check of 'mreplace' in raid10_sync_request(). In the first check, 'need_replace' will be set and 'mreplace' will be used later if no-Faulty 'mreplace' exists, In the second check, 'mreplace' will be set to NULL if it is Faulty, but 'need_replace' will not be changed accordingly. null-ptr-deref occurs if Faulty is set between two check.
Fix it by merging two checks into one. And replace 'need_replace' with 'mreplace' because their values are always the same.
Fixes: ee37d7314a32 ("md/raid10: Fix raid10 replace hang when new added disk faulty") Signed-off-by: Li Nan linan122@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230527072218.2365857-2-linan666@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/raid10.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 1f5589c5294dc..d3f8156da44e5 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3412,7 +3412,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, int must_sync; int any_working; int need_recover = 0; - int need_replace = 0; struct raid10_info *mirror = &conf->mirrors[i]; struct md_rdev *mrdev, *mreplace;
@@ -3424,11 +3423,10 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, !test_bit(Faulty, &mrdev->flags) && !test_bit(In_sync, &mrdev->flags)) need_recover = 1; - if (mreplace != NULL && - !test_bit(Faulty, &mreplace->flags)) - need_replace = 1; + if (mreplace && test_bit(Faulty, &mreplace->flags)) + mreplace = NULL;
- if (!need_recover && !need_replace) { + if (!need_recover && !mreplace) { rcu_read_unlock(); continue; } @@ -3444,8 +3442,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, rcu_read_unlock(); continue; } - if (mreplace && test_bit(Faulty, &mreplace->flags)) - mreplace = NULL; /* Unless we are doing a full sync, or a replacement * we only need to recover the block if it is set in * the bitmap @@ -3568,11 +3564,11 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, bio = r10_bio->devs[1].repl_bio; if (bio) bio->bi_end_io = NULL; - /* Note: if need_replace, then bio + /* Note: if replace is not NULL, then bio * cannot be NULL as r10buf_pool_alloc will * have allocated it. */ - if (!need_replace) + if (!mreplace) break; bio->bi_next = biolist; biolist = bio;
From: Li Nan linan122@huawei.com
[ Upstream commit 2ae6aaf76912bae53c74b191569d2ab484f24bf3 ]
When removing a disk with replacement, the replacement will be used to replace rdev. During this process, there is a brief window in which both rdev and replacement are read as NULL in raid10_write_request(). This will result in io not being submitted but it should be.
//remove //write raid10_remove_disk raid10_write_request mirror->rdev = NULL read rdev -> NULL mirror->rdev = mirror->replacement mirror->replacement = NULL read replacement -> NULL
Fix it by reading replacement first and rdev later, meanwhile, use smp_mb() to prevent memory reordering.
Fixes: 475b0321a4df ("md/raid10: writes should get directed to replacement as well as original.") Signed-off-by: Li Nan linan122@huawei.com Reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230602091839.743798-3-linan666@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/raid10.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index d3f8156da44e5..99607d51d128d 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -752,8 +752,16 @@ static struct md_rdev *read_balance(struct r10conf *conf, disk = r10_bio->devs[slot].devnum; rdev = rcu_dereference(conf->mirrors[disk].replacement); if (rdev == NULL || test_bit(Faulty, &rdev->flags) || - r10_bio->devs[slot].addr + sectors > rdev->recovery_offset) + r10_bio->devs[slot].addr + sectors > + rdev->recovery_offset) { + /* + * Read replacement first to prevent reading both rdev + * and replacement as NULL during replacement replace + * rdev. + */ + smp_mb(); rdev = rcu_dereference(conf->mirrors[disk].rdev); + } if (rdev == NULL || test_bit(Faulty, &rdev->flags)) continue; @@ -1449,9 +1457,15 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
for (i = 0; i < conf->copies; i++) { int d = r10_bio->devs[i].devnum; - struct md_rdev *rdev = rcu_dereference(conf->mirrors[d].rdev); - struct md_rdev *rrdev = rcu_dereference( - conf->mirrors[d].replacement); + struct md_rdev *rdev, *rrdev; + + rrdev = rcu_dereference(conf->mirrors[d].replacement); + /* + * Read replacement first to prevent reading both rdev and + * replacement as NULL during replacement replace rdev. + */ + smp_mb(); + rdev = rcu_dereference(conf->mirrors[d].rdev); if (rdev == rrdev) rrdev = NULL; if (rdev && (test_bit(Faulty, &rdev->flags)))
From: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de
[ Upstream commit 4848229494a323eeaab62eee5574ef9f7de80374 ]
The initialization function for the J-Core AIC aic_irq_of_init() is currently missing the call to irq_alloc_descs() which allocates and initializes all the IRQ descriptors. Add missing function call and return the error code from irq_alloc_descs() in case the allocation fails.
Fixes: 981b58f66cfc ("irqchip/jcore-aic: Add J-Core AIC driver") Signed-off-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Tested-by: Rob Landley rob@landley.net Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20230510163343.43090-1-glaubitz@physik.fu-berlin.d... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-jcore-aic.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/irqchip/irq-jcore-aic.c b/drivers/irqchip/irq-jcore-aic.c index 5f47d8ee4ae39..b9dcc8e78c750 100644 --- a/drivers/irqchip/irq-jcore-aic.c +++ b/drivers/irqchip/irq-jcore-aic.c @@ -68,6 +68,7 @@ static int __init aic_irq_of_init(struct device_node *node, unsigned min_irq = JCORE_AIC2_MIN_HWIRQ; unsigned dom_sz = JCORE_AIC_MAX_HWIRQ+1; struct irq_domain *domain; + int ret;
pr_info("Initializing J-Core AIC\n");
@@ -100,6 +101,12 @@ static int __init aic_irq_of_init(struct device_node *node, jcore_aic.irq_unmask = noop; jcore_aic.name = "AIC";
+ ret = irq_alloc_descs(-1, min_irq, dom_sz - min_irq, + of_node_to_nid(node)); + + if (ret < 0) + return ret; + domain = irq_domain_add_legacy(node, dom_sz - min_irq, min_irq, min_irq, &jcore_aic_irqdomain_ops, &jcore_aic);
From: Chuck Lever chuck.lever@oracle.com
[ Upstream commit baf6d18b116b7dc84ed5e212c3a89f17cdc3f28c ]
I noticed that svc_rqst_release_pages() was still unnecessarily releasing a page when svc_rdma_recvfrom() returns zero.
Fixes: a53d5cb0646a ("svcrdma: Avoid releasing a page in svc_xprt_release()") Reviewed-by: Jeff Layton jlayton@kernel.org Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index 3ad4291148a68..0377679678f93 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -791,6 +791,12 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) struct svc_rdma_recv_ctxt *ctxt; int ret;
+ /* Prevent svc_xprt_release() from releasing pages in rq_pages + * when returning 0 or an error. + */ + rqstp->rq_respages = rqstp->rq_pages; + rqstp->rq_next_page = rqstp->rq_respages; + rqstp->rq_xprt_ctxt = NULL;
ctxt = NULL; @@ -814,12 +820,6 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) DMA_FROM_DEVICE); svc_rdma_build_arg_xdr(rqstp, ctxt);
- /* Prevent svc_xprt_release from releasing pages in rq_pages - * if we return 0 or an error. - */ - rqstp->rq_respages = rqstp->rq_pages; - rqstp->rq_next_page = rqstp->rq_respages; - ret = svc_rdma_xdr_decode_req(&rqstp->rq_arg, ctxt); if (ret < 0) goto out_err;
From: Thomas Gleixner tglx@linutronix.de
[ Upstream commit 9d9e522010eb5685d8b53e8a24320653d9d4cbbf ]
itimer_delete() has a retry loop when the timer is concurrently expired. On non-RT kernels this just spin-waits until the timer callback has completed, except for posix CPU timers which have HAVE_POSIX_CPU_TIMERS_TASK_WORK enabled.
In that case and on RT kernels the existing task could live lock when preempting the task which does the timer delivery.
Replace spin_unlock() with an invocation of timer_wait_running() to handle it the same way as the other retry loops in the posix timer code.
Fixes: ec8f954a40da ("posix-timers: Use a callback for cancel synchronization on PREEMPT_RT") Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Frederic Weisbecker frederic@kernel.org Link: https://lore.kernel.org/r/87v8g7c50d.ffs@tglx Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/time/posix-timers.c | 43 +++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 8 deletions(-)
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 808a247205a9a..ed3c4a9543982 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -1037,27 +1037,52 @@ SYSCALL_DEFINE1(timer_delete, timer_t, timer_id) }
/* - * return timer owned by the process, used by exit_itimers + * Delete a timer if it is armed, remove it from the hash and schedule it + * for RCU freeing. */ static void itimer_delete(struct k_itimer *timer) { -retry_delete: - spin_lock_irq(&timer->it_lock); + unsigned long flags; + + /* + * irqsave is required to make timer_wait_running() work. + */ + spin_lock_irqsave(&timer->it_lock, flags);
+retry_delete: + /* + * Even if the timer is not longer accessible from other tasks + * it still might be armed and queued in the underlying timer + * mechanism. Worse, that timer mechanism might run the expiry + * function concurrently. + */ if (timer_delete_hook(timer) == TIMER_RETRY) { - spin_unlock_irq(&timer->it_lock); + /* + * Timer is expired concurrently, prevent livelocks + * and pointless spinning on RT. + * + * timer_wait_running() drops timer::it_lock, which opens + * the possibility for another task to delete the timer. + * + * That's not possible here because this is invoked from + * do_exit() only for the last thread of the thread group. + * So no other task can access and delete that timer. + */ + if (WARN_ON_ONCE(timer_wait_running(timer, &flags) != timer)) + return; + goto retry_delete; } list_del(&timer->list);
- spin_unlock_irq(&timer->it_lock); + spin_unlock_irqrestore(&timer->it_lock, flags); release_posix_timer(timer, IT_ID_SET); }
/* - * This is called by do_exit or de_thread, only when nobody else can - * modify the signal->posix_timers list. Yet we need sighand->siglock - * to prevent the race with /proc/pid/timers. + * Invoked from do_exit() when the last thread of a thread group exits. + * At that point no other task can access the timers of the dying + * task anymore. */ void exit_itimers(struct task_struct *tsk) { @@ -1067,10 +1092,12 @@ void exit_itimers(struct task_struct *tsk) if (list_empty(&tsk->signal->posix_timers)) return;
+ /* Protect against concurrent read via /proc/$PID/timers */ spin_lock_irq(&tsk->sighand->siglock); list_replace_init(&tsk->signal->posix_timers, &timers); spin_unlock_irq(&tsk->sighand->siglock);
+ /* The timers are not longer accessible via tsk::signal */ while (!list_empty(&timers)) { tmr = list_first_entry(&timers, struct k_itimer, list); itimer_delete(tmr);
From: Sebastian Andrzej Siewior bigeasy@linutronix.de
[ Upstream commit 2951580ba6adb082bb6b7154a5ecb24e7c1f7569 ]
The trace output for the HRTIMER_MODE_.*_HARD modes is seen as a number since these modes are not decoded. The author was not aware of the fancy decoding function which makes the life easier.
Extend decode_hrtimer_mode() with the additional HRTIMER_MODE_.*_HARD modes.
Fixes: ae6683d815895 ("hrtimer: Introduce HARD expiry mode") Signed-off-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Mukesh Ojha quic_mojha@quicinc.com Acked-by: Steven Rostedt (Google) rostedt@goodmis.org Link: https://lore.kernel.org/r/20230418143854.8vHWQKLM@linutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/trace/events/timer.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h index 1cf012de6442e..d49e44fcc10f2 100644 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h @@ -156,7 +156,11 @@ DEFINE_EVENT(timer_class, timer_cancel, { HRTIMER_MODE_ABS_SOFT, "ABS|SOFT" }, \ { HRTIMER_MODE_REL_SOFT, "REL|SOFT" }, \ { HRTIMER_MODE_ABS_PINNED_SOFT, "ABS|PINNED|SOFT" }, \ - { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" }) + { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" }, \ + { HRTIMER_MODE_ABS_HARD, "ABS|HARD" }, \ + { HRTIMER_MODE_REL_HARD, "REL|HARD" }, \ + { HRTIMER_MODE_ABS_PINNED_HARD, "ABS|PINNED|HARD" }, \ + { HRTIMER_MODE_REL_PINNED_HARD, "REL|PINNED|HARD" })
/** * hrtimer_init - called when the hrtimer is initialized
From: Feng Mingxi m202271825@hust.edu.cn
[ Upstream commit 8b5bf64c89c7100c921bd807ba39b2eb003061ab ]
Smatch reports: drivers/clocksource/timer-cadence-ttc.c:529 ttc_timer_probe() warn: 'timer_baseaddr' from of_iomap() not released on lines: 498,508,516.
timer_baseaddr may have the problem of not being released after use, I replaced it with the devm_of_iomap() function and added the clk_put() function to cleanup the "clk_ce" and "clk_cs".
Fixes: e932900a3279 ("arm: zynq: Use standard timer binding") Fixes: 70504f311d4b ("clocksource/drivers/cadence_ttc: Convert init function to return error") Signed-off-by: Feng Mingxi m202271825@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Acked-by: Michal Simek michal.simek@amd.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/20230425065611.702917-1-m202271825@hust.edu.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clocksource/timer-cadence-ttc.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/clocksource/timer-cadence-ttc.c b/drivers/clocksource/timer-cadence-ttc.c index 4efd0cf3b602d..0d52e28fea4de 100644 --- a/drivers/clocksource/timer-cadence-ttc.c +++ b/drivers/clocksource/timer-cadence-ttc.c @@ -486,10 +486,10 @@ static int __init ttc_timer_probe(struct platform_device *pdev) * and use it. Note that the event timer uses the interrupt and it's the * 2nd TTC hence the irq_of_parse_and_map(,1) */ - timer_baseaddr = of_iomap(timer, 0); - if (!timer_baseaddr) { + timer_baseaddr = devm_of_iomap(&pdev->dev, timer, 0, NULL); + if (IS_ERR(timer_baseaddr)) { pr_err("ERROR: invalid timer base address\n"); - return -ENXIO; + return PTR_ERR(timer_baseaddr); }
irq = irq_of_parse_and_map(timer, 1); @@ -513,20 +513,27 @@ static int __init ttc_timer_probe(struct platform_device *pdev) clk_ce = of_clk_get(timer, clksel); if (IS_ERR(clk_ce)) { pr_err("ERROR: timer input clock not found\n"); - return PTR_ERR(clk_ce); + ret = PTR_ERR(clk_ce); + goto put_clk_cs; }
ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width); if (ret) - return ret; + goto put_clk_ce;
ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); if (ret) - return ret; + goto put_clk_ce;
pr_info("%pOFn #0 at %p, irq=%d\n", timer, timer_baseaddr, irq);
return 0; + +put_clk_ce: + clk_put(clk_ce); +put_clk_cs: + clk_put(clk_cs); + return ret; }
static const struct of_device_id ttc_timer_of_match[] = {
From: Nikita Zhandarovich n.zhandarovich@fintech.ru
[ Upstream commit e5d1c8722083f0332dcd3c85fa1273d85fb6bed8 ]
Currently, while calculating residency and latency values, right operands may overflow if resulting values are big enough.
To prevent this, albeit unlikely case, play it safe and convert right operands to left ones' type s64.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
Fixes: 30f604283e05 ("PM / Domains: Allow domain power states to be read from DT") Signed-off-by: Nikita Zhandarovich n.zhandarovich@fintech.ru Acked-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/power/domain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 24a82e252b7e1..6ffee01e174da 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2860,10 +2860,10 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
err = of_property_read_u32(state_node, "min-residency-us", &residency); if (!err) - genpd_state->residency_ns = 1000 * residency; + genpd_state->residency_ns = 1000LL * residency;
- genpd_state->power_on_latency_ns = 1000 * exit_latency; - genpd_state->power_off_latency_ns = 1000 * entry_latency; + genpd_state->power_on_latency_ns = 1000LL * exit_latency; + genpd_state->power_off_latency_ns = 1000LL * entry_latency; genpd_state->fwnode = &state_node->fwnode;
return 0;
From: Robin Murphy robin.murphy@arm.com
[ Upstream commit 71746c995cac92fcf6a65661b51211cf2009d7f0 ]
It turns out that my naive DTC reset logic fails to work as intended, since, after checking with the hardware designers, the PMU actually needs to be fully enabled in order to correctly clear any pending overflows. Therefore, invert the sequence to start with turning on both enables so that we can reliably get the DTCs into a known state, then moving to our normal counters-stopped state from there. Since all the DTM counters have already been unpaired during the initial discovery pass, we just need to additionally reset the cycle counters to ensure that no other unexpected overflows occur during this period.
Fixes: 0ba64770a2f2 ("perf: Add Arm CMN-600 PMU driver") Reported-by: Geoff Blake blakgeof@amazon.com Signed-off-by: Robin Murphy robin.murphy@arm.com Link: https://lore.kernel.org/r/0ea4559261ea394f827c9aee5168c77a60aaee03.168494638... Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/perf/arm-cmn.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c index 400eb7f579dce..40945343c4cc1 100644 --- a/drivers/perf/arm-cmn.c +++ b/drivers/perf/arm-cmn.c @@ -1254,9 +1254,10 @@ static int arm_cmn_init_dtc(struct arm_cmn *cmn, struct arm_cmn_node *dn, int id if (dtc->irq < 0) return dtc->irq;
- writel_relaxed(0, dtc->base + CMN_DT_PMCR); + writel_relaxed(CMN_DT_DTC_CTL_DT_EN, dtc->base + CMN_DT_DTC_CTL); + writel_relaxed(CMN_DT_PMCR_PMU_EN | CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR); + writeq_relaxed(0, dtc->base + CMN_DT_PMCCNTR); writel_relaxed(0x1ff, dtc->base + CMN_DT_PMOVSR_CLR); - writel_relaxed(CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR);
/* We do at least know that a DTC's XP must be in that DTC's domain */ xp = arm_cmn_node_to_xp(dn); @@ -1303,7 +1304,7 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn) dn->type = CMN_TYPE_RNI; }
- writel_relaxed(CMN_DT_DTC_CTL_DT_EN, cmn->dtc[0].base + CMN_DT_DTC_CTL); + arm_cmn_set_state(cmn, CMN_STATE_DISABLED);
return 0; }
From: Zhang Rui rui.zhang@intel.com
[ Upstream commit 4658fe81b3f8afe8adf37734ec5fe595d90415c6 ]
After commit 3382388d7148 ("intel_rapl: abstract RAPL common code"), accessing to IOSF_MBI interface is done in the RAPL common code.
Thus it is the CONFIG_INTEL_RAPL_CORE that has dependency of CONFIG_IOSF_MBI, while CONFIG_INTEL_RAPL_MSR does not.
This problem was not exposed previously because all the previous RAPL common code users, aka, the RAPL MSR and MMIO I/F drivers, have CONFIG_IOSF_MBI selected.
Fix the CONFIG_IOSF_MBI dependency in RAPL code. This also fixes a build time failure when the RAPL TPMI I/F driver is introduced without selecting CONFIG_IOSF_MBI.
x86_64-linux-ld: vmlinux.o: in function `set_floor_freq_atom': intel_rapl_common.c:(.text+0x2dac9b8): undefined reference to `iosf_mbi_write' x86_64-linux-ld: intel_rapl_common.c:(.text+0x2daca66): undefined reference to `iosf_mbi_read'
Reference to iosf_mbi.h is also removed from the RAPL MSR I/F driver.
Fixes: 3382388d7148 ("intel_rapl: abstract RAPL common code") Reported-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/all/20230601213246.3271412-1-arnd@kernel.org Signed-off-by: Zhang Rui rui.zhang@intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/powercap/Kconfig | 4 +++- drivers/powercap/intel_rapl_msr.c | 1 - 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/powercap/Kconfig b/drivers/powercap/Kconfig index 8242e8c5ed77e..503797b2a1c69 100644 --- a/drivers/powercap/Kconfig +++ b/drivers/powercap/Kconfig @@ -18,10 +18,12 @@ if POWERCAP # Client driver configurations go here. config INTEL_RAPL_CORE tristate + depends on PCI + select IOSF_MBI
config INTEL_RAPL tristate "Intel RAPL Support via MSR Interface" - depends on X86 && IOSF_MBI + depends on X86 && PCI select INTEL_RAPL_CORE help This enables support for the Intel Running Average Power Limit (RAPL) diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c index 1be45f36ab6cd..c19e69e77093b 100644 --- a/drivers/powercap/intel_rapl_msr.c +++ b/drivers/powercap/intel_rapl_msr.c @@ -22,7 +22,6 @@ #include <linux/processor.h> #include <linux/platform_device.h>
-#include <asm/iosf_mbi.h> #include <asm/cpu_device_id.h> #include <asm/intel-family.h>
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 1b9c3ddcec6a55e15d3e38e7405e2d078db02020 ]
checker_stack_use_t32strd() and kprobe_handler() can be made static since they are not used from other files, while coverage_start_registers() and __kprobes_test_case() are used from assembler code, and just need a declaration to avoid a warning with the global definition.
arch/arm/probes/kprobes/checkers-common.c:43:18: error: no previous prototype for 'checker_stack_use_t32strd' arch/arm/probes/kprobes/core.c:236:16: error: no previous prototype for 'kprobe_handler' arch/arm/probes/kprobes/test-core.c:723:10: error: no previous prototype for 'coverage_start_registers' arch/arm/probes/kprobes/test-core.c:918:14: error: no previous prototype for '__kprobes_test_case_start' arch/arm/probes/kprobes/test-core.c:952:14: error: no previous prototype for '__kprobes_test_case_end_16' arch/arm/probes/kprobes/test-core.c:967:14: error: no previous prototype for '__kprobes_test_case_end_32'
Fixes: 6624cf651f1a ("ARM: kprobes: collects stack consumption for store instructions") Fixes: 454f3e132d05 ("ARM/kprobes: Remove jprobe arm implementation") Acked-by: Masami Hiramatsu (Google) mhiramat@kernel.org Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/probes/kprobes/checkers-common.c | 2 +- arch/arm/probes/kprobes/core.c | 2 +- arch/arm/probes/kprobes/opt-arm.c | 2 -- arch/arm/probes/kprobes/test-core.c | 2 +- arch/arm/probes/kprobes/test-core.h | 4 ++++ 5 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/arm/probes/kprobes/checkers-common.c b/arch/arm/probes/kprobes/checkers-common.c index 4d720990cf2a3..eba7ac4725c02 100644 --- a/arch/arm/probes/kprobes/checkers-common.c +++ b/arch/arm/probes/kprobes/checkers-common.c @@ -40,7 +40,7 @@ enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn, * Different from other insn uses imm8, the real addressing offset of * STRD in T32 encoding should be imm8 * 4. See ARMARM description. */ -enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn, +static enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn, struct arch_probes_insn *asi, const struct decode_header *h) { diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c index 9bcae72dda440..3bd017f6e256a 100644 --- a/arch/arm/probes/kprobes/core.c +++ b/arch/arm/probes/kprobes/core.c @@ -233,7 +233,7 @@ singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) * kprobe, and that level is reserved for user kprobe handlers, so we can't * risk encountering a new kprobe in an interrupt handler. */ -void __kprobes kprobe_handler(struct pt_regs *regs) +static void __kprobes kprobe_handler(struct pt_regs *regs) { struct kprobe *p, *cur; struct kprobe_ctlblk *kcb; diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c index c78180172120f..e20304f1d8bc9 100644 --- a/arch/arm/probes/kprobes/opt-arm.c +++ b/arch/arm/probes/kprobes/opt-arm.c @@ -145,8 +145,6 @@ __arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty) } }
-extern void kprobe_handler(struct pt_regs *regs); - static void optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) { diff --git a/arch/arm/probes/kprobes/test-core.c b/arch/arm/probes/kprobes/test-core.c index c562832b86272..171c7076b89f4 100644 --- a/arch/arm/probes/kprobes/test-core.c +++ b/arch/arm/probes/kprobes/test-core.c @@ -720,7 +720,7 @@ static const char coverage_register_lookup[16] = { [REG_TYPE_NOSPPCX] = COVERAGE_ANY_REG | COVERAGE_SP, };
-unsigned coverage_start_registers(const struct decode_header *h) +static unsigned coverage_start_registers(const struct decode_header *h) { unsigned regs = 0; int i; diff --git a/arch/arm/probes/kprobes/test-core.h b/arch/arm/probes/kprobes/test-core.h index f1d5583e7bbbb..7054d9fae2ea0 100644 --- a/arch/arm/probes/kprobes/test-core.h +++ b/arch/arm/probes/kprobes/test-core.h @@ -454,3 +454,7 @@ void kprobe_thumb32_test_cases(void); #else void kprobe_arm_test_cases(void); #endif + +void __kprobes_test_case_start(void); +void __kprobes_test_case_end_16(void); +void __kprobes_test_case_end_32(void);
From: Tero Kristo tero.kristo@linux.intel.com
[ Upstream commit 03f44ffb3d5be2fceda375d92c70ab6de4df7081 ]
If the intel_pstate driver is set to passive mode, then writing the same value to the energy_performance_preference sysfs twice will fail. This is caused by the wrong return value used (index of the matched energy_perf_string), instead of the length of the passed in parameter. Fix by forcing the internal return value to zero when the same preference is passed in by user. This same issue is not present when active mode is used for the driver.
Fixes: f6ebbcf08f37 ("cpufreq: intel_pstate: Implement passive mode with HWP enabled") Reported-by: Niklas Neronin niklas.neronin@intel.com Signed-off-by: Tero Kristo tero.kristo@linux.intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/intel_pstate.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index eee74a2fe3174..2f5063db2f1fc 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -824,6 +824,8 @@ static ssize_t store_energy_performance_preference( err = cpufreq_start_governor(policy); if (!ret) ret = err; + } else { + ret = 0; } }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 89382022b370dfd34eaae9c863baa123fcd4d132 ]
Should an error occur after calling sun8i_ths_resource_init() in the probe function, some resources need to be released, as already done in the .remove() function.
Switch to the devm_clk_get_enabled() helper and add a new devm_action to turn sun8i_ths_resource_init() into a fully managed function.
Move the place where reset_control_deassert() is called so that the recommended order of reset release/clock enable steps is kept. A64 manual states that:
3.3.6.4. Gating and reset
Make sure that the reset signal has been released before the release of module clock gating;
This fixes the issue and removes some LoC at the same time.
Fixes: dccc5c3b6f30 ("thermal/drivers/sun8i: Add thermal driver for H6/H5/H3/A64/A83T/R40") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Acked-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/a8ae84bd2dc4b55fe428f8e20f31438bf8bb6762.168408993... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/sun8i_thermal.c | 55 +++++++++++---------------------- 1 file changed, 18 insertions(+), 37 deletions(-)
diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c index d9cd23cbb6717..cd464db064142 100644 --- a/drivers/thermal/sun8i_thermal.c +++ b/drivers/thermal/sun8i_thermal.c @@ -319,6 +319,11 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev) return ret; }
+static void sun8i_ths_reset_control_assert(void *data) +{ + reset_control_assert(data); +} + static int sun8i_ths_resource_init(struct ths_device *tmdev) { struct device *dev = tmdev->dev; @@ -339,47 +344,35 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev) if (IS_ERR(tmdev->reset)) return PTR_ERR(tmdev->reset);
- tmdev->bus_clk = devm_clk_get(&pdev->dev, "bus"); + ret = reset_control_deassert(tmdev->reset); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, sun8i_ths_reset_control_assert, + tmdev->reset); + if (ret) + return ret; + + tmdev->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus"); if (IS_ERR(tmdev->bus_clk)) return PTR_ERR(tmdev->bus_clk); }
if (tmdev->chip->has_mod_clk) { - tmdev->mod_clk = devm_clk_get(&pdev->dev, "mod"); + tmdev->mod_clk = devm_clk_get_enabled(&pdev->dev, "mod"); if (IS_ERR(tmdev->mod_clk)) return PTR_ERR(tmdev->mod_clk); }
- ret = reset_control_deassert(tmdev->reset); - if (ret) - return ret; - - ret = clk_prepare_enable(tmdev->bus_clk); - if (ret) - goto assert_reset; - ret = clk_set_rate(tmdev->mod_clk, 24000000); if (ret) - goto bus_disable; - - ret = clk_prepare_enable(tmdev->mod_clk); - if (ret) - goto bus_disable; + return ret;
ret = sun8i_ths_calibrate(tmdev); if (ret) - goto mod_disable; + return ret;
return 0; - -mod_disable: - clk_disable_unprepare(tmdev->mod_clk); -bus_disable: - clk_disable_unprepare(tmdev->bus_clk); -assert_reset: - reset_control_assert(tmdev->reset); - - return ret; }
static int sun8i_h3_thermal_init(struct ths_device *tmdev) @@ -530,17 +523,6 @@ static int sun8i_ths_probe(struct platform_device *pdev) return 0; }
-static int sun8i_ths_remove(struct platform_device *pdev) -{ - struct ths_device *tmdev = platform_get_drvdata(pdev); - - clk_disable_unprepare(tmdev->mod_clk); - clk_disable_unprepare(tmdev->bus_clk); - reset_control_assert(tmdev->reset); - - return 0; -} - static const struct ths_thermal_chip sun8i_a83t_ths = { .sensor_num = 3, .scale = 705, @@ -642,7 +624,6 @@ MODULE_DEVICE_TABLE(of, of_ths_match);
static struct platform_driver ths_driver = { .probe = sun8i_ths_probe, - .remove = sun8i_ths_remove, .driver = { .name = "sun8i-thermal", .of_match_table = of_ths_match,
From: Paul E. McKenney paulmck@kernel.org
[ Upstream commit b409afe0268faeb77267f028ea85f2d93438fced ]
The BUSTED-BOOST and TREE03 scenarios specify a mythical tree.use_softirq module parameter, which means a failure to get full test coverage. This commit therefore corrects the name to rcutree.use_softirq.
Fixes: e2b949d54392 ("rcutorture: Make TREE03 use real-time tree.use_softirq setting") Signed-off-by: Paul E. McKenney paulmck@kernel.org Reviewed-by: Joel Fernandes (Google) joel@joelfernandes.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot | 2 +- tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot b/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot index f57720c52c0f9..84f6bb98ce993 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot +++ b/tools/testing/selftests/rcutorture/configs/rcu/BUSTED-BOOST.boot @@ -5,4 +5,4 @@ rcutree.gp_init_delay=3 rcutree.gp_cleanup_delay=3 rcutree.kthread_prio=2 threadirqs -tree.use_softirq=0 +rcutree.use_softirq=0 diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot index 64f864f1f361f..8e50bfd4b710d 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot @@ -4,4 +4,4 @@ rcutree.gp_init_delay=3 rcutree.gp_cleanup_delay=3 rcutree.kthread_prio=2 threadirqs -tree.use_softirq=0 +rcutree.use_softirq=0
From: Li Zhijian zhijianx.li@intel.com
[ Upstream commit 86e7ed1bd57d020e35d430542bf5d689c3200568 ]
Unconditionally log messages corresponding to errors.
Acked-by: Davidlohr Bueso dbueso@suse.de Signed-off-by: Li Zhijian zhijianx.li@intel.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Stable-dep-of: 23fc8df26dea ("rcu/rcuscale: Stop kfree_scale_thread thread(s) after unloading rcuscale") Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcuscale.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c index 2cc34a22a5060..5c8449a8827a1 100644 --- a/kernel/rcu/rcuscale.c +++ b/kernel/rcu/rcuscale.c @@ -50,8 +50,8 @@ MODULE_AUTHOR("Paul E. McKenney paulmck@linux.ibm.com"); pr_alert("%s" SCALE_FLAG " %s\n", scale_type, s) #define VERBOSE_SCALEOUT_STRING(s) \ do { if (verbose) pr_alert("%s" SCALE_FLAG " %s\n", scale_type, s); } while (0) -#define VERBOSE_SCALEOUT_ERRSTRING(s) \ - do { if (verbose) pr_alert("%s" SCALE_FLAG "!!! %s\n", scale_type, s); } while (0) +#define SCALEOUT_ERRSTRING(s) \ + pr_alert("%s" SCALE_FLAG "!!! %s\n", scale_type, s)
/* * The intended use cases for the nreaders and nwriters module parameters @@ -514,11 +514,11 @@ rcu_scale_cleanup(void) * during the mid-boot phase, so have to wait till the end. */ if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp) - VERBOSE_SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!"); + SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!"); if (rcu_gp_is_normal() && gp_exp) - VERBOSE_SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!"); + SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!"); if (gp_exp && gp_async) - VERBOSE_SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!"); + SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
if (torture_cleanup_begin()) return; @@ -845,7 +845,7 @@ rcu_scale_init(void) reader_tasks = kcalloc(nrealreaders, sizeof(reader_tasks[0]), GFP_KERNEL); if (reader_tasks == NULL) { - VERBOSE_SCALEOUT_ERRSTRING("out of memory"); + SCALEOUT_ERRSTRING("out of memory"); firsterr = -ENOMEM; goto unwind; } @@ -865,7 +865,7 @@ rcu_scale_init(void) kcalloc(nrealwriters, sizeof(*writer_n_durations), GFP_KERNEL); if (!writer_tasks || !writer_durations || !writer_n_durations) { - VERBOSE_SCALEOUT_ERRSTRING("out of memory"); + SCALEOUT_ERRSTRING("out of memory"); firsterr = -ENOMEM; goto unwind; }
From: Paul E. McKenney paulmck@kernel.org
[ Upstream commit ef1ef3d47677dc191b88650a9f7f91413452cc1b ]
The rcu_scale_shutdown() and kfree_scale_shutdown() kthreads/functions use wait_event() to wait for the rcuscale test to complete. However, each updater thread in such a test waits for at least 100 grace periods. If each grace period takes more than 1.2 seconds, which is long, but not insanely so, this can trigger the hung-task timeout.
This commit therefore replaces those wait_event() calls with calls to wait_event_idle(), which do not trigger the hung-task timeout.
Reported-by: kernel test robot yujie.liu@intel.com Reported-by: Liam Howlett liam.howlett@oracle.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Tested-by: Yujie Liu yujie.liu@intel.com Signed-off-by: Boqun Feng boqun.feng@gmail.com Stable-dep-of: 23fc8df26dea ("rcu/rcuscale: Stop kfree_scale_thread thread(s) after unloading rcuscale") Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcuscale.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c index 5c8449a8827a1..a3e86c4843d37 100644 --- a/kernel/rcu/rcuscale.c +++ b/kernel/rcu/rcuscale.c @@ -609,8 +609,7 @@ static int compute_real(int n) static int rcu_scale_shutdown(void *arg) { - wait_event(shutdown_wq, - atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters); + wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters); smp_mb(); /* Wake before output. */ rcu_scale_cleanup(); kernel_power_off(); @@ -736,8 +735,8 @@ kfree_scale_cleanup(void) static int kfree_scale_shutdown(void *arg) { - wait_event(shutdown_wq, - atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads); + wait_event_idle(shutdown_wq, + atomic_read(&n_kfree_scale_thread_ended) >= kfree_nrealthreads);
smp_mb(); /* Wake before output. */
From: Qiuxu Zhuo qiuxu.zhuo@intel.com
[ Upstream commit bf5ddd736509a7d9077c0b6793e6f0852214dbea ]
This code-movement-only commit moves the rcu_scale_cleanup() and rcu_scale_shutdown() functions to follow kfree_scale_cleanup(). This is code movement is in preparation for a bug-fix patch that invokes kfree_scale_cleanup() from rcu_scale_cleanup().
Signed-off-by: Qiuxu Zhuo qiuxu.zhuo@intel.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Reviewed-by: Joel Fernandes (Google) joel@joelfernandes.org Stable-dep-of: 23fc8df26dea ("rcu/rcuscale: Stop kfree_scale_thread thread(s) after unloading rcuscale") Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcuscale.c | 194 +++++++++++++++++++++--------------------- 1 file changed, 97 insertions(+), 97 deletions(-)
diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c index a3e86c4843d37..3509aabac942e 100644 --- a/kernel/rcu/rcuscale.c +++ b/kernel/rcu/rcuscale.c @@ -500,89 +500,6 @@ rcu_scale_print_module_parms(struct rcu_scale_ops *cur_ops, const char *tag) scale_type, tag, nrealreaders, nrealwriters, verbose, shutdown); }
-static void -rcu_scale_cleanup(void) -{ - int i; - int j; - int ngps = 0; - u64 *wdp; - u64 *wdpp; - - /* - * Would like warning at start, but everything is expedited - * during the mid-boot phase, so have to wait till the end. - */ - if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp) - SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!"); - if (rcu_gp_is_normal() && gp_exp) - SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!"); - if (gp_exp && gp_async) - SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!"); - - if (torture_cleanup_begin()) - return; - if (!cur_ops) { - torture_cleanup_end(); - return; - } - - if (reader_tasks) { - for (i = 0; i < nrealreaders; i++) - torture_stop_kthread(rcu_scale_reader, - reader_tasks[i]); - kfree(reader_tasks); - } - - if (writer_tasks) { - for (i = 0; i < nrealwriters; i++) { - torture_stop_kthread(rcu_scale_writer, - writer_tasks[i]); - if (!writer_n_durations) - continue; - j = writer_n_durations[i]; - pr_alert("%s%s writer %d gps: %d\n", - scale_type, SCALE_FLAG, i, j); - ngps += j; - } - pr_alert("%s%s start: %llu end: %llu duration: %llu gps: %d batches: %ld\n", - scale_type, SCALE_FLAG, - t_rcu_scale_writer_started, t_rcu_scale_writer_finished, - t_rcu_scale_writer_finished - - t_rcu_scale_writer_started, - ngps, - rcuscale_seq_diff(b_rcu_gp_test_finished, - b_rcu_gp_test_started)); - for (i = 0; i < nrealwriters; i++) { - if (!writer_durations) - break; - if (!writer_n_durations) - continue; - wdpp = writer_durations[i]; - if (!wdpp) - continue; - for (j = 0; j < writer_n_durations[i]; j++) { - wdp = &wdpp[j]; - pr_alert("%s%s %4d writer-duration: %5d %llu\n", - scale_type, SCALE_FLAG, - i, j, *wdp); - if (j % 100 == 0) - schedule_timeout_uninterruptible(1); - } - kfree(writer_durations[i]); - } - kfree(writer_tasks); - kfree(writer_durations); - kfree(writer_n_durations); - } - - /* Do torture-type-specific cleanup operations. */ - if (cur_ops->cleanup != NULL) - cur_ops->cleanup(); - - torture_cleanup_end(); -} - /* * Return the number if non-negative. If -1, the number of CPUs. * If less than -1, that much less than the number of CPUs, but @@ -602,20 +519,6 @@ static int compute_real(int n) return nr; }
-/* - * RCU scalability shutdown kthread. Just waits to be awakened, then shuts - * down system. - */ -static int -rcu_scale_shutdown(void *arg) -{ - wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters); - smp_mb(); /* Wake before output. */ - rcu_scale_cleanup(); - kernel_power_off(); - return -EINVAL; -} - /* * kfree_rcu() scalability tests: Start a kfree_rcu() loop on all CPUs for number * of iterations and measure total time and number of GP for all iterations to complete. @@ -790,6 +693,103 @@ kfree_scale_init(void) return firsterr; }
+static void +rcu_scale_cleanup(void) +{ + int i; + int j; + int ngps = 0; + u64 *wdp; + u64 *wdpp; + + /* + * Would like warning at start, but everything is expedited + * during the mid-boot phase, so have to wait till the end. + */ + if (rcu_gp_is_expedited() && !rcu_gp_is_normal() && !gp_exp) + SCALEOUT_ERRSTRING("All grace periods expedited, no normal ones to measure!"); + if (rcu_gp_is_normal() && gp_exp) + SCALEOUT_ERRSTRING("All grace periods normal, no expedited ones to measure!"); + if (gp_exp && gp_async) + SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!"); + + if (torture_cleanup_begin()) + return; + if (!cur_ops) { + torture_cleanup_end(); + return; + } + + if (reader_tasks) { + for (i = 0; i < nrealreaders; i++) + torture_stop_kthread(rcu_scale_reader, + reader_tasks[i]); + kfree(reader_tasks); + } + + if (writer_tasks) { + for (i = 0; i < nrealwriters; i++) { + torture_stop_kthread(rcu_scale_writer, + writer_tasks[i]); + if (!writer_n_durations) + continue; + j = writer_n_durations[i]; + pr_alert("%s%s writer %d gps: %d\n", + scale_type, SCALE_FLAG, i, j); + ngps += j; + } + pr_alert("%s%s start: %llu end: %llu duration: %llu gps: %d batches: %ld\n", + scale_type, SCALE_FLAG, + t_rcu_scale_writer_started, t_rcu_scale_writer_finished, + t_rcu_scale_writer_finished - + t_rcu_scale_writer_started, + ngps, + rcuscale_seq_diff(b_rcu_gp_test_finished, + b_rcu_gp_test_started)); + for (i = 0; i < nrealwriters; i++) { + if (!writer_durations) + break; + if (!writer_n_durations) + continue; + wdpp = writer_durations[i]; + if (!wdpp) + continue; + for (j = 0; j < writer_n_durations[i]; j++) { + wdp = &wdpp[j]; + pr_alert("%s%s %4d writer-duration: %5d %llu\n", + scale_type, SCALE_FLAG, + i, j, *wdp); + if (j % 100 == 0) + schedule_timeout_uninterruptible(1); + } + kfree(writer_durations[i]); + } + kfree(writer_tasks); + kfree(writer_durations); + kfree(writer_n_durations); + } + + /* Do torture-type-specific cleanup operations. */ + if (cur_ops->cleanup != NULL) + cur_ops->cleanup(); + + torture_cleanup_end(); +} + +/* + * RCU scalability shutdown kthread. Just waits to be awakened, then shuts + * down system. + */ +static int +rcu_scale_shutdown(void *arg) +{ + wait_event_idle(shutdown_wq, atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters); + smp_mb(); /* Wake before output. */ + rcu_scale_cleanup(); + kernel_power_off(); + return -EINVAL; +} + static int __init rcu_scale_init(void) {
From: Qiuxu Zhuo qiuxu.zhuo@intel.com
[ Upstream commit 23fc8df26dead16687ae6eb47b0561a4a832e2f6 ]
Running the 'kfree_rcu_test' test case [1] results in a splat [2]. The root cause is the kfree_scale_thread thread(s) continue running after unloading the rcuscale module. This commit fixes that isue by invoking kfree_scale_cleanup() from rcu_scale_cleanup() when removing the rcuscale module.
[1] modprobe rcuscale kfree_rcu_test=1 // After some time rmmod rcuscale rmmod torture
[2] BUG: unable to handle page fault for address: ffffffffc0601a87 #PF: supervisor instruction fetch in kernel mode #PF: error_code(0x0010) - not-present page PGD 11de4f067 P4D 11de4f067 PUD 11de51067 PMD 112f4d067 PTE 0 Oops: 0010 [#1] PREEMPT SMP NOPTI CPU: 1 PID: 1798 Comm: kfree_scale_thr Not tainted 6.3.0-rc1-rcu+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015 RIP: 0010:0xffffffffc0601a87 Code: Unable to access opcode bytes at 0xffffffffc0601a5d. RSP: 0018:ffffb25bc2e57e18 EFLAGS: 00010297 RAX: 0000000000000000 RBX: ffffffffc061f0b6 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff962fd0de RDI: ffffffff962fd0de RBP: ffffb25bc2e57ea8 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000000 R13: 0000000000000000 R14: 000000000000000a R15: 00000000001c1dbe FS: 0000000000000000(0000) GS:ffff921fa2200000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffc0601a5d CR3: 000000011de4c006 CR4: 0000000000370ee0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? kvfree_call_rcu+0xf0/0x3a0 ? kthread+0xf3/0x120 ? kthread_complete_and_exit+0x20/0x20 ? ret_from_fork+0x1f/0x30 </TASK> Modules linked in: rfkill sunrpc ... [last unloaded: torture] CR2: ffffffffc0601a87 ---[ end trace 0000000000000000 ]---
Fixes: e6e78b004fa7 ("rcuperf: Add kfree_rcu() performance Tests") Reviewed-by: Davidlohr Bueso dave@stgolabs.net Reviewed-by: Joel Fernandes (Google) joel@joelfernandes.org Signed-off-by: Qiuxu Zhuo qiuxu.zhuo@intel.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcuscale.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c index 3509aabac942e..57ec414710bbc 100644 --- a/kernel/rcu/rcuscale.c +++ b/kernel/rcu/rcuscale.c @@ -713,6 +713,11 @@ rcu_scale_cleanup(void) if (gp_exp && gp_async) SCALEOUT_ERRSTRING("No expedited async GPs, so went with async!");
+ if (kfree_rcu_test) { + kfree_scale_cleanup(); + return; + } + if (torture_cleanup_begin()) return; if (!cur_ops) {
From: Colin Ian King colin.i.king@gmail.com
[ Upstream commit 375b9ff53cb6f9c042817b75f2be0a650626dc4f ]
In the unlikely case that CLOCK_REALTIME is not defined, variable ret is not initialized and further accumulation of return values to ret can leave ret in an undefined state. Fix this by initialized ret to zero and changing the assignment of ret to an accumulation for the CLOCK_REALTIME case.
Fixes: 03f55c7952c9 ("kselftest: Extend vDSO selftest to clock_getres") Signed-off-by: Colin Ian King colin.i.king@gmail.com Reviewed-by: Vincenzo Frascino vincenzo.frascino@arm.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/vDSO/vdso_test_clock_getres.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/vDSO/vdso_test_clock_getres.c b/tools/testing/selftests/vDSO/vdso_test_clock_getres.c index 15dcee16ff726..38d46a8bf7cba 100644 --- a/tools/testing/selftests/vDSO/vdso_test_clock_getres.c +++ b/tools/testing/selftests/vDSO/vdso_test_clock_getres.c @@ -84,12 +84,12 @@ static inline int vdso_test_clock(unsigned int clock_id)
int main(int argc, char **argv) { - int ret; + int ret = 0;
#if _POSIX_TIMERS > 0
#ifdef CLOCK_REALTIME - ret = vdso_test_clock(CLOCK_REALTIME); + ret += vdso_test_clock(CLOCK_REALTIME); #endif
#ifdef CLOCK_BOOTTIME
From: Ravi Bangoria ravi.bangoria@amd.com
[ Upstream commit 2fad201fe38ff9a692acedb1990ece2c52a29f95 ]
Although, IBS pmus can be invoked via their own interface, indirect IBS invocation via core pmu events is also supported with fixed set of events: cpu-cycles:p, r076:p (same as cpu-cycles:p) and r0C1:p (micro-ops) for user convenience.
This indirect IBS invocation is broken since commit 66d258c5b048 ("perf/core: Optimize perf_init_event()"), which added RAW pmu under 'pmu_idr' list and thus if event_init() fails with RAW pmu, it started returning error instead of trying other pmus.
Forward precise events from core pmu to IBS by overwriting 'type' and 'config' in the kernel copy of perf_event_attr. Overwriting will cause perf_init_event() to retry with updated 'type' and 'config', which will automatically forward event to IBS pmu.
Without patch: $ sudo ./perf record -C 0 -e r076:p -- sleep 1 Error: The r076:p event is not supported.
With patch: $ sudo ./perf record -C 0 -e r076:p -- sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.341 MB perf.data (37 samples) ]
Fixes: 66d258c5b048 ("perf/core: Optimize perf_init_event()") Reported-by: Stephane Eranian eranian@google.com Signed-off-by: Ravi Bangoria ravi.bangoria@amd.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20230504110003.2548-3-ravi.bangoria@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/amd/core.c | 2 +- arch/x86/events/amd/ibs.c | 53 +++++++++++++++---------------- arch/x86/include/asm/perf_event.h | 2 ++ 3 files changed, 29 insertions(+), 28 deletions(-)
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index d93d098dea99d..4ebedc7e1188b 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -364,7 +364,7 @@ static int amd_pmu_hw_config(struct perf_event *event)
/* pass precise event sampling to ibs: */ if (event->attr.precise_ip && get_ibs_caps()) - return -ENOENT; + return forward_event_to_ibs(event);
if (has_branch_stack(event)) return -EOPNOTSUPP; diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index 2704ec1e42a30..b605e08f9a8ef 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -194,7 +194,7 @@ static struct perf_ibs *get_ibs_pmu(int type) }
/* - * Use IBS for precise event sampling: + * core pmu config -> IBS config * * perf record -a -e cpu-cycles:p ... # use ibs op counting cycle count * perf record -a -e r076:p ... # same as -e cpu-cycles:p @@ -203,25 +203,9 @@ static struct perf_ibs *get_ibs_pmu(int type) * IbsOpCntCtl (bit 19) of IBS Execution Control Register (IbsOpCtl, * MSRC001_1033) is used to select either cycle or micro-ops counting * mode. - * - * The rip of IBS samples has skid 0. Thus, IBS supports precise - * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the - * rip is invalid when IBS was not able to record the rip correctly. - * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then. - * */ -static int perf_ibs_precise_event(struct perf_event *event, u64 *config) +static int core_pmu_ibs_config(struct perf_event *event, u64 *config) { - switch (event->attr.precise_ip) { - case 0: - return -ENOENT; - case 1: - case 2: - break; - default: - return -EOPNOTSUPP; - } - switch (event->attr.type) { case PERF_TYPE_HARDWARE: switch (event->attr.config) { @@ -247,22 +231,37 @@ static int perf_ibs_precise_event(struct perf_event *event, u64 *config) return -EOPNOTSUPP; }
+/* + * The rip of IBS samples has skid 0. Thus, IBS supports precise + * levels 1 and 2 and the PERF_EFLAGS_EXACT is set. In rare cases the + * rip is invalid when IBS was not able to record the rip correctly. + * We clear PERF_EFLAGS_EXACT and take the rip from pt_regs then. + */ +int forward_event_to_ibs(struct perf_event *event) +{ + u64 config = 0; + + if (!event->attr.precise_ip || event->attr.precise_ip > 2) + return -EOPNOTSUPP; + + if (!core_pmu_ibs_config(event, &config)) { + event->attr.type = perf_ibs_op.pmu.type; + event->attr.config = config; + } + return -ENOENT; +} + static int perf_ibs_init(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; struct perf_ibs *perf_ibs; u64 max_cnt, config; - int ret;
perf_ibs = get_ibs_pmu(event->attr.type); - if (perf_ibs) { - config = event->attr.config; - } else { - perf_ibs = &perf_ibs_op; - ret = perf_ibs_precise_event(event, &config); - if (ret) - return ret; - } + if (!perf_ibs) + return -ENOENT; + + config = event->attr.config;
if (event->pmu != &perf_ibs->pmu) return -ENOENT; diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index a2b6626c681f5..0e4efcde07831 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -427,8 +427,10 @@ struct pebs_xmm {
#ifdef CONFIG_X86_LOCAL_APIC extern u32 get_ibs_caps(void); +extern int forward_event_to_ibs(struct perf_event *event); #else static inline u32 get_ibs_caps(void) { return 0; } +static inline int forward_event_to_ibs(struct perf_event *event) { return -ENOENT; } #endif
#ifdef CONFIG_PERF_EVENTS
From: Juergen Gross jgross@suse.com
[ Upstream commit 0f88130e8a6fd185b0aeb5d8e286083735f2585a ]
Normally __swp_entry_to_pte() is never called with a value translating to a valid PTE. The only known exception is pte_swap_tests(), resulting in a WARN splat in Xen PV guests, as __pte_to_swp_entry() did translate the PFN of the valid PTE to a guest local PFN, while __swp_entry_to_pte() doesn't do the opposite translation.
Fix that by using __pte() in __swp_entry_to_pte() instead of open coding the native variant of it.
For correctness do the similar conversion for __swp_entry_to_pmd().
Fixes: 05289402d717 ("mm/debug_vm_pgtable: add tests validating arch helpers for core MM features") Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Link: https://lore.kernel.org/r/20230306123259.12461-1-jgross@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/pgtable_64.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 56d0399a0cd16..dd520b44e89cc 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -235,8 +235,8 @@ static inline void native_pgd_clear(pgd_t *pgd)
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) }) #define __pmd_to_swp_entry(pmd) ((swp_entry_t) { pmd_val((pmd)) }) -#define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val }) -#define __swp_entry_to_pmd(x) ((pmd_t) { .pmd = (x).val }) +#define __swp_entry_to_pte(x) (__pte((x).val)) +#define __swp_entry_to_pmd(x) (__pmd((x).val))
extern int kern_addr_valid(unsigned long addr); extern void cleanup_highmap(void);
From: Mark Rutland mark.rutland@arm.com
[ Upstream commit dda5f312bb09e56e7a1c3e3851f2000eb2e9c879 ]
The sync_*() ops on arch/arm are defined in terms of the regular bitops with no special handling. This is not correct, as UP kernels elide barriers for the fully-ordered operations, and so the required ordering is lost when such UP kernels are run under a hypervsior on an SMP system.
Fix this by defining sync ops with the required barriers.
Note: On 32-bit arm, the sync_*() ops are currently only used by Xen, which requires ARMv7, but the semantics can be implemented for ARMv6+.
Fixes: e54d2f61528165bb ("xen/arm: sync_bitops") Signed-off-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20230605070124.3741859-2-mark.rutland@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/include/asm/assembler.h | 17 +++++++++++++++++ arch/arm/include/asm/sync_bitops.h | 29 +++++++++++++++++++++++++---- arch/arm/lib/bitops.h | 14 +++++++++++--- arch/arm/lib/testchangebit.S | 4 ++++ arch/arm/lib/testclearbit.S | 4 ++++ arch/arm/lib/testsetbit.S | 4 ++++ 6 files changed, 65 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 09c241280ed9c..5d52da168ab3a 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -326,6 +326,23 @@ #endif .endm
+/* + * Raw SMP data memory barrier + */ + .macro __smp_dmb mode +#if __LINUX_ARM_ARCH__ >= 7 + .ifeqs "\mode","arm" + dmb ish + .else + W(dmb) ish + .endif +#elif __LINUX_ARM_ARCH__ == 6 + mcr p15, 0, r0, c7, c10, 5 @ dmb +#else + .error "Incompatible SMP platform" +#endif + .endm + #if defined(CONFIG_CPU_V7M) /* * setmode is used to assert to be in svc mode during boot. For v7-M diff --git a/arch/arm/include/asm/sync_bitops.h b/arch/arm/include/asm/sync_bitops.h index 6f5d627c44a3c..f46b3c570f92e 100644 --- a/arch/arm/include/asm/sync_bitops.h +++ b/arch/arm/include/asm/sync_bitops.h @@ -14,14 +14,35 @@ * ops which are SMP safe even on a UP kernel. */
+/* + * Unordered + */ + #define sync_set_bit(nr, p) _set_bit(nr, p) #define sync_clear_bit(nr, p) _clear_bit(nr, p) #define sync_change_bit(nr, p) _change_bit(nr, p) -#define sync_test_and_set_bit(nr, p) _test_and_set_bit(nr, p) -#define sync_test_and_clear_bit(nr, p) _test_and_clear_bit(nr, p) -#define sync_test_and_change_bit(nr, p) _test_and_change_bit(nr, p) #define sync_test_bit(nr, addr) test_bit(nr, addr) -#define arch_sync_cmpxchg arch_cmpxchg
+/* + * Fully ordered + */ + +int _sync_test_and_set_bit(int nr, volatile unsigned long * p); +#define sync_test_and_set_bit(nr, p) _sync_test_and_set_bit(nr, p) + +int _sync_test_and_clear_bit(int nr, volatile unsigned long * p); +#define sync_test_and_clear_bit(nr, p) _sync_test_and_clear_bit(nr, p) + +int _sync_test_and_change_bit(int nr, volatile unsigned long * p); +#define sync_test_and_change_bit(nr, p) _sync_test_and_change_bit(nr, p) + +#define arch_sync_cmpxchg(ptr, old, new) \ +({ \ + __typeof__(*(ptr)) __ret; \ + __smp_mb__before_atomic(); \ + __ret = arch_cmpxchg_relaxed((ptr), (old), (new)); \ + __smp_mb__after_atomic(); \ + __ret; \ +})
#endif diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h index 95bd359912889..f069d1b2318e6 100644 --- a/arch/arm/lib/bitops.h +++ b/arch/arm/lib/bitops.h @@ -28,7 +28,7 @@ UNWIND( .fnend ) ENDPROC(\name ) .endm
- .macro testop, name, instr, store + .macro __testop, name, instr, store, barrier ENTRY( \name ) UNWIND( .fnstart ) ands ip, r1, #3 @@ -38,7 +38,7 @@ UNWIND( .fnstart ) mov r0, r0, lsr #5 add r1, r1, r0, lsl #2 @ Get word offset mov r3, r2, lsl r3 @ create mask - smp_dmb + \barrier #if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP) .arch_extension mp ALT_SMP(W(pldw) [r1]) @@ -50,13 +50,21 @@ UNWIND( .fnstart ) strex ip, r2, [r1] cmp ip, #0 bne 1b - smp_dmb + \barrier cmp r0, #0 movne r0, #1 2: bx lr UNWIND( .fnend ) ENDPROC(\name ) .endm + + .macro testop, name, instr, store + __testop \name, \instr, \store, smp_dmb + .endm + + .macro sync_testop, name, instr, store + __testop \name, \instr, \store, __smp_dmb + .endm #else .macro bitop, name, instr ENTRY( \name ) diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S index 4ebecc67e6e04..f13fe9bc2399a 100644 --- a/arch/arm/lib/testchangebit.S +++ b/arch/arm/lib/testchangebit.S @@ -10,3 +10,7 @@ .text
testop _test_and_change_bit, eor, str + +#if __LINUX_ARM_ARCH__ >= 6 +sync_testop _sync_test_and_change_bit, eor, str +#endif diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S index 009afa0f5b4a7..4d2c5ca620ebf 100644 --- a/arch/arm/lib/testclearbit.S +++ b/arch/arm/lib/testclearbit.S @@ -10,3 +10,7 @@ .text
testop _test_and_clear_bit, bicne, strne + +#if __LINUX_ARM_ARCH__ >= 6 +sync_testop _sync_test_and_clear_bit, bicne, strne +#endif diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S index f3192e55acc87..649dbab65d8d0 100644 --- a/arch/arm/lib/testsetbit.S +++ b/arch/arm/lib/testsetbit.S @@ -10,3 +10,7 @@ .text
testop _test_and_set_bit, orreq, streq + +#if __LINUX_ARM_ARCH__ >= 6 +sync_testop _sync_test_and_set_bit, orreq, streq +#endif
From: Roberto Sassu roberto.sassu@huawei.com
[ Upstream commit b1de86d4248b273cb12c4cd7d20c08d459519f7d ]
Add the description for missing parameters of evm_inode_setattr() to avoid the warning arising with W=n compile option.
Fixes: 817b54aa45db ("evm: add evm_inode_setattr to prevent updating an invalid security.evm") # v3.2+ Fixes: c1632a0f1120 ("fs: port ->setattr() to pass mnt_idmap") # v6.3+ Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Reviewed-by: Stefan Berger stefanb@linux.ibm.com Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/integrity/evm/evm_main.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 7d87772f0ce68..baddd99c38a43 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -770,7 +770,9 @@ static int evm_attr_change(struct dentry *dentry, struct iattr *attr)
/** * evm_inode_setattr - prevent updating an invalid EVM extended attribute + * @idmap: idmap of the mount * @dentry: pointer to the affected dentry + * @attr: iattr structure containing the new file attributes * * Permit update of file attributes when files have a valid EVM signature, * except in the case of them having an immutable portable signature.
From: Roberto Sassu roberto.sassu@huawei.com
[ Upstream commit 996e0a97ebd7b11cb785794e2a83c20c1add9d92 ]
Fix build warnings (function parameters description) for evm_read_protected_xattrs(), evm_set_key() and evm_verifyxattr().
Fixes: 7626676320f3 ("evm: provide a function to set the EVM key from the kernel") # v4.5+ Fixes: 8314b6732ae4 ("ima: Define new template fields xattrnames, xattrlengths and xattrvalues") # v5.14+ Fixes: 2960e6cb5f7c ("evm: additional parameter to pass integrity cache entry 'iint'") # v3.2+ Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/integrity/evm/evm_crypto.c | 2 +- security/integrity/evm/evm_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index b862f0f919bfc..99c7452555c3c 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -40,7 +40,7 @@ static const char evm_hmac[] = "hmac(sha1)"; /** * evm_set_key() - set EVM HMAC key from the kernel * @key: pointer to a buffer with the key data - * @size: length of the key data + * @keylen: length of the key data * * This function allows setting the EVM HMAC key from the kernel * without using the "encrypted" key subsystem keys. It can be used diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index baddd99c38a43..b0e791e184329 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -324,7 +324,6 @@ int evm_protected_xattr_if_enabled(const char *req_xattr_name) /** * evm_read_protected_xattrs - read EVM protected xattr names, lengths, values * @dentry: dentry of the read xattrs - * @inode: inode of the read xattrs * @buffer: buffer xattr names, lengths or values are copied to * @buffer_size: size of buffer * @type: n: names, l: lengths, v: values @@ -396,6 +395,7 @@ int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer, * @xattr_name: requested xattr * @xattr_value: requested xattr value * @xattr_value_len: requested xattr value length + * @iint: inode integrity metadata * * Calculate the HMAC for the given dentry and verify it against the stored * security.evm xattr. For performance, use the xattr value and length
From: Roberto Sassu roberto.sassu@huawei.com
[ Upstream commit 95526d13038c2bbddd567a4d8e39fac42484e182 ]
Fix build warnings (function parameters description) for ima_collect_modsig(), ima_match_policy() and ima_parse_add_rule().
Fixes: 15588227e086 ("ima: Collect modsig") # v5.4+ Fixes: 2fe5d6def167 ("ima: integrity appraisal extension") # v5.14+ Fixes: 4af4662fa4a9 ("integrity: IMA policy") # v3.2+ Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/integrity/ima/ima_modsig.c | 3 +++ security/integrity/ima/ima_policy.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/security/integrity/ima/ima_modsig.c b/security/integrity/ima/ima_modsig.c index fb25723c65bc4..3e7bee30080f2 100644 --- a/security/integrity/ima/ima_modsig.c +++ b/security/integrity/ima/ima_modsig.c @@ -89,6 +89,9 @@ int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
/** * ima_collect_modsig - Calculate the file hash without the appended signature. + * @modsig: parsed module signature + * @buf: data to verify the signature on + * @size: data size * * Since the modsig is part of the file contents, the hash used in its signature * isn't the same one ordinarily calculated by IMA. Therefore PKCS7 code diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index ed43d30682ff8..7e41917e1f767 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -674,6 +674,7 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func) * @secid: LSM secid of the task to be validated * @func: IMA hook identifier * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) + * @flags: IMA actions to consider (e.g. IMA_MEASURE | IMA_APPRAISE) * @pcr: set the pcr to extend * @template_desc: the template that should be used for this rule * @func_data: func specific data, may be NULL @@ -1709,7 +1710,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
/** * ima_parse_add_rule - add a rule to ima_policy_rules - * @rule - ima measurement policy rule + * @rule: ima measurement policy rule * * Avoid locking by allowing just one writer at a time in ima_write_policy() * Returns the length of the rule parsed, an error code on failure
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit d97038d5ec2062733c1e016caf9baaf68cf64ea1 ]
Add check for the return value of kstrdup() and return the error if it fails in order to avoid NULL pointer dereference.
Fixes: e163fdb3f7f8 ("pstore/ram: Regularize prz label allocation lifetime") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20230614093733.36048-1-jiasheng@iscas.ac.cn Signed-off-by: Sasha Levin sashal@kernel.org --- fs/pstore/ram_core.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 155c7010b1f83..fd9bab137685d 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -591,6 +591,8 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size, raw_spin_lock_init(&prz->buffer_lock); prz->flags = flags; prz->label = kstrdup(label, GFP_KERNEL); + if (!prz->label) + goto err;
ret = persistent_ram_buffer_map(start, size, prz, memtype); if (ret)
From: Jesper Dangaard Brouer brouer@redhat.com
[ Upstream commit 84214ab4689f962b4bfc47fc9a5838d25ac4274d ]
When function igc_rx_hash() was introduced in v4.20 via commit 0507ef8a0372 ("igc: Add transmit and receive fastpath and interrupt handlers"), the hardware wasn't configured to provide RSS hash, thus it made sense to not enable net_device NETIF_F_RXHASH feature bit.
The NIC hardware was configured to enable RSS hash info in v5.2 via commit 2121c2712f82 ("igc: Add multiple receive queues control supporting"), but forgot to set the NETIF_F_RXHASH feature bit.
The original implementation of igc_rx_hash() didn't extract the associated pkt_hash_type, but statically set PKT_HASH_TYPE_L3. The largest portions of this patch are about extracting the RSS Type from the hardware and mapping this to enum pkt_hash_types. This was based on Foxville i225 software user manual rev-1.3.1 and tested on Intel Ethernet Controller I225-LM (rev 03).
For UDP it's worth noting that RSS (type) hashing have been disabled both for IPv4 and IPv6 (see IGC_MRQC_RSS_FIELD_IPV4_UDP + IGC_MRQC_RSS_FIELD_IPV6_UDP) because hardware RSS doesn't handle fragmented pkts well when enabled (can cause out-of-order). This results in PKT_HASH_TYPE_L3 for UDP packets, and hash value doesn't include UDP port numbers. Not being PKT_HASH_TYPE_L4, have the effect that netstack will do a software based hash calc calling into flow_dissect, but only when code calls skb_get_hash(), which doesn't necessary happen for local delivery.
For QA verification testing I wrote a small bpftrace prog: [0] https://github.com/xdp-project/xdp-project/blob/master/areas/hints/monitor_s...
Fixes: 2121c2712f82 ("igc: Add multiple receive queues control supporting") Signed-off-by: Jesper Dangaard Brouer brouer@redhat.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Song Yoong Siang yoong.siang.song@intel.com Link: https://lore.kernel.org/bpf/168182464270.616355.11391652654430626584.stgit@f... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/igc/igc.h | 28 ++++++++++++++++++++ drivers/net/ethernet/intel/igc/igc_main.c | 31 ++++++++++++++++++++--- 2 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h index 66678cd72a6cd..486e1ce609cd5 100644 --- a/drivers/net/ethernet/intel/igc/igc.h +++ b/drivers/net/ethernet/intel/igc/igc.h @@ -13,6 +13,7 @@ #include <linux/ptp_clock_kernel.h> #include <linux/timecounter.h> #include <linux/net_tstamp.h> +#include <linux/bitfield.h>
#include "igc_hw.h"
@@ -312,6 +313,33 @@ extern char igc_driver_name[]; #define IGC_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 #define IGC_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
+/* RX-desc Write-Back format RSS Type's */ +enum igc_rss_type_num { + IGC_RSS_TYPE_NO_HASH = 0, + IGC_RSS_TYPE_HASH_TCP_IPV4 = 1, + IGC_RSS_TYPE_HASH_IPV4 = 2, + IGC_RSS_TYPE_HASH_TCP_IPV6 = 3, + IGC_RSS_TYPE_HASH_IPV6_EX = 4, + IGC_RSS_TYPE_HASH_IPV6 = 5, + IGC_RSS_TYPE_HASH_TCP_IPV6_EX = 6, + IGC_RSS_TYPE_HASH_UDP_IPV4 = 7, + IGC_RSS_TYPE_HASH_UDP_IPV6 = 8, + IGC_RSS_TYPE_HASH_UDP_IPV6_EX = 9, + IGC_RSS_TYPE_MAX = 10, +}; +#define IGC_RSS_TYPE_MAX_TABLE 16 +#define IGC_RSS_TYPE_MASK GENMASK(3,0) /* 4-bits (3:0) = mask 0x0F */ + +/* igc_rss_type - Rx descriptor RSS type field */ +static inline u32 igc_rss_type(const union igc_adv_rx_desc *rx_desc) +{ + /* RSS Type 4-bits (3:0) number: 0-9 (above 9 is reserved) + * Accessing the same bits via u16 (wb.lower.lo_dword.hs_rss.pkt_info) + * is slightly slower than via u32 (wb.lower.lo_dword.data) + */ + return le32_get_bits(rx_desc->wb.lower.lo_dword.data, IGC_RSS_TYPE_MASK); +} + /* Interrupt defines */ #define IGC_START_ITR 648 /* ~6000 ints/sec */ #define IGC_4K_ITR 980 diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index eb7aa8c13f7e5..32e4ebac4b693 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -1683,14 +1683,36 @@ static void igc_rx_checksum(struct igc_ring *ring, le32_to_cpu(rx_desc->wb.upper.status_error)); }
+/* Mapping HW RSS Type to enum pkt_hash_types */ +static const enum pkt_hash_types igc_rss_type_table[IGC_RSS_TYPE_MAX_TABLE] = { + [IGC_RSS_TYPE_NO_HASH] = PKT_HASH_TYPE_L2, + [IGC_RSS_TYPE_HASH_TCP_IPV4] = PKT_HASH_TYPE_L4, + [IGC_RSS_TYPE_HASH_IPV4] = PKT_HASH_TYPE_L3, + [IGC_RSS_TYPE_HASH_TCP_IPV6] = PKT_HASH_TYPE_L4, + [IGC_RSS_TYPE_HASH_IPV6_EX] = PKT_HASH_TYPE_L3, + [IGC_RSS_TYPE_HASH_IPV6] = PKT_HASH_TYPE_L3, + [IGC_RSS_TYPE_HASH_TCP_IPV6_EX] = PKT_HASH_TYPE_L4, + [IGC_RSS_TYPE_HASH_UDP_IPV4] = PKT_HASH_TYPE_L4, + [IGC_RSS_TYPE_HASH_UDP_IPV6] = PKT_HASH_TYPE_L4, + [IGC_RSS_TYPE_HASH_UDP_IPV6_EX] = PKT_HASH_TYPE_L4, + [10] = PKT_HASH_TYPE_NONE, /* RSS Type above 9 "Reserved" by HW */ + [11] = PKT_HASH_TYPE_NONE, /* keep array sized for SW bit-mask */ + [12] = PKT_HASH_TYPE_NONE, /* to handle future HW revisons */ + [13] = PKT_HASH_TYPE_NONE, + [14] = PKT_HASH_TYPE_NONE, + [15] = PKT_HASH_TYPE_NONE, +}; + static inline void igc_rx_hash(struct igc_ring *ring, union igc_adv_rx_desc *rx_desc, struct sk_buff *skb) { - if (ring->netdev->features & NETIF_F_RXHASH) - skb_set_hash(skb, - le32_to_cpu(rx_desc->wb.lower.hi_dword.rss), - PKT_HASH_TYPE_L3); + if (ring->netdev->features & NETIF_F_RXHASH) { + u32 rss_hash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); + u32 rss_type = igc_rss_type(rx_desc); + + skb_set_hash(skb, rss_hash, igc_rss_type_table[rss_type]); + } }
static void igc_rx_vlan(struct igc_ring *rx_ring, @@ -6525,6 +6547,7 @@ static int igc_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_TSO; netdev->features |= NETIF_F_TSO6; netdev->features |= NETIF_F_TSO_ECN; + netdev->features |= NETIF_F_RXHASH; netdev->features |= NETIF_F_RXCSUM; netdev->features |= NETIF_F_HW_CSUM; netdev->features |= NETIF_F_SCTP_CRC;
From: Peter Seiderer ps.report@gmx.net
[ Upstream commit 3e56c80931c7615250fe4bf83f93b57881969266 ]
Fix ath9k_hw_verify_hang()/ar9003_hw_detect_mac_hang() register offset calculation (do not overflow the shift for the second register/queues above five, use the register layout described in the comments above ath9k_hw_verify_hang() instead).
Fixes: 222e04830ff0 ("ath9k: Fix MAC HW hang check for AR9003")
Reported-by: Gregg Wonderly greggwonderly@seqtechllc.com Link: https://lore.kernel.org/linux-wireless/E3A9C354-0CB7-420C-ADEF-F0177FB722F4@... Signed-off-by: Peter Seiderer ps.report@gmx.net Acked-by: Toke Høiland-Jørgensen toke@toke.dk Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230422212423.26065-1-ps.report@gmx.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 27 ++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 42f00a2a8c800..cf5648188459c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -1099,17 +1099,22 @@ static bool ath9k_hw_verify_hang(struct ath_hw *ah, unsigned int queue) { u32 dma_dbg_chain, dma_dbg_complete; u8 dcu_chain_state, dcu_complete_state; + unsigned int dbg_reg, reg_offset; int i;
- for (i = 0; i < NUM_STATUS_READS; i++) { - if (queue < 6) - dma_dbg_chain = REG_READ(ah, AR_DMADBG_4); - else - dma_dbg_chain = REG_READ(ah, AR_DMADBG_5); + if (queue < 6) { + dbg_reg = AR_DMADBG_4; + reg_offset = queue * 5; + } else { + dbg_reg = AR_DMADBG_5; + reg_offset = (queue - 6) * 5; + }
+ for (i = 0; i < NUM_STATUS_READS; i++) { + dma_dbg_chain = REG_READ(ah, dbg_reg); dma_dbg_complete = REG_READ(ah, AR_DMADBG_6);
- dcu_chain_state = (dma_dbg_chain >> (5 * queue)) & 0x1f; + dcu_chain_state = (dma_dbg_chain >> reg_offset) & 0x1f; dcu_complete_state = dma_dbg_complete & 0x3;
if ((dcu_chain_state != 0x6) || (dcu_complete_state != 0x1)) @@ -1128,6 +1133,7 @@ static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah) u8 dcu_chain_state, dcu_complete_state; bool dcu_wait_frdone = false; unsigned long chk_dcu = 0; + unsigned int reg_offset; unsigned int i = 0;
dma_dbg_4 = REG_READ(ah, AR_DMADBG_4); @@ -1139,12 +1145,15 @@ static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah) goto exit;
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { - if (i < 6) + if (i < 6) { chk_dbg = dma_dbg_4; - else + reg_offset = i * 5; + } else { chk_dbg = dma_dbg_5; + reg_offset = (i - 6) * 5; + }
- dcu_chain_state = (chk_dbg >> (5 * i)) & 0x1f; + dcu_chain_state = (chk_dbg >> reg_offset) & 0x1f; if (dcu_chain_state == 0x6) { dcu_wait_frdone = true; chk_dcu |= BIT(i);
From: Fedor Pchelkin pchelkin@ispras.ru
[ Upstream commit f24292e827088bba8de7158501ac25a59b064953 ]
For the reasons also described in commit b383e8abed41 ("wifi: ath9k: avoid uninit memory read in ath9k_htc_rx_msg()"), ath9k_htc_rx_msg() should validate pkt_len before accessing the SKB.
For example, the obtained SKB may have been badly constructed with pkt_len = 8. In this case, the SKB can only contain a valid htc_frame_hdr but after being processed in ath9k_htc_rx_msg() and passed to ath9k_wmi_ctrl_rx() endpoint RX handler, it is expected to have a WMI command header which should be located inside its data payload.
Implement sanity checking inside ath9k_wmi_ctrl_rx(). Otherwise, uninit memory can be referenced.
Tested on Qualcomm Atheros Communications AR9271 802.11n .
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.") Reported-and-tested-by: syzbot+f2cb6e0ffdb961921e4d@syzkaller.appspotmail.com Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Acked-by: Toke Høiland-Jørgensen toke@toke.dk Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230424183348.111355-1-pchelkin@ispras.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/wmi.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 19345b8f7bfd5..d652c647d56b5 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -221,6 +221,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, if (unlikely(wmi->stopped)) goto free_skb;
+ /* Validate the obtained SKB. */ + if (unlikely(skb->len < sizeof(struct wmi_cmd_hdr))) + goto free_skb; + hdr = (struct wmi_cmd_hdr *) skb->data; cmd_id = be16_to_cpu(hdr->command_id);
From: Martin KaFai Lau martin.lau@kernel.org
[ Upstream commit c39028b333f3a3a765c5c0b9726b8e38aedf0ba1 ]
The btf_dump/struct_data selftest is failing with:
[...] test_btf_dump_struct_data:FAIL:unexpected return value dumping fs_context unexpected unexpected return value dumping fs_context: actual -7 != expected 264 [...]
The reason is in btf_dump_type_data_check_overflow(). It does not use BTF_MEMBER_BITFIELD_SIZE from the struct's member (btf_member). Instead, it is using the enum size which is 4. It had been working till the recent commit 4e04143c869c ("fs_context: drop the unused lsm_flags member") removed an integer member which also removed the 4 bytes padding at the end of the fs_context. Missing this 4 bytes padding exposed this bug. In particular, when btf_dump_type_data_check_overflow() reaches the member 'phase', -E2BIG is returned.
The fix is to pass bit_sz to btf_dump_type_data_check_overflow(). In btf_dump_type_data_check_overflow(), it does a different size check when bit_sz is not zero.
The current fs_context:
[3600] ENUM 'fs_context_purpose' encoding=UNSIGNED size=4 vlen=3 'FS_CONTEXT_FOR_MOUNT' val=0 'FS_CONTEXT_FOR_SUBMOUNT' val=1 'FS_CONTEXT_FOR_RECONFIGURE' val=2 [3601] ENUM 'fs_context_phase' encoding=UNSIGNED size=4 vlen=7 'FS_CONTEXT_CREATE_PARAMS' val=0 'FS_CONTEXT_CREATING' val=1 'FS_CONTEXT_AWAITING_MOUNT' val=2 'FS_CONTEXT_AWAITING_RECONF' val=3 'FS_CONTEXT_RECONF_PARAMS' val=4 'FS_CONTEXT_RECONFIGURING' val=5 'FS_CONTEXT_FAILED' val=6 [3602] STRUCT 'fs_context' size=264 vlen=21 'ops' type_id=3603 bits_offset=0 'uapi_mutex' type_id=235 bits_offset=64 'fs_type' type_id=872 bits_offset=1216 'fs_private' type_id=21 bits_offset=1280 'sget_key' type_id=21 bits_offset=1344 'root' type_id=781 bits_offset=1408 'user_ns' type_id=251 bits_offset=1472 'net_ns' type_id=984 bits_offset=1536 'cred' type_id=1785 bits_offset=1600 'log' type_id=3621 bits_offset=1664 'source' type_id=42 bits_offset=1792 'security' type_id=21 bits_offset=1856 's_fs_info' type_id=21 bits_offset=1920 'sb_flags' type_id=20 bits_offset=1984 'sb_flags_mask' type_id=20 bits_offset=2016 's_iflags' type_id=20 bits_offset=2048 'purpose' type_id=3600 bits_offset=2080 bitfield_size=8 'phase' type_id=3601 bits_offset=2088 bitfield_size=8 'need_free' type_id=67 bits_offset=2096 bitfield_size=1 'global' type_id=67 bits_offset=2097 bitfield_size=1 'oldapi' type_id=67 bits_offset=2098 bitfield_size=1
Fixes: 920d16af9b42 ("libbpf: BTF dumper support for typed data") Signed-off-by: Martin KaFai Lau martin.lau@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20230428013638.1581263-1-martin.lau@linux.dev Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/btf_dump.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index 98cb3831aa18c..b91dd7cd4ffb0 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -2126,9 +2126,25 @@ static int btf_dump_type_data_check_overflow(struct btf_dump *d, const struct btf_type *t, __u32 id, const void *data, - __u8 bits_offset) + __u8 bits_offset, + __u8 bit_sz) { - __s64 size = btf__resolve_size(d->btf, id); + __s64 size; + + if (bit_sz) { + /* bits_offset is at most 7. bit_sz is at most 128. */ + __u8 nr_bytes = (bits_offset + bit_sz + 7) / 8; + + /* When bit_sz is non zero, it is called from + * btf_dump_struct_data() where it only cares about + * negative error value. + * Return nr_bytes in success case to make it + * consistent as the regular integer case below. + */ + return data + nr_bytes > d->typed_dump->data_end ? -E2BIG : nr_bytes; + } + + size = btf__resolve_size(d->btf, id);
if (size < 0 || size >= INT_MAX) { pr_warn("unexpected size [%zu] for id [%u]\n", @@ -2281,7 +2297,7 @@ static int btf_dump_dump_type_data(struct btf_dump *d, { int size, err = 0;
- size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset); + size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset, bit_sz); if (size < 0) return size; err = btf_dump_type_data_check_zero(d, t, id, data, bits_offset, bit_sz);
From: Pengcheng Yang yangpc@wangsu.com
[ Upstream commit f4dea9689c5fea3d07170c2cb0703e216f1a0922 ]
Using sizeof(nv) or strlen(nv)+1 is correct.
Fixes: c890063e4404 ("bpf: sample BPF_SOCKET_OPS_BASE_RTT program") Signed-off-by: Pengcheng Yang yangpc@wangsu.com Link: https://lore.kernel.org/r/1683276658-2860-1-git-send-email-yangpc@wangsu.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- samples/bpf/tcp_basertt_kern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/samples/bpf/tcp_basertt_kern.c b/samples/bpf/tcp_basertt_kern.c index 8dfe09a92feca..822b0742b8154 100644 --- a/samples/bpf/tcp_basertt_kern.c +++ b/samples/bpf/tcp_basertt_kern.c @@ -47,7 +47,7 @@ int bpf_basertt(struct bpf_sock_ops *skops) case BPF_SOCK_OPS_BASE_RTT: n = bpf_getsockopt(skops, SOL_TCP, TCP_CONGESTION, cong, sizeof(cong)); - if (!n && !__builtin_memcmp(cong, nv, sizeof(nv)+1)) { + if (!n && !__builtin_memcmp(cong, nv, sizeof(nv))) { /* Set base_rtt to 80us */ rv = 80; } else if (n) {
From: Vijaya Krishna Nivarthi quic_vnivarth@quicinc.com
[ Upstream commit 5fd7c99ecf45c8ee8a9b1268f0ffc91cc6271da2 ]
The CS_TOGGLE bit when set is supposed to instruct FW to toggle CS line between words. The driver with intent of disabling this behaviour has been unsetting BIT(0). This has not caused any trouble so far because the original BIT(1) is untouched and BIT(0) likely wasn't being used.
Correct this to prevent a potential future bug.
Signed-off-by: Vijaya Krishna Nivarthi <quic_vnivarth@quicinc.com Acked-by: Konrad Dybcio <konrad.dybcio@linaro.org Fixes: 561de45f72bd ("spi: spi-geni-qcom: Add SPI driver support for GENI based QUP") Reviewed-by: Douglas Anderson <dianders@chromium.org Link: https://lore.kernel.org/r/1682412128-1913-1-git-send-email-quic_vnivarth@qui... Signed-off-by: Mark Brown <broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-geni-qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index 2f51421e2a718..4b92f119955c7 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -32,7 +32,7 @@ #define CS_DEMUX_OUTPUT_SEL GENMASK(3, 0)
#define SE_SPI_TRANS_CFG 0x25c -#define CS_TOGGLE BIT(0) +#define CS_TOGGLE BIT(1)
#define SE_SPI_WORD_LEN 0x268 #define WORD_LEN_MSK GENMASK(9, 0)
From: Amisha Patel amisha.patel@microchip.com
[ Upstream commit 9ce4bb09123e9754996e358bd808d39f5d112899 ]
Mandatory WFA testcase CT_Security_WPA2Personal_STA_RSNEBoundsVerification-AbsentRSNCap, performs bounds verfication on Beacon and/or Probe response frames. It failed and observed the reason to be absence of cipher suite and AKM suite in RSN information. To fix this, enable the RSN flag before extracting RSN capabilities.
Fixes: cd21d99e595e ("wifi: wilc1000: validate pairwise and authentication suite offsets") Signed-off-by: Amisha Patel amisha.patel@microchip.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230421181005.4865-1-amisha.patel@microchip.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/microchip/wilc1000/hif.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c index 3e5cc947b9b90..a7bca0475e1ee 100644 --- a/drivers/net/wireless/microchip/wilc1000/hif.c +++ b/drivers/net/wireless/microchip/wilc1000/hif.c @@ -470,6 +470,9 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, int rsn_ie_len = sizeof(struct element) + rsn_ie[1]; int offset = 8;
+ param->mode_802_11i = 2; + param->rsn_found = true; + /* extract RSN capabilities */ if (offset < rsn_ie_len) { /* skip over pairwise suites */ @@ -479,11 +482,8 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, /* skip over authentication suites */ offset += (rsn_ie[offset] * 4) + 2;
- if (offset + 1 < rsn_ie_len) { - param->mode_802_11i = 2; - param->rsn_found = true; + if (offset + 1 < rsn_ie_len) memcpy(param->rsn_cap, &rsn_ie[offset], 2); - } } } }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit d9aef04fcfa81ee4fb2804a21a3712b7bbd936af ]
The type of "mwifiex_adapter->nd_info" is "struct cfg80211_wowlan_nd_info", not "struct cfg80211_wowlan_nd_match".
Use struct_size() to ease the computation of the needed size.
The current code over-allocates some memory, so is safe. But it wastes 32 bytes.
Fixes: 7d7f07d8c5d3 ("mwifiex: add wowlan net-detect support") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/7a6074fb056d2181e058a3cc6048d8155c20aec7.168337198... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/scan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c index 0b877f3f6b974..5ec8a42e7150a 100644 --- a/drivers/net/wireless/marvell/mwifiex/scan.c +++ b/drivers/net/wireless/marvell/mwifiex/scan.c @@ -2199,9 +2199,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
if (nd_config) { adapter->nd_info = - kzalloc(sizeof(struct cfg80211_wowlan_nd_match) + - sizeof(struct cfg80211_wowlan_nd_match *) * - scan_rsp->number_of_sets, GFP_ATOMIC); + kzalloc(struct_size(adapter->nd_info, matches, + scan_rsp->number_of_sets), + GFP_ATOMIC);
if (adapter->nd_info) adapter->nd_info->n_matches = scan_rsp->number_of_sets;
From: Alexander Mikhalitsyn aleksandr.mikhalitsyn@canonical.com
[ Upstream commit 2598619e012cee5273a2821441b9a051ad931249 ]
Implement ->bpf_bypass_getsockopt proto callback and filter out SCTP_SOCKOPT_PEELOFF, SCTP_SOCKOPT_PEELOFF_FLAGS and SCTP_SOCKOPT_CONNECTX3 socket options from running eBPF hook on them.
SCTP_SOCKOPT_PEELOFF and SCTP_SOCKOPT_PEELOFF_FLAGS options do fd_install(), and if BPF_CGROUP_RUN_PROG_GETSOCKOPT hook returns an error after success of the original handler sctp_getsockopt(...), userspace will receive an error from getsockopt syscall and will be not aware that fd was successfully installed into a fdtable.
As pointed by Marcelo Ricardo Leitner it seems reasonable to skip bpf getsockopt hook for SCTP_SOCKOPT_CONNECTX3 sockopt too. Because internaly, it triggers connect() and if error is masked then userspace will be confused.
This patch was born as a result of discussion around a new SCM_PIDFD interface: https://lore.kernel.org/all/20230413133355.350571-3-aleksandr.mikhalitsyn@ca...
Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks") Cc: Daniel Borkmann daniel@iogearbox.net Cc: Christian Brauner brauner@kernel.org Cc: Stanislav Fomichev sdf@google.com Cc: Neil Horman nhorman@tuxdriver.com Cc: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Cc: Xin Long lucien.xin@gmail.com Cc: linux-sctp@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Suggested-by: Stanislav Fomichev sdf@google.com Acked-by: Stanislav Fomichev sdf@google.com Signed-off-by: Alexander Mikhalitsyn aleksandr.mikhalitsyn@canonical.com Acked-by: Xin Long lucien.xin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/sctp/socket.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 2bbc81ddb9e08..ed35d4a4c5253 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -8287,6 +8287,22 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, return retval; }
+static bool sctp_bpf_bypass_getsockopt(int level, int optname) +{ + if (level == SOL_SCTP) { + switch (optname) { + case SCTP_SOCKOPT_PEELOFF: + case SCTP_SOCKOPT_PEELOFF_FLAGS: + case SCTP_SOCKOPT_CONNECTX3: + return true; + default: + return false; + } + } + + return false; +} + static int sctp_hash(struct sock *sk) { /* STUB */ @@ -9655,6 +9671,7 @@ struct proto sctp_prot = { .shutdown = sctp_shutdown, .setsockopt = sctp_setsockopt, .getsockopt = sctp_getsockopt, + .bpf_bypass_getsockopt = sctp_bpf_bypass_getsockopt, .sendmsg = sctp_sendmsg, .recvmsg = sctp_recvmsg, .bind = sctp_bind, @@ -9707,6 +9724,7 @@ struct proto sctpv6_prot = { .shutdown = sctp_shutdown, .setsockopt = sctp_setsockopt, .getsockopt = sctp_getsockopt, + .bpf_bypass_getsockopt = sctp_bpf_bypass_getsockopt, .sendmsg = sctp_sendmsg, .recvmsg = sctp_recvmsg, .bind = sctp_bind,
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit bdeeed3498c7871c17465bb4f11d1bc67f9098af ]
It seems like __builtin_offset() doesn't preserve CO-RE field relocations properly. So if offsetof() macro is defined through __builtin_offset(), CO-RE-enabled BPF code using container_of() will be subtly and silently broken.
To avoid this problem, redefine offsetof() and container_of() in the form that works with CO-RE relocations more reliably.
Fixes: 5fbc220862fc ("tools/libpf: Add offsetof/container_of macro in bpf_helpers.h") Reported-by: Lennart Poettering lennart@poettering.net Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/r/20230509065502.2306180-1-andrii@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/bpf_helpers.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h index b9987c3efa3c4..956b57d02eb9a 100644 --- a/tools/lib/bpf/bpf_helpers.h +++ b/tools/lib/bpf/bpf_helpers.h @@ -72,16 +72,21 @@ /* * Helper macros to manipulate data structures */ -#ifndef offsetof -#define offsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER) -#endif -#ifndef container_of + +/* offsetof() definition that uses __builtin_offset() might not preserve field + * offset CO-RE relocation properly, so force-redefine offsetof() using + * old-school approach which works with CO-RE correctly + */ +#undef offsetof +#define offsetof(type, member) ((unsigned long)&((type *)0)->member) + +/* redefined container_of() to ensure we use the above offsetof() macro */ +#undef container_of #define container_of(ptr, type, member) \ ({ \ void *__mptr = (void *)(ptr); \ ((type *)(__mptr - offsetof(type, member))); \ }) -#endif
/* * Helper macro to throw a compilation error if __bpf_unreachable() gets
From: Stanislav Fomichev sdf@google.com
[ Upstream commit 29ebbba7d46136cba324264e513a1e964ca16c0a ]
With the way the hooks implemented right now, we have a special condition: optval larger than PAGE_SIZE will expose only first 4k into BPF; any modifications to the optval are ignored. If the BPF program doesn't handle this condition by resetting optlen to 0, the userspace will get EFAULT.
The intention of the EFAULT was to make it apparent to the developers that the program is doing something wrong. However, this inadvertently might affect production workloads with the BPF programs that are not too careful (i.e., returning EFAULT for perfectly valid setsockopt/getsockopt calls).
Let's try to minimize the chance of BPF program screwing up userspace by ignoring the output of those BPF programs (instead of returning EFAULT to the userspace). pr_info_once those cases to the dmesg to help with figuring out what's going wrong.
Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks") Suggested-by: Martin KaFai Lau martin.lau@kernel.org Signed-off-by: Stanislav Fomichev sdf@google.com Link: https://lore.kernel.org/r/20230511170456.1759459-2-sdf@google.com Signed-off-by: Martin KaFai Lau martin.lau@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/cgroup.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 87174832aa86d..297569e5c6399 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1481,6 +1481,12 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level, ret = 1; } else if (ctx.optlen > max_optlen || ctx.optlen < -1) { /* optlen is out of bounds */ + if (*optlen > PAGE_SIZE && ctx.optlen >= 0) { + pr_info_once("bpf setsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n", + ctx.optlen, max_optlen); + ret = 0; + goto out; + } ret = -EFAULT; } else { /* optlen within bounds, run kernel handler */ @@ -1536,6 +1542,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, .optname = optname, .retval = retval, }; + int orig_optlen; int ret;
/* Opportunistic check to see whether we have any BPF program @@ -1545,6 +1552,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, if (__cgroup_bpf_prog_array_is_empty(cgrp, CGROUP_GETSOCKOPT)) return retval;
+ orig_optlen = max_optlen; ctx.optlen = max_optlen;
max_optlen = sockopt_alloc_buf(&ctx, max_optlen, &buf); @@ -1568,6 +1576,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, ret = -EFAULT; goto out; } + orig_optlen = ctx.optlen;
if (copy_from_user(ctx.optval, optval, min(ctx.optlen, max_optlen)) != 0) { @@ -1587,6 +1596,12 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, }
if (optval && (ctx.optlen > max_optlen || ctx.optlen < 0)) { + if (orig_optlen > PAGE_SIZE && ctx.optlen >= 0) { + pr_info_once("bpf getsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n", + ctx.optlen, max_optlen); + ret = retval; + goto out; + } ret = -EFAULT; goto out; }
From: Joy Chakraborty joychakr@google.com
[ Upstream commit 9f34baf67e4d08908fd94ff29c825bb673295336 ]
n_bytes variable in the driver represents the number of bytes per word that needs to be sent/copied to fifo. Bits/word can be between 8 and 32 bits from the client but in memory they are a power of 2, same is mentioned in spi.h header: " * @bits_per_word: Data transfers involve one or more words; word sizes * like eight or 12 bits are common. In-memory wordsizes are * powers of two bytes (e.g. 20 bit samples use 32 bits). * This may be changed by the device's driver, or left at the * default (0) indicating protocol words are eight bit bytes. * The spi_transfer.bits_per_word can override this for each transfer. "
Hence, round of n_bytes to a power of 2 to avoid values like 3 which would generate unalligned/odd accesses to memory/fifo.
* tested on Baikal-T1 based system with DW SPI-looped back interface transferring a chunk of data with DFS:8,12,16.
Fixes: a51acc2400d4 ("spi: dw: Add support for 32-bits max xfer size") Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com Signed-off-by: Joy Chakraborty <joychakr@google.com Reviewed-by: Serge Semin <fancer.lancer@gmail.com Tested-by: Serge Semin <fancer.lancer@gmail.com Link: https://lore.kernel.org/r/20230512104746.1797865-4-joychakr@google.com Signed-off-by: Mark Brown <broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-dw-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 59e22c6b4b201..8fc598f09a728 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -416,7 +416,10 @@ static int dw_spi_transfer_one(struct spi_controller *master, int ret;
dws->dma_mapped = 0; - dws->n_bytes = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE); + dws->n_bytes = + roundup_pow_of_two(DIV_ROUND_UP(transfer->bits_per_word, + BITS_PER_BYTE)); + dws->tx = (void *)transfer->tx_buf; dws->tx_len = transfer->len / dws->n_bytes; dws->rx = transfer->rx_buf;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 0d9b41daa5907756a31772d8af8ac5ff25cf17c1 ]
If sock->service_name is NULL, the local variable service_name_tlv_length will not be assigned by nfc_llcp_build_tlv(), later leading to using value frmo the stack. Smatch warning:
net/nfc/llcp_commands.c:442 nfc_llcp_send_connect() error: uninitialized symbol 'service_name_tlv_length'.
Fixes: de9e5aeb4f40 ("NFC: llcp: Fix usage of llcp_add_tlv()") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/nfc/llcp_commands.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c index 3c4172a5aeb5e..bb9f40563ff63 100644 --- a/net/nfc/llcp_commands.c +++ b/net/nfc/llcp_commands.c @@ -394,7 +394,8 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) const u8 *service_name_tlv = NULL; const u8 *miux_tlv = NULL; const u8 *rw_tlv = NULL; - u8 service_name_tlv_length, miux_tlv_length, rw_tlv_length, rw; + u8 service_name_tlv_length = 0; + u8 miux_tlv_length, rw_tlv_length, rw; int err; u16 size = 0; __be16 miux;
From: Alan Maguire alan.maguire@oracle.com
[ Upstream commit 04cb8453a91c7c22f60ddadb6cef0d19abb33bb5 ]
On aarch64, "bpftool feature" reports an incorrect BPF JIT limit:
$ sudo /sbin/bpftool feature Scanning system configuration... bpf() syscall restricted to privileged users JIT compiler is enabled JIT compiler hardening is disabled JIT compiler kallsyms exports are enabled for root skipping kernel config, can't open file: No such file or directory Global memory limit for JIT compiler for unprivileged users is -201326592 bytes
This is because /proc/sys/net/core/bpf_jit_limit reports
$ sudo cat /proc/sys/net/core/bpf_jit_limit 68169519595520
...and an int is assumed in read_procfs(). Change read_procfs() to return a long to avoid negative value reporting.
Fixes: 7a4522bbef0c ("tools: bpftool: add probes for /proc/ eBPF parameters") Reported-by: Nicky Veitch nicky.veitch@oracle.com Signed-off-by: Alan Maguire alan.maguire@oracle.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Jiri Olsa jolsa@kernel.org Acked-by: Quentin Monnet quentin@isovalent.com Link: https://lore.kernel.org/bpf/20230512113134.58996-1-alan.maguire@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/bpf/bpftool/feature.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c index 7f36385aa9e2e..0c9544c6d3020 100644 --- a/tools/bpf/bpftool/feature.c +++ b/tools/bpf/bpftool/feature.c @@ -135,12 +135,12 @@ static void print_end_section(void)
/* Probing functions */
-static int read_procfs(const char *path) +static long read_procfs(const char *path) { char *endptr, *line = NULL; size_t len = 0; FILE *fd; - int res; + long res;
fd = fopen(path, "r"); if (!fd) @@ -162,7 +162,7 @@ static int read_procfs(const char *path)
static void probe_unprivileged_disabled(void) { - int res; + long res;
/* No support for C-style ouptut */
@@ -181,14 +181,14 @@ static void probe_unprivileged_disabled(void) printf("Unable to retrieve required privileges for bpf() syscall\n"); break; default: - printf("bpf() syscall restriction has unknown value %d\n", res); + printf("bpf() syscall restriction has unknown value %ld\n", res); } } }
static void probe_jit_enable(void) { - int res; + long res;
/* No support for C-style ouptut */
@@ -210,7 +210,7 @@ static void probe_jit_enable(void) printf("Unable to retrieve JIT-compiler status\n"); break; default: - printf("JIT-compiler status has unknown value %d\n", + printf("JIT-compiler status has unknown value %ld\n", res); } } @@ -218,7 +218,7 @@ static void probe_jit_enable(void)
static void probe_jit_harden(void) { - int res; + long res;
/* No support for C-style ouptut */
@@ -240,7 +240,7 @@ static void probe_jit_harden(void) printf("Unable to retrieve JIT hardening status\n"); break; default: - printf("JIT hardening status has unknown value %d\n", + printf("JIT hardening status has unknown value %ld\n", res); } } @@ -248,7 +248,7 @@ static void probe_jit_harden(void)
static void probe_jit_kallsyms(void) { - int res; + long res;
/* No support for C-style ouptut */
@@ -267,14 +267,14 @@ static void probe_jit_kallsyms(void) printf("Unable to retrieve JIT kallsyms export status\n"); break; default: - printf("JIT kallsyms exports status has unknown value %d\n", res); + printf("JIT kallsyms exports status has unknown value %ld\n", res); } } }
static void probe_jit_limit(void) { - int res; + long res;
/* No support for C-style ouptut */
@@ -287,7 +287,7 @@ static void probe_jit_limit(void) printf("Unable to retrieve global memory limit for JIT compiler for unprivileged users\n"); break; default: - printf("Global memory limit for JIT compiler for unprivileged users is %d bytes\n", res); + printf("Global memory limit for JIT compiler for unprivileged users is %ld bytes\n", res); } } }
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 2715bb11cfff964aa33946847f9527cfbd4874f5 ]
In case of failure, debugfs_create_dir() does not return NULL, but an error pointer. Most incorrect error checks were fixed, but the one in create_regulator() was forgotten.
Fix the remaining error check.
Fixes: 2bf1c45be3b8f3a3 ("regulator: Fix error checking for debugfs_create_dir") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/ee980a108b5854dd8ce3630f8f673e784e057d17.168501305... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 211ab227b000c..77573569bc78a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1874,7 +1874,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
if (err != -EEXIST) regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs); - if (!regulator->debugfs) { + if (IS_ERR(regulator->debugfs)) { rdev_dbg(rdev, "Failed to create debugfs directory\n"); } else { debugfs_create_u32("uA_load", 0444, regulator->debugfs,
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 08880713ceec023dd94d634f1e8902728c385939 ]
If CONFIG_DEBUG_FS is not set:
regulator: Failed to create debugfs directory ... regulator-dummy: Failed to create debugfs directory
As per the comments for debugfs_create_dir(), errors returned by this function should be expected, and ignored:
* If debugfs is not enabled in the kernel, the value -%ENODEV will be * returned. * * NOTE: it's expected that most callers should _ignore_ the errors returned * by this function. Other debugfs functions handle the fact that the "dentry" * passed to them could be an error and they don't crash in that case. * Drivers should generally work fine even if debugfs fails to init anyway.
Adhere to the debugfs spirit, and streamline all operations by: 1. Demoting the importance of the printed error messages to debug level, like is already done in create_regulator(), 2. Further ignoring any returned errors, as by design, all debugfs functions are no-ops when passed an error pointer.
Fixes: 2bf1c45be3b8f3a3 ("regulator: Fix error checking for debugfs_create_dir") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/2f8bb6e113359ddfab7b59e4d4274bd4c06d6d0a.168501305... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/core.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 77573569bc78a..ebde10e744343 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1874,19 +1874,17 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
if (err != -EEXIST) regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs); - if (IS_ERR(regulator->debugfs)) { + if (IS_ERR(regulator->debugfs)) rdev_dbg(rdev, "Failed to create debugfs directory\n"); - } else { - debugfs_create_u32("uA_load", 0444, regulator->debugfs, - ®ulator->uA_load); - debugfs_create_u32("min_uV", 0444, regulator->debugfs, - ®ulator->voltage[PM_SUSPEND_ON].min_uV); - debugfs_create_u32("max_uV", 0444, regulator->debugfs, - ®ulator->voltage[PM_SUSPEND_ON].max_uV); - debugfs_create_file("constraint_flags", 0444, - regulator->debugfs, regulator, - &constraint_flags_fops); - } + + debugfs_create_u32("uA_load", 0444, regulator->debugfs, + ®ulator->uA_load); + debugfs_create_u32("min_uV", 0444, regulator->debugfs, + ®ulator->voltage[PM_SUSPEND_ON].min_uV); + debugfs_create_u32("max_uV", 0444, regulator->debugfs, + ®ulator->voltage[PM_SUSPEND_ON].max_uV); + debugfs_create_file("constraint_flags", 0444, regulator->debugfs, + regulator, &constraint_flags_fops);
/* * Check now if the regulator is an always on regulator - if @@ -5193,10 +5191,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) }
rdev->debugfs = debugfs_create_dir(rname, debugfs_root); - if (IS_ERR(rdev->debugfs)) { - rdev_warn(rdev, "Failed to create debugfs directory\n"); - return; - } + if (IS_ERR(rdev->debugfs)) + rdev_dbg(rdev, "Failed to create debugfs directory\n");
debugfs_create_u32("use_count", 0444, rdev->debugfs, &rdev->use_count); @@ -6104,7 +6100,7 @@ static int __init regulator_init(void)
debugfs_root = debugfs_create_dir("regulator", NULL); if (IS_ERR(debugfs_root)) - pr_warn("regulator: Failed to create debugfs directory\n"); + pr_debug("regulator: Failed to create debugfs directory\n");
#ifdef CONFIG_DEBUG_FS debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 925244325159824385209e3e0e3f91fa6bf0646c ]
Should spectrum_cs_config() fail, some resources need to be released as already done in the remove function.
While at it, remove a useless and erroneous comment. The probe is spectrum_cs_probe(), not spectrum_cs_attach().
Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/c0bc0c21c58ca477fc5521607615bafbf2aef8eb.168456773... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intersil/orinoco/spectrum_cs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intersil/orinoco/spectrum_cs.c b/drivers/net/wireless/intersil/orinoco/spectrum_cs.c index 291ef97ed45ec..841d623c621ac 100644 --- a/drivers/net/wireless/intersil/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/intersil/orinoco/spectrum_cs.c @@ -157,6 +157,7 @@ spectrum_cs_probe(struct pcmcia_device *link) { struct orinoco_private *priv; struct orinoco_pccard *card; + int ret;
priv = alloc_orinocodev(sizeof(*card), &link->dev, spectrum_cs_hard_reset, @@ -169,8 +170,16 @@ spectrum_cs_probe(struct pcmcia_device *link) card->p_dev = link; link->priv = priv;
- return spectrum_cs_config(link); -} /* spectrum_cs_attach */ + ret = spectrum_cs_config(link); + if (ret) + goto err_free_orinocodev; + + return 0; + +err_free_orinocodev: + free_orinocodev(priv); + return ret; +}
static void spectrum_cs_detach(struct pcmcia_device *link) {
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 67a81d911c01225f426cc6bee2373df044c1a9b7 ]
Should orinoco_cs_config() fail, some resources need to be released as already done in the remove function.
While at it, remove a useless and erroneous comment. The probe is orinoco_cs_probe(), not orinoco_cs_attach().
Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/e24735ce4d82901d5f7ea08419eea53bfdde3d65.168456828... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intersil/orinoco/orinoco_cs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_cs.c b/drivers/net/wireless/intersil/orinoco/orinoco_cs.c index a956f965a1e5e..03bfd2482656c 100644 --- a/drivers/net/wireless/intersil/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_cs.c @@ -96,6 +96,7 @@ orinoco_cs_probe(struct pcmcia_device *link) { struct orinoco_private *priv; struct orinoco_pccard *card; + int ret;
priv = alloc_orinocodev(sizeof(*card), &link->dev, orinoco_cs_hard_reset, NULL); @@ -107,8 +108,16 @@ orinoco_cs_probe(struct pcmcia_device *link) card->p_dev = link; link->priv = priv;
- return orinoco_cs_config(link); -} /* orinoco_cs_attach */ + ret = orinoco_cs_config(link); + if (ret) + goto err_free_orinocodev; + + return 0; + +err_free_orinocodev: + free_orinocodev(priv); + return ret; +}
static void orinoco_cs_detach(struct pcmcia_device *link) {
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 6b92e4351a29af52c285fe235e6e4d1a75de04b2 ]
Should atmel_config() fail, some resources need to be released as already done in the remove function.
While at it, remove a useless and erroneous comment. The probe is atmel_probe(), not atmel_attach().
Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/1e65f174607a83348034197fa7d603bab10ba4a9.168456915... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/atmel/atmel_cs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/atmel/atmel_cs.c b/drivers/net/wireless/atmel/atmel_cs.c index 453bb84cb3386..58bba9875d366 100644 --- a/drivers/net/wireless/atmel/atmel_cs.c +++ b/drivers/net/wireless/atmel/atmel_cs.c @@ -72,6 +72,7 @@ struct local_info { static int atmel_probe(struct pcmcia_device *p_dev) { struct local_info *local; + int ret;
dev_dbg(&p_dev->dev, "atmel_attach()\n");
@@ -82,8 +83,16 @@ static int atmel_probe(struct pcmcia_device *p_dev)
p_dev->priv = local;
- return atmel_config(p_dev); -} /* atmel_attach */ + ret = atmel_config(p_dev); + if (ret) + goto err_free_priv; + + return 0; + +err_free_priv: + kfree(p_dev->priv); + return ret; +}
static void atmel_detach(struct pcmcia_device *link) {
From: Jakub Kicinski kuba@kernel.org
[ Upstream commit 18774612246d036c04ce9fee7f67192f96f48725 ]
Commit 406f42fa0d3c ("net-next: When a bond have a massive amount of VLANs...") introduced a rbtree for faster Ethernet address look up. To maintain netdev->dev_addr in this tree we need to make all the writes to it got through appropriate helpers.
Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211018235021.1279697-15-kuba@kernel.org Stable-dep-of: 391af06a02e7 ("wifi: wl3501_cs: Fix an error handling path in wl3501_probe()") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/wl3501_cs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index cb71b73853f4e..7351a2c127adc 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -1945,8 +1945,7 @@ static int wl3501_config(struct pcmcia_device *link) goto failed; }
- for (i = 0; i < 6; i++) - dev->dev_addr[i] = ((char *)&this->mac_addr)[i]; + eth_hw_addr_set(dev, this->mac_addr);
/* print probe information */ printk(KERN_INFO "%s: wl3501 @ 0x%3.3x, IRQ %d, "
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 391af06a02e7642039ac5f6c4b2c034ab0992b5d ]
Should wl3501_config() fail, some resources need to be released as already done in the remove function.
Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/7cc9c9316489b7d69b36aeb0edd3123538500b41.168456986... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/wl3501_cs.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
--- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -1862,6 +1862,7 @@ static int wl3501_probe(struct pcmcia_de { struct net_device *dev; struct wl3501_card *this; + int ret;
/* The io structure describes IO port mapping */ p_dev->resource[0]->end = 16; @@ -1873,8 +1874,7 @@ static int wl3501_probe(struct pcmcia_de
dev = alloc_etherdev(sizeof(struct wl3501_card)); if (!dev) - goto out_link; - + return -ENOMEM;
dev->netdev_ops = &wl3501_netdev_ops; dev->watchdog_timeo = 5 * HZ; @@ -1887,9 +1887,15 @@ static int wl3501_probe(struct pcmcia_de netif_stop_queue(dev); p_dev->priv = dev;
- return wl3501_config(p_dev); -out_link: - return -ENOMEM; + ret = wl3501_config(p_dev); + if (ret) + goto out_free_etherdev; + + return 0; + +out_free_etherdev: + free_netdev(dev); + return ret; }
static int wl3501_config(struct pcmcia_device *link)
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 9e8e9187673cb24324f9165dd47b2b28f60b0b10 ]
Instead of doing simple operations and using an additional variable on stack, utilize strnlen() and reuse len variable.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220603164414.48436-1-andriy.shevchenko@linux.int... Stable-dep-of: 4f8d66a9fb2e ("wifi: ray_cs: Fix an error handling path in ray_probe()") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ray_cs.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index f8409e93fe33e..98741b06707b6 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -1643,31 +1643,29 @@ static void authenticate_timeout(struct timer_list *t) /*===========================================================================*/ static int parse_addr(char *in_str, UCHAR *out) { + int i, k; int len; - int i, j, k; int status;
if (in_str == NULL) return 0; - if ((len = strlen(in_str)) < 2) + len = strnlen(in_str, ADDRLEN * 2 + 1) - 1; + if (len < 1) return 0; memset(out, 0, ADDRLEN);
status = 1; - j = len - 1; - if (j > 12) - j = 12; i = 5;
- while (j > 0) { - if ((k = hex_to_bin(in_str[j--])) != -1) + while (len > 0) { + if ((k = hex_to_bin(in_str[len--])) != -1) out[i] = k; else return 0;
- if (j == 0) + if (len == 0) break; - if ((k = hex_to_bin(in_str[j--])) != -1) + if ((k = hex_to_bin(in_str[len--])) != -1) out[i] += k << 4; else return 0;
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 4dfc63c002a555a2c3c34d89009532ad803be876 ]
The status variable assigned only once and used also only once. Replace it's usage by actual value.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220603164414.48436-2-andriy.shevchenko@linux.int... Stable-dep-of: 4f8d66a9fb2e ("wifi: ray_cs: Fix an error handling path in ray_probe()") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ray_cs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 98741b06707b6..81e0945fa443d 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -1645,7 +1645,6 @@ static int parse_addr(char *in_str, UCHAR *out) { int i, k; int len; - int status;
if (in_str == NULL) return 0; @@ -1654,7 +1653,6 @@ static int parse_addr(char *in_str, UCHAR *out) return 0; memset(out, 0, ADDRLEN);
- status = 1; i = 5;
while (len > 0) { @@ -1672,7 +1670,7 @@ static int parse_addr(char *in_str, UCHAR *out) if (!i--) break; } - return status; + return 1; }
/*===========================================================================*/
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 4f8d66a9fb2edcd05c1e563456a55a08910bfb37 ]
Should ray_config() fail, some resources need to be released as already done in the remove function.
While at it, remove a useless and erroneous comment. The probe is ray_probe(), not ray_attach().
Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/8c544d18084f8b37dd108e844f7e79e85ff708ff.168457037... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ray_cs.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 81e0945fa443d..96330a6c066be 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -270,13 +270,14 @@ static int ray_probe(struct pcmcia_device *p_dev) { ray_dev_t *local; struct net_device *dev; + int ret;
dev_dbg(&p_dev->dev, "ray_attach()\n");
/* Allocate space for private device-specific data */ dev = alloc_etherdev(sizeof(ray_dev_t)); if (!dev) - goto fail_alloc_dev; + return -ENOMEM;
local = netdev_priv(dev); local->finder = p_dev; @@ -313,11 +314,16 @@ static int ray_probe(struct pcmcia_device *p_dev) timer_setup(&local->timer, NULL, 0);
this_device = p_dev; - return ray_config(p_dev); + ret = ray_config(p_dev); + if (ret) + goto err_free_dev; + + return 0;
-fail_alloc_dev: - return -ENOMEM; -} /* ray_attach */ +err_free_dev: + free_netdev(dev); + return ret; +}
static void ray_detach(struct pcmcia_device *link) {
From: Fedor Pchelkin pchelkin@ispras.ru
[ Upstream commit 061b0cb9327b80d7a0f63a33e7c3e2a91a71f142 ]
A bad USB device is able to construct a service connection response message with target endpoint being ENDPOINT0 which is reserved for HTC_CTRL_RSVD_SVC and should not be modified to be used for any other services.
Reject such service connection responses.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.") Reported-by: syzbot+b68fbebe56d8362907e8@syzkaller.appspotmail.com Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Acked-by: Toke Høiland-Jørgensen toke@toke.dk Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230516150427.79469-1-pchelkin@ispras.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/htc_hst.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index fe62ff668f757..99667aba289df 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -114,7 +114,13 @@ static void htc_process_conn_rsp(struct htc_target *target,
if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) { epid = svc_rspmsg->endpoint_id; - if (epid < 0 || epid >= ENDPOINT_MAX) + + /* Check that the received epid for the endpoint to attach + * a new service is valid. ENDPOINT0 can't be used here as it + * is already reserved for HTC_CTRL_RSVD_SVC service and thus + * should not be modified. + */ + if (epid <= ENDPOINT0 || epid >= ENDPOINT_MAX) return;
service_id = be16_to_cpu(svc_rspmsg->service_id);
From: Jesper Dangaard Brouer brouer@redhat.com
[ Upstream commit 095641817e1bf6aa2560e025e47575188ee3edaf ]
Dan Carpenter found via Smatch static checker, that unsigned 'mtu_lo' is never less than zero.
Variable mtu_lo should have been an 'int', because read_mtu_device_lo() uses minus as error indications.
Fixes: b62eba563229 ("selftests/bpf: Tests using bpf_check_mtu BPF-helper") Reported-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Jesper Dangaard Brouer brouer@redhat.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Simon Horman simon.horman@corigine.com Link: https://lore.kernel.org/bpf/168605104733.3636467.17945947801753092590.stgit@... Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/prog_tests/check_mtu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/check_mtu.c b/tools/testing/selftests/bpf/prog_tests/check_mtu.c index 012068f33a0a8..871971cdd7b75 100644 --- a/tools/testing/selftests/bpf/prog_tests/check_mtu.c +++ b/tools/testing/selftests/bpf/prog_tests/check_mtu.c @@ -197,7 +197,7 @@ static void test_check_mtu_tc(__u32 mtu, __u32 ifindex)
void test_check_mtu(void) { - __u32 mtu_lo; + int mtu_lo;
if (test__start_subtest("bpf_check_mtu XDP-attach")) test_check_mtu_xdp_attach();
From: Marek Vasut marex@denx.de
[ Upstream commit b241e260820b68c09586e8a0ae0fc23c0e3215bd ]
In case WoWlan was never configured during the operation of the system, the hw->wiphy->wowlan_config will be NULL. rsi_config_wowlan() checks whether wowlan_config is non-NULL and if it is not, then WARNs about it. The warning is valid, as during normal operation the rsi_config_wowlan() should only ever be called with non-NULL wowlan_config. In shutdown this rsi_config_wowlan() should only ever be called if WoWlan was configured before by the user.
Add checks for non-NULL wowlan_config into the shutdown hook. While at it, check whether the wiphy is also non-NULL before accessing wowlan_config . Drop the single-use wowlan_config variable, just inline it into function call.
Fixes: 16bbc3eb8372 ("rsi: fix null pointer dereference during rsi_shutdown()") Signed-off-by: Marek Vasut marex@denx.de Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230527222833.273741-1-marex@denx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/rsi/rsi_91x_sdio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c index 9f16128e4ffab..3952c8baba181 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -1463,10 +1463,8 @@ static void rsi_shutdown(struct device *dev)
rsi_dbg(ERR_ZONE, "SDIO Bus shutdown =====>\n");
- if (hw) { - struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config; - - if (rsi_config_wowlan(adapter, wowlan)) + if (hw && hw->wiphy && hw->wiphy->wowlan_config) { + if (rsi_config_wowlan(adapter, hw->wiphy->wowlan_config)) rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n"); }
From: Marek Vasut marex@denx.de
[ Upstream commit e74f562328b03fbe9cf438f958464dff3a644dfc ]
It makes no sense to set MMC_PM_KEEP_POWER in shutdown. The flag indicates to the MMC subsystem to keep the slot powered on during suspend, but in shutdown the slot should actually be powered off. Drop this call.
Fixes: 063848c3e155 ("rsi: sdio: Add WOWLAN support for S5 shutdown state") Signed-off-by: Marek Vasut marex@denx.de Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230527222859.273768-1-marex@denx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/rsi/rsi_91x_sdio.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c index 3952c8baba181..670de56c69a26 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -1479,9 +1479,6 @@ static void rsi_shutdown(struct device *dev) if (sdev->write_fail) rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n");
- if (rsi_set_sdio_pm_caps(adapter)) - rsi_dbg(INFO_ZONE, "Setting power management caps failed\n"); - rsi_dbg(INFO_ZONE, "***** RSI module shut down *****\n"); }
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 5e008df11c55228a86a1bae692cc2002503572c9 ]
Patch series "watchdog/hardlockup: Add the buddy hardlockup detector", v5.
This patch series adds the "buddy" hardlockup detector. In brief, the buddy hardlockup detector can detect hardlockups without arch-level support by having CPUs checkup on a "buddy" CPU periodically.
Given the new design of this patch series, testing all combinations is fairly difficult. I've attempted to make sure that all combinations of CONFIG_ options are good, but it wouldn't surprise me if I missed something. I apologize in advance and I'll do my best to fix any problems that are found.
This patch (of 18):
The real watchdog_update_hrtimer_threshold() is defined in kernel/watchdog_hld.c. That file is included if CONFIG_HARDLOCKUP_DETECTOR_PERF and the function is defined in that file if CONFIG_HARDLOCKUP_CHECK_TIMESTAMP.
The dummy version of the function in "nmi.h" didn't get that quite right. While this doesn't appear to be a huge deal, it's nice to make it consistent.
It doesn't break builds because CHECK_TIMESTAMP is only defined by x86 so others don't get a double definition, and x86 uses perf lockup detector, so it gets the out of line version.
Link: https://lkml.kernel.org/r/20230519101840.v5.18.Ia44852044cdcb074f387e80df6b4... Link: https://lkml.kernel.org/r/20230519101840.v5.1.I8cbb2f4fa740528fcfade4f5439b6... Fixes: 7edaeb6841df ("kernel/watchdog: Prevent false positives with turbo modes") Signed-off-by: Douglas Anderson dianders@chromium.org Reviewed-by: Nicholas Piggin npiggin@gmail.com Reviewed-by: Petr Mladek pmladek@suse.com Cc: Andi Kleen ak@linux.intel.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Chen-Yu Tsai wens@csie.org Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Daniel Thompson daniel.thompson@linaro.org Cc: "David S. Miller" davem@davemloft.net Cc: Guenter Roeck groeck@chromium.org Cc: Ian Rogers irogers@google.com Cc: Lecopzer Chen lecopzer.chen@mediatek.com Cc: Marc Zyngier maz@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Masayoshi Mizuma msys.mizuma@gmail.com Cc: Matthias Kaehlcke mka@chromium.org Cc: Michael Ellerman mpe@ellerman.id.au Cc: Pingfan Liu kernelfans@gmail.com Cc: Randy Dunlap rdunlap@infradead.org Cc: "Ravi V. Shankar" ravi.v.shankar@intel.com Cc: Ricardo Neri ricardo.neri@intel.com Cc: Stephane Eranian eranian@google.com Cc: Stephen Boyd swboyd@chromium.org Cc: Sumit Garg sumit.garg@linaro.org Cc: Tzung-Bi Shih tzungbi@chromium.org Cc: Will Deacon will@kernel.org Cc: Colin Cross ccross@android.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/nmi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/nmi.h b/include/linux/nmi.h index f700ff2df074e..0db377ff8f608 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -197,7 +197,7 @@ u64 hw_nmi_get_sample_period(int watchdog_thresh); #endif
#if defined(CONFIG_HARDLOCKUP_CHECK_TIMESTAMP) && \ - defined(CONFIG_HARDLOCKUP_DETECTOR) + defined(CONFIG_HARDLOCKUP_DETECTOR_PERF) void watchdog_update_hrtimer_threshold(u64 period); #else static inline void watchdog_update_hrtimer_threshold(u64 period) { }
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 4379e59fe5665cfda737e45b8bf2f05321ef049c ]
Currently, in the watchdog_overflow_callback() we first check to see if the watchdog had been touched and _then_ we handle the workaround for turbo mode. This order should be reversed.
Specifically, "touching" the hardlockup detector's watchdog should avoid lockups being detected for one period that should be roughly the same regardless of whether we're running turbo or not. That means that we should do the extra accounting for turbo _before_ we look at (and clear) the global indicating that we've been touched.
NOTE: this fix is made based on code inspection. I am not aware of any reports where the old code would have generated false positives. That being said, this order seems more correct and also makes it easier down the line to share code with the "buddy" hardlockup detector.
Link: https://lkml.kernel.org/r/20230519101840.v5.2.I843b0d1de3e096ba111a179f3adb1... Fixes: 7edaeb6841df ("kernel/watchdog: Prevent false positives with turbo modes") Signed-off-by: Douglas Anderson dianders@chromium.org Cc: Andi Kleen ak@linux.intel.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Chen-Yu Tsai wens@csie.org Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Colin Cross ccross@android.com Cc: Daniel Thompson daniel.thompson@linaro.org Cc: "David S. Miller" davem@davemloft.net Cc: Guenter Roeck groeck@chromium.org Cc: Ian Rogers irogers@google.com Cc: Lecopzer Chen lecopzer.chen@mediatek.com Cc: Marc Zyngier maz@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Masayoshi Mizuma msys.mizuma@gmail.com Cc: Matthias Kaehlcke mka@chromium.org Cc: Michael Ellerman mpe@ellerman.id.au Cc: Nicholas Piggin npiggin@gmail.com Cc: Petr Mladek pmladek@suse.com Cc: Pingfan Liu kernelfans@gmail.com Cc: Randy Dunlap rdunlap@infradead.org Cc: "Ravi V. Shankar" ravi.v.shankar@intel.com Cc: Ricardo Neri ricardo.neri@intel.com Cc: Stephane Eranian eranian@google.com Cc: Stephen Boyd swboyd@chromium.org Cc: Sumit Garg sumit.garg@linaro.org Cc: Tzung-Bi Shih tzungbi@chromium.org Cc: Will Deacon will@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/watchdog_hld.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c index 247bf0b1582ca..1e8a49dc956e2 100644 --- a/kernel/watchdog_hld.c +++ b/kernel/watchdog_hld.c @@ -114,14 +114,14 @@ static void watchdog_overflow_callback(struct perf_event *event, /* Ensure the watchdog never gets throttled */ event->hw.interrupts = 0;
+ if (!watchdog_check_timestamp()) + return; + if (__this_cpu_read(watchdog_nmi_touch) == true) { __this_cpu_write(watchdog_nmi_touch, false); return; }
- if (!watchdog_check_timestamp()) - return; - /* check for a hardlockup * This is done by making sure our timer interrupt * is incrementing. The timer interrupt should have
From: Zhen Lei thunder.leizhen@huawei.com
[ Upstream commit 1cba6c4309f03de570202c46f03df3f73a0d4c82 ]
Patch series "kexec: enable kexec_crash_size to support two crash kernel regions".
When crashkernel=X fails to reserve region under 4G, it will fall back to reserve region above 4G and a region of the default size will also be reserved under 4G. Unfortunately, /sys/kernel/kexec_crash_size only supports one crash kernel region now, the user cannot sense the low memory reserved by reading /sys/kernel/kexec_crash_size. Also, low memory cannot be freed by writing this file.
For example: resource_size(crashk_res) = 512M resource_size(crashk_low_res) = 256M
The result of 'cat /sys/kernel/kexec_crash_size' is 512M, but it should be 768M. When we execute 'echo 0 > /sys/kernel/kexec_crash_size', the size of crashk_res becomes 0 and resource_size(crashk_low_res) is still 256 MB, which is incorrect.
Since crashk_res manages the memory with high address and crashk_low_res manages the memory with low address, crashk_low_res is shrunken only when all crashk_res is shrunken. And because when there is only one crash kernel region, crashk_res is always used. Therefore, if all crashk_res is shrunken and crashk_low_res still exists, swap them.
This patch (of 6):
If the value of parameter 'new_size' is in the semi-open and semi-closed interval (crashk_res.end - KEXEC_CRASH_MEM_ALIGN + 1, crashk_res.end], the calculation result of ram_res is:
ram_res->start = crashk_res.end + 1 ram_res->end = crashk_res.end
The operation of insert_resource() fails, and ram_res is not added to iomem_resource. As a result, the memory of the control block ram_res is leaked.
In fact, on all architectures, the start address and size of crashk_res are already aligned by KEXEC_CRASH_MEM_ALIGN. Therefore, we do not need to round up crashk_res.start again. Instead, we should round up 'new_size' in advance.
Link: https://lkml.kernel.org/r/20230527123439.772-1-thunder.leizhen@huawei.com Link: https://lkml.kernel.org/r/20230527123439.772-2-thunder.leizhen@huawei.com Fixes: 6480e5a09237 ("kdump: add missing RAM resource in crash_shrink_memory()") Fixes: 06a7f711246b ("kexec: premit reduction of the reserved memory size") Signed-off-by: Zhen Lei thunder.leizhen@huawei.com Acked-by: Baoquan He bhe@redhat.com Cc: Cong Wang amwang@redhat.com Cc: Eric W. Biederman ebiederm@xmission.com Cc: Michael Holzheu holzheu@linux.vnet.ibm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/kexec_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index bdc2d952911ce..7e735fd338586 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -1029,6 +1029,7 @@ int crash_shrink_memory(unsigned long new_size) start = crashk_res.start; end = crashk_res.end; old_size = (end == 0) ? 0 : end - start + 1; + new_size = roundup(new_size, KEXEC_CRASH_MEM_ALIGN); if (new_size >= old_size) { ret = (new_size == old_size) ? 0 : -EINVAL; goto unlock; @@ -1040,9 +1041,7 @@ int crash_shrink_memory(unsigned long new_size) goto unlock; }
- start = roundup(start, KEXEC_CRASH_MEM_ALIGN); - end = roundup(start + new_size, KEXEC_CRASH_MEM_ALIGN); - + end = start + new_size; crash_free_reserved_phys_range(end, crashk_res.end);
if ((start == end) && (crashk_res.parent != NULL))
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 434587df9f7fd68575f99a889cc5f2efc2eaee5e ]
There are no other files referencing this function, apparently it was left global to avoid an 'unused function' warning when the only caller is left out. With a 'W=1' build, it causes a 'missing prototype' warning though:
drivers/memstick/host/r592.c:47:13: error: no previous prototype for 'memstick_debug_get_tpc_name' [-Werror=missing-prototypes]
Annotate the function as 'static __maybe_unused' to avoid both problems.
Fixes: 926341250102 ("memstick: add driver for Ricoh R5C592 card reader") Signed-off-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20230516202714.560929-1-arnd@kernel.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memstick/host/r592.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index 42bfc46842b82..461f5ffd02bc1 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c @@ -44,12 +44,10 @@ static const char *tpc_names[] = { * memstick_debug_get_tpc_name - debug helper that returns string for * a TPC number */ -const char *memstick_debug_get_tpc_name(int tpc) +static __maybe_unused const char *memstick_debug_get_tpc_name(int tpc) { return tpc_names[tpc-1]; } -EXPORT_SYMBOL(memstick_debug_get_tpc_name); -
/* Read a register*/ static inline u32 r592_read_reg(struct r592_device *dev, int address)
From: Remi Pommarel repk@triplefau.lt
[ Upstream commit 75086cc6dee046e3fbb3dba148b376d8802f83bc ]
On EDMA capable hardware, ath9k_txq_list_has_key() can enter infinite loop if it is called while all txq_fifos have packets that use different key that the one we are looking for. Fix it by exiting the loop if all txq_fifos have been checked already.
Because this loop is called under spin_lock_bh() (see ath_txq_lock) it causes the following rcu stall:
rcu: INFO: rcu_sched self-detected stall on CPU ath10k_pci 0000:01:00.0: failed to read temperature -11 rcu: 1-....: (5254 ticks this GP) idle=189/1/0x4000000000000002 softirq=8442983/8442984 fqs=2579 (t=5257 jiffies g=17983297 q=334) Task dump for CPU 1: task:hostapd state:R running task stack: 0 pid: 297 ppid: 289 flags:0x0000000a Call trace: dump_backtrace+0x0/0x170 show_stack+0x1c/0x24 sched_show_task+0x140/0x170 dump_cpu_task+0x48/0x54 rcu_dump_cpu_stacks+0xf0/0x134 rcu_sched_clock_irq+0x8d8/0x9fc update_process_times+0xa0/0xec tick_sched_timer+0x5c/0xd0 __hrtimer_run_queues+0x154/0x320 hrtimer_interrupt+0x120/0x2f0 arch_timer_handler_virt+0x38/0x44 handle_percpu_devid_irq+0x9c/0x1e0 handle_domain_irq+0x64/0x90 gic_handle_irq+0x78/0xb0 call_on_irq_stack+0x28/0x38 do_interrupt_handler+0x54/0x5c el1_interrupt+0x2c/0x4c el1h_64_irq_handler+0x14/0x1c el1h_64_irq+0x74/0x78 ath9k_txq_has_key+0x1bc/0x250 [ath9k] ath9k_set_key+0x1cc/0x3dc [ath9k] drv_set_key+0x78/0x170 ieee80211_key_replace+0x564/0x6cc ieee80211_key_link+0x174/0x220 ieee80211_add_key+0x11c/0x300 nl80211_new_key+0x12c/0x330 genl_family_rcv_msg_doit+0xbc/0x11c genl_rcv_msg+0xd8/0x1c4 netlink_rcv_skb+0x40/0x100 genl_rcv+0x3c/0x50 netlink_unicast+0x1ec/0x2c0 netlink_sendmsg+0x198/0x3c0 ____sys_sendmsg+0x210/0x250 ___sys_sendmsg+0x78/0xc4 __sys_sendmsg+0x4c/0x90 __arm64_sys_sendmsg+0x28/0x30 invoke_syscall.constprop.0+0x60/0x100 do_el0_svc+0x48/0xd0 el0_svc+0x14/0x50 el0t_64_sync_handler+0xa8/0xb0 el0t_64_sync+0x158/0x15c
This rcu stall is hard to reproduce as is, but changing ATH_TXFIFO_DEPTH from 8 to 2 makes it reasonably easy to reproduce.
Fixes: ca2848022c12 ("ath9k: Postpone key cache entry deletion for TXQ frames reference it") Signed-off-by: Remi Pommarel repk@triplefau.lt Tested-by: Nicolas Escande nico.escande@gmail.com Acked-by: Toke Høiland-Jørgensen toke@toke.dk Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230609093744.1985-1-repk@triplefau.lt Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e2791d45f5f59..98868f60a8c2f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -850,7 +850,7 @@ static bool ath9k_txq_list_has_key(struct list_head *txq_list, u32 keyix) static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix) { struct ath_hw *ah = sc->sc_ah; - int i; + int i, j; struct ath_txq *txq; bool key_in_use = false;
@@ -868,8 +868,9 @@ static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix) if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { int idx = txq->txq_tailidx;
- while (!key_in_use && - !list_empty(&txq->txq_fifo[idx])) { + for (j = 0; !key_in_use && + !list_empty(&txq->txq_fifo[idx]) && + j < ATH_TXFIFO_DEPTH; j++) { key_in_use = ath9k_txq_list_has_key( &txq->txq_fifo[idx], keyix); INCR(idx, ATH_TXFIFO_DEPTH);
From: Edwin Peer edwin.peer@broadcom.com
[ Upstream commit fa0e21fa44438a0e856d42224bfa24641d37b979 ]
This filter already exists for excluding IPv6 SNMP stats. Extend its definition to also exclude IFLA_VF_INFO stats in RTM_GETLINK.
This patch constitutes a partial fix for a netlink attribute nesting overflow bug in IFLA_VFINFO_LIST. By excluding the stats when the requester doesn't need them, the truncation of the VF list is avoided.
While it was technically only the stats added in commit c5a9f6f0ab40 ("net/core: Add drop counters to VF statistics") breaking the camel's back, the appreciable size of the stats data should never have been included without due consideration for the maximum number of VFs supported by PCI.
Fixes: 3b766cd83232 ("net/core: Add reading VF statistics through the PF netdevice") Fixes: c5a9f6f0ab40 ("net/core: Add drop counters to VF statistics") Signed-off-by: Edwin Peer edwin.peer@broadcom.com Cc: Edwin Peer espeer@gmail.com Signed-off-by: Gal Pressman gal@nvidia.com Link: https://lore.kernel.org/r/20230611105108.122586-1-gal@nvidia.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/rtnetlink.c | 96 +++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 45 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index bc187289bf64b..0ab558501290b 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -922,24 +922,27 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, nla_total_size(sizeof(struct ifla_vf_rate)) + nla_total_size(sizeof(struct ifla_vf_link_state)) + nla_total_size(sizeof(struct ifla_vf_rss_query_en)) + - nla_total_size(0) + /* nest IFLA_VF_STATS */ - /* IFLA_VF_STATS_RX_PACKETS */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_TX_PACKETS */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_RX_BYTES */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_TX_BYTES */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_BROADCAST */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_MULTICAST */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_RX_DROPPED */ - nla_total_size_64bit(sizeof(__u64)) + - /* IFLA_VF_STATS_TX_DROPPED */ - nla_total_size_64bit(sizeof(__u64)) + nla_total_size(sizeof(struct ifla_vf_trust))); + if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) { + size += num_vfs * + (nla_total_size(0) + /* nest IFLA_VF_STATS */ + /* IFLA_VF_STATS_RX_PACKETS */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_TX_PACKETS */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_RX_BYTES */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_TX_BYTES */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_BROADCAST */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_MULTICAST */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_RX_DROPPED */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_TX_DROPPED */ + nla_total_size_64bit(sizeof(__u64))); + } return size; } else return 0; @@ -1214,7 +1217,8 @@ static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb, static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb, struct net_device *dev, int vfs_num, - struct nlattr *vfinfo) + struct nlattr *vfinfo, + u32 ext_filter_mask) { struct ifla_vf_rss_query_en vf_rss_query_en; struct nlattr *vf, *vfstats, *vfvlanlist; @@ -1320,33 +1324,35 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb, goto nla_put_vf_failure; } nla_nest_end(skb, vfvlanlist); - memset(&vf_stats, 0, sizeof(vf_stats)); - if (dev->netdev_ops->ndo_get_vf_stats) - dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num, - &vf_stats); - vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS); - if (!vfstats) - goto nla_put_vf_failure; - if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS, - vf_stats.rx_packets, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS, - vf_stats.tx_packets, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES, - vf_stats.rx_bytes, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES, - vf_stats.tx_bytes, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST, - vf_stats.broadcast, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST, - vf_stats.multicast, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED, - vf_stats.rx_dropped, IFLA_VF_STATS_PAD) || - nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED, - vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) { - nla_nest_cancel(skb, vfstats); - goto nla_put_vf_failure; + if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) { + memset(&vf_stats, 0, sizeof(vf_stats)); + if (dev->netdev_ops->ndo_get_vf_stats) + dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num, + &vf_stats); + vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS); + if (!vfstats) + goto nla_put_vf_failure; + if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS, + vf_stats.rx_packets, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS, + vf_stats.tx_packets, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES, + vf_stats.rx_bytes, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES, + vf_stats.tx_bytes, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST, + vf_stats.broadcast, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST, + vf_stats.multicast, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED, + vf_stats.rx_dropped, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED, + vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) { + nla_nest_cancel(skb, vfstats); + goto nla_put_vf_failure; + } + nla_nest_end(skb, vfstats); } - nla_nest_end(skb, vfstats); nla_nest_end(skb, vf); return 0;
@@ -1379,7 +1385,7 @@ static noinline_for_stack int rtnl_fill_vf(struct sk_buff *skb, return -EMSGSIZE;
for (i = 0; i < num_vfs; i++) { - if (rtnl_fill_vfinfo(skb, dev, i, vfinfo)) + if (rtnl_fill_vfinfo(skb, dev, i, vfinfo, ext_filter_mask)) return -EMSGSIZE; }
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 96fb6f47db24a712d650b0a9b9074873f273fb0e ]
In mac80211, it's required that we pull from TXQs by calling ieee80211_tx_dequeue() only with softirqs disabled. However, in iwl_mvm_queue_state_change() we're often called with them enabled, e.g. from flush if anything was flushed, triggering a mac80211 warning.
Fix that by disabling the softirqs across the TX call.
Fixes: cfbc6c4c5b91 ("iwlwifi: mvm: support mac80211 TXQs model") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230614123446.0feef7fa81db.I4dd62542d955b40dd8f0a... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 3ee4b3ecd0c82..01f65c9789e72 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1309,8 +1309,11 @@ static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode, else set_bit(IWL_MVM_TXQ_STATE_STOP_FULL, &mvmtxq->state);
- if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST) + if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST) { + local_bh_disable(); iwl_mvm_mac_itxq_xmit(mvm->hw, txq); + local_bh_enable(); + } }
out:
From: Emmanuel Grumbach emmanuel.grumbach@intel.com
[ Upstream commit 91ca9c3ade1be665f5ce88594ee687c56b0357d5 ]
It is yet unclear if the WARNING really points to a real problem, but for sure the stack dump doesn't help fixing it. Just use a regular error print instead.
Signed-off-by: Emmanuel Grumbach emmanuel.grumbach@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20220205112029.a79e733a12f7.I8189344294222... Signed-off-by: Luca Coelho luciano.coelho@intel.com Stable-dep-of: 1902f1953b8b ("wifi: iwlwifi: pcie: fix NULL pointer dereference in iwl_pcie_irq_rx_msix_handler()") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index fea89330f692c..8885b19fd8de6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1608,10 +1608,13 @@ irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id) if (WARN_ON(entry->entry >= trans->num_rx_queues)) return IRQ_NONE;
- if (WARN_ONCE(!rxq, - "[%d] Got MSI-X interrupt before we have Rx queues", - entry->entry)) + if (!rxq) { + if (net_ratelimit()) + IWL_ERR(trans, + "[%d] Got MSI-X interrupt before we have Rx queues\n", + entry->entry); return IRQ_NONE; + }
lock_map_acquire(&trans->sync_cmd_lockdep_map); IWL_DEBUG_ISR(trans, "[%d] Got interrupt\n", entry->entry);
From: Anjaneyulu pagadala.yesu.anjaneyulu@intel.com
[ Upstream commit 1902f1953b8ba100ee8705cb8a6f1a9795550eca ]
rxq can be NULL only when trans_pcie->rxq is NULL and entry->entry is zero. For the case when entry->entry is not equal to 0, rxq won't be NULL even if trans_pcie->rxq is NULL. Modify checker to check for trans_pcie->rxq.
Fixes: abc599efa67b ("iwlwifi: pcie: don't crash when rx queues aren't allocated in interrupt") Signed-off-by: Anjaneyulu pagadala.yesu.anjaneyulu@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230614123446.5a5eb3889a4a.I375a1d58f16b48cd2044e... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 8885b19fd8de6..6c6512158813b 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1601,14 +1601,14 @@ irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id) struct msix_entry *entry = dev_id; struct iwl_trans_pcie *trans_pcie = iwl_pcie_get_trans_pcie(entry); struct iwl_trans *trans = trans_pcie->trans; - struct iwl_rxq *rxq = &trans_pcie->rxq[entry->entry]; + struct iwl_rxq *rxq;
trace_iwlwifi_dev_irq_msix(trans->dev, entry, false, 0, 0);
if (WARN_ON(entry->entry >= trans->num_rx_queues)) return IRQ_NONE;
- if (!rxq) { + if (!trans_pcie->rxq) { if (net_ratelimit()) IWL_ERR(trans, "[%d] Got MSI-X interrupt before we have Rx queues\n", @@ -1616,6 +1616,7 @@ irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id) return IRQ_NONE; }
+ rxq = &trans_pcie->rxq[entry->entry]; lock_map_acquire(&trans->sync_cmd_lockdep_map); IWL_DEBUG_ISR(trans, "[%d] Got interrupt\n", entry->entry);
From: Benjamin Berg benjamin.berg@intel.com
[ Upstream commit dfd9aa3e7a456d57b18021d66472ab7ff8373ab7 ]
The cfg80211_gen_new_ie function merges the IEs using inheritance rules. Rewrite this function to fix issues around inheritance rules. In particular, vendor elements do not require any special handling, as they are either all inherited or overridden by the subprofile. Also, add fragmentation handling as this may be needed in some cases.
This also changes the function to not require making a copy. The new version could be optimized a bit by explicitly tracking which IEs have been handled already rather than looking that up again every time.
Note that a small behavioural change is the removal of the SSID special handling. This should be fine for the MBSSID element, as the SSID must be included in the subelement.
Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") Signed-off-by: Benjamin Berg benjamin.berg@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230616094949.bc6152e146db.I2b5f3bc45085e1901e5b5... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/scan.c | 213 ++++++++++++++++++++++++++------------------ 1 file changed, 124 insertions(+), 89 deletions(-)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index ef31e401d7914..a565476809f02 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -262,117 +262,152 @@ bool cfg80211_is_element_inherited(const struct element *elem, } EXPORT_SYMBOL(cfg80211_is_element_inherited);
-static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen, - const u8 *subelement, size_t subie_len, - u8 *new_ie, gfp_t gfp) +static size_t cfg80211_copy_elem_with_frags(const struct element *elem, + const u8 *ie, size_t ie_len, + u8 **pos, u8 *buf, size_t buf_len) { - u8 *pos, *tmp; - const u8 *tmp_old, *tmp_new; - const struct element *non_inherit_elem; - u8 *sub_copy; + if (WARN_ON((u8 *)elem < ie || elem->data > ie + ie_len || + elem->data + elem->datalen > ie + ie_len)) + return 0;
- /* copy subelement as we need to change its content to - * mark an ie after it is processed. - */ - sub_copy = kmemdup(subelement, subie_len, gfp); - if (!sub_copy) + if (elem->datalen + 2 > buf + buf_len - *pos) return 0;
- pos = &new_ie[0]; + memcpy(*pos, elem, elem->datalen + 2); + *pos += elem->datalen + 2;
- /* set new ssid */ - tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len); - if (tmp_new) { - memcpy(pos, tmp_new, tmp_new[1] + 2); - pos += (tmp_new[1] + 2); + /* Finish if it is not fragmented */ + if (elem->datalen != 255) + return *pos - buf; + + ie_len = ie + ie_len - elem->data - elem->datalen; + ie = (const u8 *)elem->data + elem->datalen; + + for_each_element(elem, ie, ie_len) { + if (elem->id != WLAN_EID_FRAGMENT) + break; + + if (elem->datalen + 2 > buf + buf_len - *pos) + return 0; + + memcpy(*pos, elem, elem->datalen + 2); + *pos += elem->datalen + 2; + + if (elem->datalen != 255) + break; }
- /* get non inheritance list if exists */ - non_inherit_elem = - cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, - sub_copy, subie_len); + return *pos - buf; +}
- /* go through IEs in ie (skip SSID) and subelement, - * merge them into new_ie +static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen, + const u8 *subie, size_t subie_len, + u8 *new_ie, size_t new_ie_len) +{ + const struct element *non_inherit_elem, *parent, *sub; + u8 *pos = new_ie; + u8 id, ext_id; + unsigned int match_len; + + non_inherit_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, + subie, subie_len); + + /* We copy the elements one by one from the parent to the generated + * elements. + * If they are not inherited (included in subie or in the non + * inheritance element), then we copy all occurrences the first time + * we see this element type. */ - tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen); - tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie; - - while (tmp_old + 2 - ie <= ielen && - tmp_old + tmp_old[1] + 2 - ie <= ielen) { - if (tmp_old[0] == 0) { - tmp_old++; + for_each_element(parent, ie, ielen) { + if (parent->id == WLAN_EID_FRAGMENT) continue; + + if (parent->id == WLAN_EID_EXTENSION) { + if (parent->datalen < 1) + continue; + + id = WLAN_EID_EXTENSION; + ext_id = parent->data[0]; + match_len = 1; + } else { + id = parent->id; + match_len = 0; }
- if (tmp_old[0] == WLAN_EID_EXTENSION) - tmp = (u8 *)cfg80211_find_ext_ie(tmp_old[2], sub_copy, - subie_len); - else - tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy, - subie_len); + /* Find first occurrence in subie */ + sub = cfg80211_find_elem_match(id, subie, subie_len, + &ext_id, match_len, 0);
- if (!tmp) { - const struct element *old_elem = (void *)tmp_old; + /* Copy from parent if not in subie and inherited */ + if (!sub && + cfg80211_is_element_inherited(parent, non_inherit_elem)) { + if (!cfg80211_copy_elem_with_frags(parent, + ie, ielen, + &pos, new_ie, + new_ie_len)) + return 0;
- /* ie in old ie but not in subelement */ - if (cfg80211_is_element_inherited(old_elem, - non_inherit_elem)) { - memcpy(pos, tmp_old, tmp_old[1] + 2); - pos += tmp_old[1] + 2; - } - } else { - /* ie in transmitting ie also in subelement, - * copy from subelement and flag the ie in subelement - * as copied (by setting eid field to WLAN_EID_SSID, - * which is skipped anyway). - * For vendor ie, compare OUI + type + subType to - * determine if they are the same ie. - */ - if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) { - if (tmp_old[1] >= 5 && tmp[1] >= 5 && - !memcmp(tmp_old + 2, tmp + 2, 5)) { - /* same vendor ie, copy from - * subelement - */ - memcpy(pos, tmp, tmp[1] + 2); - pos += tmp[1] + 2; - tmp[0] = WLAN_EID_SSID; - } else { - memcpy(pos, tmp_old, tmp_old[1] + 2); - pos += tmp_old[1] + 2; - } - } else { - /* copy ie from subelement into new ie */ - memcpy(pos, tmp, tmp[1] + 2); - pos += tmp[1] + 2; - tmp[0] = WLAN_EID_SSID; - } + continue; }
- if (tmp_old + tmp_old[1] + 2 - ie == ielen) - break; + /* Already copied if an earlier element had the same type */ + if (cfg80211_find_elem_match(id, ie, (u8 *)parent - ie, + &ext_id, match_len, 0)) + continue;
- tmp_old += tmp_old[1] + 2; + /* Not inheriting, copy all similar elements from subie */ + while (sub) { + if (!cfg80211_copy_elem_with_frags(sub, + subie, subie_len, + &pos, new_ie, + new_ie_len)) + return 0; + + sub = cfg80211_find_elem_match(id, + sub->data + sub->datalen, + subie_len + subie - + (sub->data + + sub->datalen), + &ext_id, match_len, 0); + } }
- /* go through subelement again to check if there is any ie not - * copied to new ie, skip ssid, capability, bssid-index ie + /* The above misses elements that are included in subie but not in the + * parent, so do a pass over subie and append those. + * Skip the non-tx BSSID caps and non-inheritance element. */ - tmp_new = sub_copy; - while (tmp_new + 2 - sub_copy <= subie_len && - tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { - if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP || - tmp_new[0] == WLAN_EID_SSID)) { - memcpy(pos, tmp_new, tmp_new[1] + 2); - pos += tmp_new[1] + 2; + for_each_element(sub, subie, subie_len) { + if (sub->id == WLAN_EID_NON_TX_BSSID_CAP) + continue; + + if (sub->id == WLAN_EID_FRAGMENT) + continue; + + if (sub->id == WLAN_EID_EXTENSION) { + if (sub->datalen < 1) + continue; + + id = WLAN_EID_EXTENSION; + ext_id = sub->data[0]; + match_len = 1; + + if (ext_id == WLAN_EID_EXT_NON_INHERITANCE) + continue; + } else { + id = sub->id; + match_len = 0; } - if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len) - break; - tmp_new += tmp_new[1] + 2; + + /* Processed if one was included in the parent */ + if (cfg80211_find_elem_match(id, ie, ielen, + &ext_id, match_len, 0)) + continue; + + if (!cfg80211_copy_elem_with_frags(sub, subie, subie_len, + &pos, new_ie, new_ie_len)) + return 0; }
- kfree(sub_copy); return pos - new_ie; }
@@ -2180,7 +2215,7 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, new_ie_len = cfg80211_gen_new_ie(ie, ielen, profile, profile_len, new_ie, - gfp); + IEEE80211_MAX_DATA_LEN); if (!new_ie_len) continue;
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 2db72b8a700943aa54dce0aabe6ff1b72b615162 ]
We've already done the 'decryption' here, so tell mac80211 it need not do it again.
Fixes: b1fdc2505abc ("iwlwifi: mvm: advertise BIGTK client support if available") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230620125813.a50cf68fbf2e.Ieceacbe3789d81ea02ae0... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 49c28c96fdf28..411254e9e603f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -302,7 +302,8 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta, struct ieee80211_hdr *hdr, struct iwl_rx_mpdu_desc *desc, - u32 status) + u32 status, + struct ieee80211_rx_status *stats) { struct iwl_mvm_sta *mvmsta; struct iwl_mvm_vif *mvmvif; @@ -331,8 +332,10 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
/* good cases */ if (likely(status & IWL_RX_MPDU_STATUS_MIC_OK && - !(status & IWL_RX_MPDU_STATUS_REPLAY_ERROR))) + !(status & IWL_RX_MPDU_STATUS_REPLAY_ERROR))) { + stats->flag |= RX_FLAG_DECRYPTED; return 0; + }
if (!sta) return -1; @@ -401,7 +404,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
if (unlikely(ieee80211_is_mgmt(hdr->frame_control) && !ieee80211_has_protected(hdr->frame_control))) - return iwl_mvm_rx_mgmt_prot(sta, hdr, desc, status); + return iwl_mvm_rx_mgmt_prot(sta, hdr, desc, status, stats);
if (!ieee80211_has_protected(hdr->frame_control) || (status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
From: Dmitry Antipov dmantipov@yandex.ru
[ Upstream commit 2aa083acea9f61be3280184384551178f510ff51 ]
Since 'ieee80211_queue_delayed_work()' expects timeout in jiffies and not milliseconds, 'msecs_to_jiffies()' should be used in 'ath_restart_work()' and '__ath9k_flush()'.
Fixes: d63ffc45c5d3 ("ath9k: rename tx_complete_work to hw_check_work") Signed-off-by: Dmitry Antipov dmantipov@yandex.ru Acked-by: Toke Høiland-Jørgensen toke@toke.dk Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230613134655.248728-1-dmantipov@yandex.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 98868f60a8c2f..9e6d088bd2818 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -203,7 +203,7 @@ void ath_cancel_work(struct ath_softc *sc) void ath_restart_work(struct ath_softc *sc) { ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work, - ATH_HW_CHECK_POLL_INT); + msecs_to_jiffies(ATH_HW_CHECK_POLL_INT));
if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah)) ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, @@ -2239,7 +2239,7 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop, }
ieee80211_queue_delayed_work(hw, &sc->hw_check_work, - ATH_HW_CHECK_POLL_INT); + msecs_to_jiffies(ATH_HW_CHECK_POLL_INT)); }
static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
From: Tobias Klauser tklauser@distanz.ch
[ Upstream commit 2064a132c0de3426d5ba43023200994e0c77e652 ]
family is only set to either AF_INET or AF_INET6 based on len. In all other cases we return early. Thus the check against AF_UNSPEC can be omitted.
Signed-off-by: Tobias Klauser tklauser@distanz.ch Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20220630082618.15649-1-tklauser@distanz.ch Stable-dep-of: 9a5cb79762e0 ("bpf: Fix bpf socket lookup from tc/xdp to respect socket VRF bindings") Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/filter.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c index 519315a1acf3a..a8291ba156446 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6177,8 +6177,8 @@ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, u64 flags) { struct sock *sk = NULL; - u8 family = AF_UNSPEC; struct net *net; + u8 family; int sdif;
if (len == sizeof(tuple->ipv4)) @@ -6188,8 +6188,7 @@ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, else return NULL;
- if (unlikely(family == AF_UNSPEC || flags || - !((s32)netns_id < 0 || netns_id <= S32_MAX))) + if (unlikely(flags || !((s32)netns_id < 0 || netns_id <= S32_MAX))) goto out;
if (family == AF_INET)
From: Gilad Sever gilad9366@gmail.com
[ Upstream commit 6e98730bc0b44acaf86eccc75f823128aa9c9e79 ]
Change BPF helper socket lookup functions to use TC specific variants: bpf_tc_sk_lookup_tcp() / bpf_tc_sk_lookup_udp() / bpf_tc_skc_lookup_tcp() instead of sharing implementation with the cg / sk_skb hooking points. This allows introducing a separate logic for the TC flow.
The tc functions are identical to the original code.
Signed-off-by: Gilad Sever gilad9366@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Shmulik Ladkani shmulik.ladkani@gmail.com Reviewed-by: Eyal Birger eyal.birger@gmail.com Acked-by: Stanislav Fomichev sdf@google.com Link: https://lore.kernel.org/bpf/20230621104211.301902-2-gilad9366@gmail.com Stable-dep-of: 9a5cb79762e0 ("bpf: Fix bpf socket lookup from tc/xdp to respect socket VRF bindings") Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/filter.c | 63 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 3 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c index a8291ba156446..650214f1d25fa 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6346,6 +6346,63 @@ static const struct bpf_func_proto bpf_sk_lookup_udp_proto = { .arg5_type = ARG_ANYTHING, };
+BPF_CALL_5(bpf_tc_skc_lookup_tcp, struct sk_buff *, skb, + struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) +{ + return (unsigned long)bpf_skc_lookup(skb, tuple, len, IPPROTO_TCP, + netns_id, flags); +} + +static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = { + .func = bpf_tc_skc_lookup_tcp, + .gpl_only = false, + .pkt_access = true, + .ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, + .arg3_type = ARG_CONST_SIZE, + .arg4_type = ARG_ANYTHING, + .arg5_type = ARG_ANYTHING, +}; + +BPF_CALL_5(bpf_tc_sk_lookup_tcp, struct sk_buff *, skb, + struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) +{ + return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP, + netns_id, flags); +} + +static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = { + .func = bpf_tc_sk_lookup_tcp, + .gpl_only = false, + .pkt_access = true, + .ret_type = RET_PTR_TO_SOCKET_OR_NULL, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, + .arg3_type = ARG_CONST_SIZE, + .arg4_type = ARG_ANYTHING, + .arg5_type = ARG_ANYTHING, +}; + +BPF_CALL_5(bpf_tc_sk_lookup_udp, struct sk_buff *, skb, + struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) +{ + return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP, + netns_id, flags); +} + +static const struct bpf_func_proto bpf_tc_sk_lookup_udp_proto = { + .func = bpf_tc_sk_lookup_udp, + .gpl_only = false, + .pkt_access = true, + .ret_type = RET_PTR_TO_SOCKET_OR_NULL, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, + .arg3_type = ARG_CONST_SIZE, + .arg4_type = ARG_ANYTHING, + .arg5_type = ARG_ANYTHING, +}; + BPF_CALL_1(bpf_sk_release, struct sock *, sk) { if (sk && sk_is_refcounted(sk)) @@ -7475,9 +7532,9 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) #endif #ifdef CONFIG_INET case BPF_FUNC_sk_lookup_tcp: - return &bpf_sk_lookup_tcp_proto; + return &bpf_tc_sk_lookup_tcp_proto; case BPF_FUNC_sk_lookup_udp: - return &bpf_sk_lookup_udp_proto; + return &bpf_tc_sk_lookup_udp_proto; case BPF_FUNC_sk_release: return &bpf_sk_release_proto; case BPF_FUNC_tcp_sock: @@ -7485,7 +7542,7 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) case BPF_FUNC_get_listener_sock: return &bpf_get_listener_sock_proto; case BPF_FUNC_skc_lookup_tcp: - return &bpf_skc_lookup_tcp_proto; + return &bpf_tc_skc_lookup_tcp_proto; case BPF_FUNC_tcp_check_syncookie: return &bpf_tcp_check_syncookie_proto; case BPF_FUNC_skb_ecn_set_ce:
From: Gilad Sever gilad9366@gmail.com
[ Upstream commit 97fbfeb86917bdbe9c41d5143e335a929147f405 ]
skb->dev always exists in the tc flow. There is no need to use bpf_skc_lookup(), bpf_sk_lookup() from this code path.
This change facilitates fixing the tc flow to be VRF aware.
Signed-off-by: Gilad Sever gilad9366@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Shmulik Ladkani shmulik.ladkani@gmail.com Reviewed-by: Eyal Birger eyal.birger@gmail.com Acked-by: Stanislav Fomichev sdf@google.com Link: https://lore.kernel.org/bpf/20230621104211.301902-3-gilad9366@gmail.com Stable-dep-of: 9a5cb79762e0 ("bpf: Fix bpf socket lookup from tc/xdp to respect socket VRF bindings") Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/filter.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c index 650214f1d25fa..60c1ad379a0b6 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6349,8 +6349,12 @@ static const struct bpf_func_proto bpf_sk_lookup_udp_proto = { BPF_CALL_5(bpf_tc_skc_lookup_tcp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - return (unsigned long)bpf_skc_lookup(skb, tuple, len, IPPROTO_TCP, - netns_id, flags); + struct net *caller_net = dev_net(skb->dev); + int ifindex = skb->dev->ifindex; + + return (unsigned long)__bpf_skc_lookup(skb, tuple, len, caller_net, + ifindex, IPPROTO_TCP, netns_id, + flags); }
static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = { @@ -6368,8 +6372,12 @@ static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = { BPF_CALL_5(bpf_tc_sk_lookup_tcp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP, - netns_id, flags); + struct net *caller_net = dev_net(skb->dev); + int ifindex = skb->dev->ifindex; + + return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net, + ifindex, IPPROTO_TCP, netns_id, + flags); }
static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = { @@ -6387,8 +6395,12 @@ static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = { BPF_CALL_5(bpf_tc_sk_lookup_udp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP, - netns_id, flags); + struct net *caller_net = dev_net(skb->dev); + int ifindex = skb->dev->ifindex; + + return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net, + ifindex, IPPROTO_UDP, netns_id, + flags); }
static const struct bpf_func_proto bpf_tc_sk_lookup_udp_proto = {
From: Gilad Sever gilad9366@gmail.com
[ Upstream commit 9a5cb79762e0eda17ca15c2a6eaca4622383c21c ]
When calling bpf_sk_lookup_tcp(), bpf_sk_lookup_udp() or bpf_skc_lookup_tcp() from tc/xdp ingress, VRF socket bindings aren't respoected, i.e. unbound sockets are returned, and bound sockets aren't found.
VRF binding is determined by the sdif argument to sk_lookup(), however when called from tc the IP SKB control block isn't initialized and thus inet{,6}_sdif() always returns 0.
Fix by calculating sdif for the tc/xdp flows by observing the device's l3 enslaved state.
The cg/sk_skb hooking points which are expected to support inet{,6}_sdif() pass sdif=-1 which makes __bpf_skc_lookup() use the existing logic.
Fixes: 6acc9b432e67 ("bpf: Add helper to retrieve socket in BPF") Signed-off-by: Gilad Sever gilad9366@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Shmulik Ladkani shmulik.ladkani@gmail.com Reviewed-by: Eyal Birger eyal.birger@gmail.com Acked-by: Stanislav Fomichev sdf@google.com Cc: David Ahern dsahern@kernel.org Link: https://lore.kernel.org/bpf/20230621104211.301902-4-gilad9366@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/netdevice.h | 9 +++++ net/core/filter.c | 69 ++++++++++++++++++++++----------------- 2 files changed, 48 insertions(+), 30 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c0a4589ab706f..b5df2e59a51d3 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -5196,6 +5196,15 @@ static inline bool netif_is_l3_slave(const struct net_device *dev) return dev->priv_flags & IFF_L3MDEV_SLAVE; }
+static inline int dev_sdif(const struct net_device *dev) +{ +#ifdef CONFIG_NET_L3_MASTER_DEV + if (netif_is_l3_slave(dev)) + return dev->ifindex; +#endif + return 0; +} + static inline bool netif_is_bridge_master(const struct net_device *dev) { return dev->priv_flags & IFF_EBRIDGE; diff --git a/net/core/filter.c b/net/core/filter.c index 60c1ad379a0b6..18eb8049c795c 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6174,12 +6174,11 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple, static struct sock * __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id, - u64 flags) + u64 flags, int sdif) { struct sock *sk = NULL; struct net *net; u8 family; - int sdif;
if (len == sizeof(tuple->ipv4)) family = AF_INET; @@ -6191,10 +6190,12 @@ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, if (unlikely(flags || !((s32)netns_id < 0 || netns_id <= S32_MAX))) goto out;
- if (family == AF_INET) - sdif = inet_sdif(skb); - else - sdif = inet6_sdif(skb); + if (sdif < 0) { + if (family == AF_INET) + sdif = inet_sdif(skb); + else + sdif = inet6_sdif(skb); + }
if ((s32)netns_id < 0) { net = caller_net; @@ -6214,10 +6215,11 @@ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, static struct sock * __bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id, - u64 flags) + u64 flags, int sdif) { struct sock *sk = __bpf_skc_lookup(skb, tuple, len, caller_net, - ifindex, proto, netns_id, flags); + ifindex, proto, netns_id, flags, + sdif);
if (sk) { struct sock *sk2 = sk_to_full_sk(sk); @@ -6257,7 +6259,7 @@ bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, }
return __bpf_skc_lookup(skb, tuple, len, caller_net, ifindex, proto, - netns_id, flags); + netns_id, flags, -1); }
static struct sock * @@ -6349,12 +6351,13 @@ static const struct bpf_func_proto bpf_sk_lookup_udp_proto = { BPF_CALL_5(bpf_tc_skc_lookup_tcp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - struct net *caller_net = dev_net(skb->dev); - int ifindex = skb->dev->ifindex; + struct net_device *dev = skb->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_skc_lookup(skb, tuple, len, caller_net, ifindex, IPPROTO_TCP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = { @@ -6372,12 +6375,13 @@ static const struct bpf_func_proto bpf_tc_skc_lookup_tcp_proto = { BPF_CALL_5(bpf_tc_sk_lookup_tcp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - struct net *caller_net = dev_net(skb->dev); - int ifindex = skb->dev->ifindex; + struct net_device *dev = skb->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net, ifindex, IPPROTO_TCP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = { @@ -6395,12 +6399,13 @@ static const struct bpf_func_proto bpf_tc_sk_lookup_tcp_proto = { BPF_CALL_5(bpf_tc_sk_lookup_udp, struct sk_buff *, skb, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { - struct net *caller_net = dev_net(skb->dev); - int ifindex = skb->dev->ifindex; + struct net_device *dev = skb->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_sk_lookup(skb, tuple, len, caller_net, ifindex, IPPROTO_UDP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_tc_sk_lookup_udp_proto = { @@ -6432,12 +6437,13 @@ static const struct bpf_func_proto bpf_sk_release_proto = { BPF_CALL_5(bpf_xdp_sk_lookup_udp, struct xdp_buff *, ctx, struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags) { - struct net *caller_net = dev_net(ctx->rxq->dev); - int ifindex = ctx->rxq->dev->ifindex; + struct net_device *dev = ctx->rxq->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net, ifindex, IPPROTO_UDP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_xdp_sk_lookup_udp_proto = { @@ -6455,12 +6461,13 @@ static const struct bpf_func_proto bpf_xdp_sk_lookup_udp_proto = { BPF_CALL_5(bpf_xdp_skc_lookup_tcp, struct xdp_buff *, ctx, struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags) { - struct net *caller_net = dev_net(ctx->rxq->dev); - int ifindex = ctx->rxq->dev->ifindex; + struct net_device *dev = ctx->rxq->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_skc_lookup(NULL, tuple, len, caller_net, ifindex, IPPROTO_TCP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_xdp_skc_lookup_tcp_proto = { @@ -6478,12 +6485,13 @@ static const struct bpf_func_proto bpf_xdp_skc_lookup_tcp_proto = { BPF_CALL_5(bpf_xdp_sk_lookup_tcp, struct xdp_buff *, ctx, struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags) { - struct net *caller_net = dev_net(ctx->rxq->dev); - int ifindex = ctx->rxq->dev->ifindex; + struct net_device *dev = ctx->rxq->dev; + int ifindex = dev->ifindex, sdif = dev_sdif(dev); + struct net *caller_net = dev_net(dev);
return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net, ifindex, IPPROTO_TCP, netns_id, - flags); + flags, sdif); }
static const struct bpf_func_proto bpf_xdp_sk_lookup_tcp_proto = { @@ -6503,7 +6511,8 @@ BPF_CALL_5(bpf_sock_addr_skc_lookup_tcp, struct bpf_sock_addr_kern *, ctx, { return (unsigned long)__bpf_skc_lookup(NULL, tuple, len, sock_net(ctx->sk), 0, - IPPROTO_TCP, netns_id, flags); + IPPROTO_TCP, netns_id, flags, + -1); }
static const struct bpf_func_proto bpf_sock_addr_skc_lookup_tcp_proto = { @@ -6522,7 +6531,7 @@ BPF_CALL_5(bpf_sock_addr_sk_lookup_tcp, struct bpf_sock_addr_kern *, ctx, { return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, sock_net(ctx->sk), 0, IPPROTO_TCP, - netns_id, flags); + netns_id, flags, -1); }
static const struct bpf_func_proto bpf_sock_addr_sk_lookup_tcp_proto = { @@ -6541,7 +6550,7 @@ BPF_CALL_5(bpf_sock_addr_sk_lookup_udp, struct bpf_sock_addr_kern *, ctx, { return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, sock_net(ctx->sk), 0, IPPROTO_UDP, - netns_id, flags); + netns_id, flags, -1); }
static const struct bpf_func_proto bpf_sock_addr_sk_lookup_udp_proto = {
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit 9fde4c557f78ee2f3626e92b4089ce9d54a2573a ]
The Stuff Bit Count is always coded on 4 bits [1]. Update the Stuff Bit Count size accordingly.
In addition, the CRC fields of CAN FD Frames contain stuff bits at fixed positions called fixed stuff bits [2]. The CRC field starts with a fixed stuff bit and then has another fixed stuff bit after each fourth bit [2], which allows us to derive this formula:
FSB count = 1 + round_down(len(CRC field)/4)
The length of the CRC field is [1]:
len(CRC field) = len(Stuff Bit Count) + len(CRC) = 4 + len(CRC)
with len(CRC) either 17 or 21 bits depending of the payload length.
In conclusion, for CRC17:
FSB count = 1 + round_down((4 + 17)/4) = 6
and for CRC 21:
FSB count = 1 + round_down((4 + 21)/4) = 7
Add a Fixed Stuff bits (FSB) field with above values and update CANFD_FRAME_OVERHEAD_SFF and CANFD_FRAME_OVERHEAD_EFF accordingly.
[1] ISO 11898-1:2015 section 10.4.2.6 "CRC field":
The CRC field shall contain the CRC sequence followed by a recessive CRC delimiter. For FD Frames, the CRC field shall also contain the stuff count.
Stuff count
If FD Frames, the stuff count shall be at the beginning of the CRC field. It shall consist of the stuff bit count modulo 8 in a 3-bit gray code followed by a parity bit [...]
[2] ISO 11898-1:2015 paragraph 10.5 "Frame coding":
In the CRC field of FD Frames, the stuff bits shall be inserted at fixed positions; they are called fixed stuff bits. There shall be a fixed stuff bit before the first bit of the stuff count, even if the last bits of the preceding field are a sequence of five consecutive bits of identical value, there shall be only the fixed stuff bit, there shall not be two consecutive stuff bits. A further fixed stuff bit shall be inserted after each fourth bit of the CRC field [...]
Fixes: 85d99c3e2a13 ("can: length: can_skb_get_frame_len(): introduce function to get data length of frame in data link layer") Suggested-by: Thomas Kopp Thomas.Kopp@microchip.com Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Reviewed-by: Thomas Kopp Thomas.Kopp@microchip.com Link: https://lore.kernel.org/all/20230611025728.450837-2-mailhol.vincent@wanadoo.... Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/can/length.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/include/linux/can/length.h b/include/linux/can/length.h index 6995092b774ec..ef1fd32cef16b 100644 --- a/include/linux/can/length.h +++ b/include/linux/can/length.h @@ -69,17 +69,18 @@ * Error Status Indicator (ESI) 1 * Data length code (DLC) 4 * Data field 0...512 - * Stuff Bit Count (SBC) 0...16: 4 20...64:5 + * Stuff Bit Count (SBC) 4 * CRC 0...16: 17 20...64:21 * CRC delimiter (CD) 1 + * Fixed Stuff bits (FSB) 0...16: 6 20...64:7 * ACK slot (AS) 1 * ACK delimiter (AD) 1 * End-of-frame (EOF) 7 * Inter frame spacing 3 * - * assuming CRC21, rounded up and ignoring bitstuffing + * assuming CRC21, rounded up and ignoring dynamic bitstuffing */ -#define CANFD_FRAME_OVERHEAD_SFF DIV_ROUND_UP(61, 8) +#define CANFD_FRAME_OVERHEAD_SFF DIV_ROUND_UP(67, 8)
/* * Size of a CAN-FD Extended Frame @@ -98,17 +99,18 @@ * Error Status Indicator (ESI) 1 * Data length code (DLC) 4 * Data field 0...512 - * Stuff Bit Count (SBC) 0...16: 4 20...64:5 + * Stuff Bit Count (SBC) 4 * CRC 0...16: 17 20...64:21 * CRC delimiter (CD) 1 + * Fixed Stuff bits (FSB) 0...16: 6 20...64:7 * ACK slot (AS) 1 * ACK delimiter (AD) 1 * End-of-frame (EOF) 7 * Inter frame spacing 3 * - * assuming CRC21, rounded up and ignoring bitstuffing + * assuming CRC21, rounded up and ignoring dynamic bitstuffing */ -#define CANFD_FRAME_OVERHEAD_EFF DIV_ROUND_UP(80, 8) +#define CANFD_FRAME_OVERHEAD_EFF DIV_ROUND_UP(86, 8)
/* * Maximum size of a Classical CAN frame
From: Vinicius Costa Gomes vinicius.gomes@intel.com
[ Upstream commit 9c50e2b150c8ee0eee5f8154e2ad168cdd748877 ]
Currently, the igc driver supports timestamping only one tx packet at a time. During the transmission flow, the skb that requires hardware timestamping is saved in adapter->ptp_tx_skb. Once hardware has the timestamp, an interrupt is delivered, and adapter->ptp_tx_work is scheduled. In igc_ptp_tx_work(), we read the timestamp register, update adapter->ptp_tx_skb, and notify the network stack.
While the thread executing the transmission flow (the user process running in kernel mode) and the thread executing ptp_tx_work don't access adapter->ptp_tx_skb concurrently, there are two other places where adapter->ptp_tx_skb is accessed: igc_ptp_tx_hang() and igc_ptp_suspend().
igc_ptp_tx_hang() is executed by the adapter->watchdog_task worker thread which runs periodically so it is possible we have two threads accessing ptp_tx_skb at the same time. Consider the following scenario: right after __IGC_PTP_TX_IN_PROGRESS is set in igc_xmit_frame_ring(), igc_ptp_tx_hang() is executed. Since adapter->ptp_tx_start hasn't been written yet, this is considered a timeout and adapter->ptp_tx_skb is cleaned up.
This patch fixes the issue described above by adding the ptp_tx_lock to protect access to ptp_tx_skb and ptp_tx_start fields from igc_adapter. Since igc_xmit_frame_ring() called in atomic context by the networking stack, ptp_tx_lock is defined as a spinlock, and the irq safe variants of lock/unlock are used.
With the introduction of the ptp_tx_lock, the __IGC_PTP_TX_IN_PROGRESS flag doesn't provide much of a use anymore so this patch gets rid of it.
Fixes: 2c344ae24501 ("igc: Add support for TX timestamping") Signed-off-by: Andre Guedes andre.guedes@intel.com Signed-off-by: Vinicius Costa Gomes vinicius.gomes@intel.com Reviewed-by: Kurt Kanzenbach kurt@linutronix.de Tested-by: Naama Meir naamax.meir@linux.intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/igc/igc.h | 5 +- drivers/net/ethernet/intel/igc/igc_main.c | 9 ++-- drivers/net/ethernet/intel/igc/igc_ptp.c | 57 ++++++++++++----------- 3 files changed, 41 insertions(+), 30 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h index 486e1ce609cd5..192fee9e72b05 100644 --- a/drivers/net/ethernet/intel/igc/igc.h +++ b/drivers/net/ethernet/intel/igc/igc.h @@ -228,6 +228,10 @@ struct igc_adapter { struct ptp_clock *ptp_clock; struct ptp_clock_info ptp_caps; struct work_struct ptp_tx_work; + /* Access to ptp_tx_skb and ptp_tx_start are protected by the + * ptp_tx_lock. + */ + spinlock_t ptp_tx_lock; struct sk_buff *ptp_tx_skb; struct hwtstamp_config tstamp_config; unsigned long ptp_tx_start; @@ -430,7 +434,6 @@ enum igc_state_t { __IGC_TESTING, __IGC_RESETTING, __IGC_DOWN, - __IGC_PTP_TX_IN_PROGRESS, };
enum igc_tx_flags { diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 32e4ebac4b693..abc63ca9d28bf 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -1576,9 +1576,10 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb, * the other timer registers before skipping the * timestamping request. */ - if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && - !test_and_set_bit_lock(__IGC_PTP_TX_IN_PROGRESS, - &adapter->state)) { + unsigned long flags; + + spin_lock_irqsave(&adapter->ptp_tx_lock, flags); + if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && !adapter->ptp_tx_skb) { skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; tx_flags |= IGC_TX_FLAGS_TSTAMP;
@@ -1587,6 +1588,8 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb, } else { adapter->tx_hwtstamp_skipped++; } + + spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); }
if (skb_vlan_tag_present(skb)) { diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c index 743c31659709b..6803d91cf71cd 100644 --- a/drivers/net/ethernet/intel/igc/igc_ptp.c +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c @@ -608,6 +608,7 @@ static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter, return 0; }
+/* Requires adapter->ptp_tx_lock held by caller. */ static void igc_ptp_tx_timeout(struct igc_adapter *adapter) { struct igc_hw *hw = &adapter->hw; @@ -615,7 +616,6 @@ static void igc_ptp_tx_timeout(struct igc_adapter *adapter) dev_kfree_skb_any(adapter->ptp_tx_skb); adapter->ptp_tx_skb = NULL; adapter->tx_hwtstamp_timeouts++; - clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state); /* Clear the tx valid bit in TSYNCTXCTL register to enable interrupt. */ rd32(IGC_TXSTMPH); netdev_warn(adapter->netdev, "Tx timestamp timeout\n"); @@ -623,20 +623,20 @@ static void igc_ptp_tx_timeout(struct igc_adapter *adapter)
void igc_ptp_tx_hang(struct igc_adapter *adapter) { - bool timeout = time_is_before_jiffies(adapter->ptp_tx_start + - IGC_PTP_TX_TIMEOUT); + unsigned long flags;
- if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state)) - return; + spin_lock_irqsave(&adapter->ptp_tx_lock, flags);
- /* If we haven't received a timestamp within the timeout, it is - * reasonable to assume that it will never occur, so we can unlock the - * timestamp bit when this occurs. - */ - if (timeout) { - cancel_work_sync(&adapter->ptp_tx_work); - igc_ptp_tx_timeout(adapter); - } + if (!adapter->ptp_tx_skb) + goto unlock; + + if (time_is_after_jiffies(adapter->ptp_tx_start + IGC_PTP_TX_TIMEOUT)) + goto unlock; + + igc_ptp_tx_timeout(adapter); + +unlock: + spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); }
/** @@ -646,6 +646,8 @@ void igc_ptp_tx_hang(struct igc_adapter *adapter) * If we were asked to do hardware stamping and such a time stamp is * available, then it must have been for this skb here because we only * allow only one such packet into the queue. + * + * Context: Expects adapter->ptp_tx_lock to be held by caller. */ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) { @@ -681,13 +683,7 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) shhwtstamps.hwtstamp = ktime_add_ns(shhwtstamps.hwtstamp, adjust);
- /* Clear the lock early before calling skb_tstamp_tx so that - * applications are not woken up before the lock bit is clear. We use - * a copy of the skb pointer to ensure other threads can't change it - * while we're notifying the stack. - */ adapter->ptp_tx_skb = NULL; - clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
/* Notify the stack and free the skb after we've unlocked */ skb_tstamp_tx(skb, &shhwtstamps); @@ -698,24 +694,33 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) * igc_ptp_tx_work * @work: pointer to work struct * - * This work function polls the TSYNCTXCTL valid bit to determine when a - * timestamp has been taken for the current stored skb. + * This work function checks the TSYNCTXCTL valid bit to determine when + * a timestamp has been taken for the current stored skb. */ static void igc_ptp_tx_work(struct work_struct *work) { struct igc_adapter *adapter = container_of(work, struct igc_adapter, ptp_tx_work); struct igc_hw *hw = &adapter->hw; + unsigned long flags; u32 tsynctxctl;
- if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state)) - return; + spin_lock_irqsave(&adapter->ptp_tx_lock, flags); + + if (!adapter->ptp_tx_skb) + goto unlock;
tsynctxctl = rd32(IGC_TSYNCTXCTL); - if (WARN_ON_ONCE(!(tsynctxctl & IGC_TSYNCTXCTL_TXTT_0))) - return; + tsynctxctl &= IGC_TSYNCTXCTL_TXTT_0; + if (!tsynctxctl) { + WARN_ONCE(1, "Received a TSTAMP interrupt but no TSTAMP is ready.\n"); + goto unlock; + }
igc_ptp_tx_hwtstamp(adapter); + +unlock: + spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); }
/** @@ -964,6 +969,7 @@ void igc_ptp_init(struct igc_adapter *adapter) return; }
+ spin_lock_init(&adapter->ptp_tx_lock); spin_lock_init(&adapter->tmreg_lock); INIT_WORK(&adapter->ptp_tx_work, igc_ptp_tx_work);
@@ -1028,7 +1034,6 @@ void igc_ptp_suspend(struct igc_adapter *adapter) cancel_work_sync(&adapter->ptp_tx_work); dev_kfree_skb_any(adapter->ptp_tx_skb); adapter->ptp_tx_skb = NULL; - clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
if (pci_device_is_present(adapter->pdev)) { igc_ptp_time_save(adapter);
From: Bartosz Golaszewski bartosz.golaszewski@linaro.org
[ Upstream commit c4fc88ad2a765224a648db8ab35f125e120fe41b ]
Commit 49725ffc15fc ("net: stmmac: power up/down serdes in stmmac_open/release") correctly added a call to the serdes_powerdown() callback to stmmac_release() but did not remove the one from stmmac_remove() which leads to a doubled call to serdes_powerdown().
This can lead to all kinds of problems: in the case of the qcom ethqos driver, it caused an unbalanced regulator disable splat.
Fixes: 49725ffc15fc ("net: stmmac: power up/down serdes in stmmac_open/release") Signed-off-by: Bartosz Golaszewski bartosz.golaszewski@linaro.org Reviewed-by: Jiri Pirko jiri@nvidia.com Acked-by: Junxiao Chang junxiao.chang@intel.com Reviewed-by: Andrew Halaney ahalaney@redhat.com Tested-by: Andrew Halaney ahalaney@redhat.com Link: https://lore.kernel.org/r/20230621135537.376649-1-brgl@bgdev.pl Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 179f8d196c890..a43628dd1f4c2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -7318,12 +7318,6 @@ int stmmac_dvr_remove(struct device *dev) netif_carrier_off(ndev); unregister_netdev(ndev);
- /* Serdes power down needs to happen after VLAN filter - * is deleted that is triggered by unregister_netdev(). - */ - if (priv->plat->serdes_powerdown) - priv->plat->serdes_powerdown(ndev, priv->plat->bsp_priv); - #ifdef CONFIG_DEBUG_FS stmmac_exit_fs(ndev); #endif
From: Eric Dumazet edumazet@google.com
[ Upstream commit 8d61f926d42045961e6b65191c09e3678d86a9cf ]
syzbot reported a possible deadlock in netlink_set_err() [1]
A similar issue was fixed in commit 1d482e666b8e ("netlink: disable IRQs for netlink_lock_table()") in netlink_lock_table()
This patch adds IRQ safety to netlink_set_err() and __netlink_diag_dump() which were not covered by cited commit.
[1]
WARNING: possible irq lock inversion dependency detected 6.4.0-rc6-syzkaller-00240-g4e9f0ec38852 #0 Not tainted
syz-executor.2/23011 just changed the state of lock: ffffffff8e1a7a58 (nl_table_lock){.+.?}-{2:2}, at: netlink_set_err+0x2e/0x3a0 net/netlink/af_netlink.c:1612 but this lock was taken by another, SOFTIRQ-safe lock in the past: (&local->queue_stop_reason_lock){..-.}-{2:2}
and interrupts could create inverse lock ordering between them.
other info that might help us debug this: Possible interrupt unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(nl_table_lock); local_irq_disable(); lock(&local->queue_stop_reason_lock); lock(nl_table_lock); <Interrupt> lock(&local->queue_stop_reason_lock);
*** DEADLOCK ***
Fixes: 1d482e666b8e ("netlink: disable IRQs for netlink_lock_table()") Reported-by: syzbot+a7d200a347f912723e5c@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=a7d200a347f912723e5c Link: https://lore.kernel.org/netdev/000000000000e38d1605fea5747e@google.com/T/#u Signed-off-by: Eric Dumazet edumazet@google.com Cc: Johannes Berg johannes.berg@intel.com Link: https://lore.kernel.org/r/20230621154337.1668594-1-edumazet@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netlink/af_netlink.c | 5 +++-- net/netlink/diag.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 46c4306ddee7e..f41e130a812f0 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1610,6 +1610,7 @@ static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p) int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code) { struct netlink_set_err_data info; + unsigned long flags; struct sock *sk; int ret = 0;
@@ -1619,12 +1620,12 @@ int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code) /* sk->sk_err wants a positive error value */ info.code = -code;
- read_lock(&nl_table_lock); + read_lock_irqsave(&nl_table_lock, flags);
sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list) ret += do_one_set_err(sk, &info);
- read_unlock(&nl_table_lock); + read_unlock_irqrestore(&nl_table_lock, flags); return ret; } EXPORT_SYMBOL(netlink_set_err); diff --git a/net/netlink/diag.c b/net/netlink/diag.c index c6255eac305c7..4143b2ea4195a 100644 --- a/net/netlink/diag.c +++ b/net/netlink/diag.c @@ -94,6 +94,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, struct net *net = sock_net(skb->sk); struct netlink_diag_req *req; struct netlink_sock *nlsk; + unsigned long flags; struct sock *sk; int num = 2; int ret = 0; @@ -152,7 +153,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, num++;
mc_list: - read_lock(&nl_table_lock); + read_lock_irqsave(&nl_table_lock, flags); sk_for_each_bound(sk, &tbl->mc_list) { if (sk_hashed(sk)) continue; @@ -173,7 +174,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, } num++; } - read_unlock(&nl_table_lock); + read_unlock_irqrestore(&nl_table_lock, flags);
done: cb->args[0] = num;
From: Eric Dumazet edumazet@google.com
[ Upstream commit aa5406950726e336c5c9585b09799a734b6e77bf ]
syzbot reports that some netdev devices do not have a six bytes address [1]
Replace ETH_ALEN by dev->addr_len.
[1] (Case of a device where dev->addr_len = 4)
BUG: KMSAN: kernel-infoleak in instrument_copy_to_user include/linux/instrumented.h:114 [inline] BUG: KMSAN: kernel-infoleak in copyout+0xb8/0x100 lib/iov_iter.c:169 instrument_copy_to_user include/linux/instrumented.h:114 [inline] copyout+0xb8/0x100 lib/iov_iter.c:169 _copy_to_iter+0x6d8/0x1d00 lib/iov_iter.c:536 copy_to_iter include/linux/uio.h:206 [inline] simple_copy_to_iter+0x68/0xa0 net/core/datagram.c:513 __skb_datagram_iter+0x123/0xdc0 net/core/datagram.c:419 skb_copy_datagram_iter+0x5c/0x200 net/core/datagram.c:527 skb_copy_datagram_msg include/linux/skbuff.h:3960 [inline] netlink_recvmsg+0x4ae/0x15a0 net/netlink/af_netlink.c:1970 sock_recvmsg_nosec net/socket.c:1019 [inline] sock_recvmsg net/socket.c:1040 [inline] ____sys_recvmsg+0x283/0x7f0 net/socket.c:2722 ___sys_recvmsg+0x223/0x840 net/socket.c:2764 do_recvmmsg+0x4f9/0xfd0 net/socket.c:2858 __sys_recvmmsg net/socket.c:2937 [inline] __do_sys_recvmmsg net/socket.c:2960 [inline] __se_sys_recvmmsg net/socket.c:2953 [inline] __x64_sys_recvmmsg+0x397/0x490 net/socket.c:2953 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Uninit was stored to memory at: __nla_put lib/nlattr.c:1009 [inline] nla_put+0x1c6/0x230 lib/nlattr.c:1067 nlmsg_populate_fdb_fill+0x2b8/0x600 net/core/rtnetlink.c:4071 nlmsg_populate_fdb net/core/rtnetlink.c:4418 [inline] ndo_dflt_fdb_dump+0x616/0x840 net/core/rtnetlink.c:4456 rtnl_fdb_dump+0x14ff/0x1fc0 net/core/rtnetlink.c:4629 netlink_dump+0x9d1/0x1310 net/netlink/af_netlink.c:2268 netlink_recvmsg+0xc5c/0x15a0 net/netlink/af_netlink.c:1995 sock_recvmsg_nosec+0x7a/0x120 net/socket.c:1019 ____sys_recvmsg+0x664/0x7f0 net/socket.c:2720 ___sys_recvmsg+0x223/0x840 net/socket.c:2764 do_recvmmsg+0x4f9/0xfd0 net/socket.c:2858 __sys_recvmmsg net/socket.c:2937 [inline] __do_sys_recvmmsg net/socket.c:2960 [inline] __se_sys_recvmmsg net/socket.c:2953 [inline] __x64_sys_recvmmsg+0x397/0x490 net/socket.c:2953 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Uninit was created at: slab_post_alloc_hook+0x12d/0xb60 mm/slab.h:716 slab_alloc_node mm/slub.c:3451 [inline] __kmem_cache_alloc_node+0x4ff/0x8b0 mm/slub.c:3490 kmalloc_trace+0x51/0x200 mm/slab_common.c:1057 kmalloc include/linux/slab.h:559 [inline] __hw_addr_create net/core/dev_addr_lists.c:60 [inline] __hw_addr_add_ex+0x2e5/0x9e0 net/core/dev_addr_lists.c:118 __dev_mc_add net/core/dev_addr_lists.c:867 [inline] dev_mc_add+0x9a/0x130 net/core/dev_addr_lists.c:885 igmp6_group_added+0x267/0xbc0 net/ipv6/mcast.c:680 ipv6_mc_up+0x296/0x3b0 net/ipv6/mcast.c:2754 ipv6_mc_remap+0x1e/0x30 net/ipv6/mcast.c:2708 addrconf_type_change net/ipv6/addrconf.c:3731 [inline] addrconf_notify+0x4d3/0x1d90 net/ipv6/addrconf.c:3699 notifier_call_chain kernel/notifier.c:93 [inline] raw_notifier_call_chain+0xe4/0x430 kernel/notifier.c:461 call_netdevice_notifiers_info net/core/dev.c:1935 [inline] call_netdevice_notifiers_extack net/core/dev.c:1973 [inline] call_netdevice_notifiers+0x1ee/0x2d0 net/core/dev.c:1987 bond_enslave+0xccd/0x53f0 drivers/net/bonding/bond_main.c:1906 do_set_master net/core/rtnetlink.c:2626 [inline] rtnl_newlink_create net/core/rtnetlink.c:3460 [inline] __rtnl_newlink net/core/rtnetlink.c:3660 [inline] rtnl_newlink+0x378c/0x40e0 net/core/rtnetlink.c:3673 rtnetlink_rcv_msg+0x16a6/0x1840 net/core/rtnetlink.c:6395 netlink_rcv_skb+0x371/0x650 net/netlink/af_netlink.c:2546 rtnetlink_rcv+0x34/0x40 net/core/rtnetlink.c:6413 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0xf28/0x1230 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x122f/0x13d0 net/netlink/af_netlink.c:1913 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg net/socket.c:747 [inline] ____sys_sendmsg+0x999/0xd50 net/socket.c:2503 ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2557 __sys_sendmsg net/socket.c:2586 [inline] __do_sys_sendmsg net/socket.c:2595 [inline] __se_sys_sendmsg net/socket.c:2593 [inline] __x64_sys_sendmsg+0x304/0x490 net/socket.c:2593 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Bytes 2856-2857 of 3500 are uninitialized Memory access of size 3500 starts at ffff888018d99104 Data copied to user address 0000000020000480
Fixes: d83b06036048 ("net: add fdb generic dump routine") Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: Eric Dumazet edumazet@google.com Reviewed-by: Jiri Pirko jiri@nvidia.com Link: https://lore.kernel.org/r/20230621174720.1845040-1-edumazet@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/rtnetlink.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 0ab558501290b..49766446797c1 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -3911,7 +3911,7 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb, ndm->ndm_ifindex = dev->ifindex; ndm->ndm_state = ndm_state;
- if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr)) + if (nla_put(skb, NDA_LLADDR, dev->addr_len, addr)) goto nla_put_failure; if (vid) if (nla_put(skb, NDA_VLAN, sizeof(u16), &vid)) @@ -3925,10 +3925,10 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb, return -EMSGSIZE; }
-static inline size_t rtnl_fdb_nlmsg_size(void) +static inline size_t rtnl_fdb_nlmsg_size(const struct net_device *dev) { return NLMSG_ALIGN(sizeof(struct ndmsg)) + - nla_total_size(ETH_ALEN) + /* NDA_LLADDR */ + nla_total_size(dev->addr_len) + /* NDA_LLADDR */ nla_total_size(sizeof(u16)) + /* NDA_VLAN */ 0; } @@ -3940,7 +3940,7 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type, struct sk_buff *skb; int err = -ENOBUFS;
- skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC); + skb = nlmsg_new(rtnl_fdb_nlmsg_size(dev), GFP_ATOMIC); if (!skb) goto errout;
From: Eric Dumazet edumazet@google.com
[ Upstream commit 6a940abdef3162e5723f1495b8a49859d1708f79 ]
Drivers must not assume in their ndo_start_xmit() that skbs have their mac_header set. skb->data is all what is needed.
bonding seems to be one of the last offender as caught by syzbot:
WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 skb_mac_offset include/linux/skbuff.h:2913 [inline] WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_xmit_hash drivers/net/bonding/bond_main.c:4170 [inline] WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_xmit_3ad_xor_slave_get drivers/net/bonding/bond_main.c:5149 [inline] WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_3ad_xor_xmit drivers/net/bonding/bond_main.c:5186 [inline] WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 __bond_start_xmit drivers/net/bonding/bond_main.c:5442 [inline] WARNING: CPU: 1 PID: 12155 at include/linux/skbuff.h:2907 bond_start_xmit+0x14ab/0x19d0 drivers/net/bonding/bond_main.c:5470 Modules linked in: CPU: 1 PID: 12155 Comm: syz-executor.3 Not tainted 6.1.30-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/25/2023 RIP: 0010:skb_mac_header include/linux/skbuff.h:2907 [inline] RIP: 0010:skb_mac_offset include/linux/skbuff.h:2913 [inline] RIP: 0010:bond_xmit_hash drivers/net/bonding/bond_main.c:4170 [inline] RIP: 0010:bond_xmit_3ad_xor_slave_get drivers/net/bonding/bond_main.c:5149 [inline] RIP: 0010:bond_3ad_xor_xmit drivers/net/bonding/bond_main.c:5186 [inline] RIP: 0010:__bond_start_xmit drivers/net/bonding/bond_main.c:5442 [inline] RIP: 0010:bond_start_xmit+0x14ab/0x19d0 drivers/net/bonding/bond_main.c:5470 Code: 8b 7c 24 30 e8 76 dd 1a 01 48 85 c0 74 0d 48 89 c3 e8 29 67 2e fe e9 15 ef ff ff e8 1f 67 2e fe e9 10 ef ff ff e8 15 67 2e fe <0f> 0b e9 45 f8 ff ff e8 09 67 2e fe e9 dc fa ff ff e8 ff 66 2e fe RSP: 0018:ffffc90002fff6e0 EFLAGS: 00010283 RAX: ffffffff835874db RBX: 000000000000ffff RCX: 0000000000040000 RDX: ffffc90004dcf000 RSI: 00000000000000b5 RDI: 00000000000000b6 RBP: ffffc90002fff8b8 R08: ffffffff83586d16 R09: ffffffff83586584 R10: 0000000000000007 R11: ffff8881599fc780 R12: ffff88811b6a7b7e R13: 1ffff110236d4f6f R14: ffff88811b6a7ac0 R15: 1ffff110236d4f76 FS: 00007f2e9eb47700(0000) GS:ffff8881f6b00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b2e421000 CR3: 000000010e6d4000 CR4: 00000000003526e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> [<ffffffff8471a49f>] netdev_start_xmit include/linux/netdevice.h:4925 [inline] [<ffffffff8471a49f>] __dev_direct_xmit+0x4ef/0x850 net/core/dev.c:4380 [<ffffffff851d845b>] dev_direct_xmit include/linux/netdevice.h:3043 [inline] [<ffffffff851d845b>] packet_direct_xmit+0x18b/0x300 net/packet/af_packet.c:284 [<ffffffff851c7472>] packet_snd net/packet/af_packet.c:3112 [inline] [<ffffffff851c7472>] packet_sendmsg+0x4a22/0x64d0 net/packet/af_packet.c:3143 [<ffffffff8467a4b2>] sock_sendmsg_nosec net/socket.c:716 [inline] [<ffffffff8467a4b2>] sock_sendmsg net/socket.c:736 [inline] [<ffffffff8467a4b2>] __sys_sendto+0x472/0x5f0 net/socket.c:2139 [<ffffffff8467a715>] __do_sys_sendto net/socket.c:2151 [inline] [<ffffffff8467a715>] __se_sys_sendto net/socket.c:2147 [inline] [<ffffffff8467a715>] __x64_sys_sendto+0xe5/0x100 net/socket.c:2147 [<ffffffff8553071f>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<ffffffff8553071f>] do_syscall_64+0x2f/0x50 arch/x86/entry/common.c:80 [<ffffffff85600087>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
Fixes: 7b8fc0103bb5 ("bonding: add a vlan+srcmac tx hashing option") Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: Eric Dumazet edumazet@google.com Cc: Jarod Wilson jarod@redhat.com Cc: Moshe Tal moshet@nvidia.com Cc: Jussi Maki joamaki@gmail.com Cc: Jay Vosburgh j.vosburgh@gmail.com Cc: Andy Gospodarek andy@greyhouse.net Cc: Vladimir Oltean vladimir.oltean@nxp.com Link: https://lore.kernel.org/r/20230622152304.2137482-1-edumazet@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b4d613bdbc060..7b0b4049bd294 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3900,7 +3900,7 @@ u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb) return skb->hash;
return __bond_xmit_hash(bond, skb, skb->data, skb->protocol, - skb_mac_offset(skb), skb_network_offset(skb), + 0, skb_network_offset(skb), skb_headlen(skb)); }
From: Sabrina Dubroca sd@queasysnail.net
[ Upstream commit 5f789f103671fec3733ebe756e56adf15c90c21d ]
On systems where netdevsim is built-in or loaded before the test starts, kci_test_ipsec_offload doesn't remove the netdevsim device it created during the test.
Fixes: e05b2d141fef ("netdevsim: move netdev creation/destruction to dev probe") Signed-off-by: Sabrina Dubroca sd@queasysnail.net Reviewed-by: Simon Horman simon.horman@corigine.com Reviewed-by: Jiri Pirko jiri@nvidia.com Link: https://lore.kernel.org/r/e1cb94f4f82f4eca4a444feec4488a1323396357.168746690... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/rtnetlink.sh | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh index c3a905923ef29..cbf166df57da7 100755 --- a/tools/testing/selftests/net/rtnetlink.sh +++ b/tools/testing/selftests/net/rtnetlink.sh @@ -835,6 +835,7 @@ EOF fi
# clean up any leftovers + echo 0 > /sys/bus/netdevsim/del_device $probed && rmmod netdevsim
if [ $ret -ne 0 ]; then
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit ce3aee7114c575fab32a5e9e939d4bbb3dcca79f ]
syzkaller reported use-after-free in __gtp_encap_destroy(). [0]
It shows the same process freed sk and touched it illegally.
Commit e198987e7dd7 ("gtp: fix suspicious RCU usage") added lock_sock() and release_sock() in __gtp_encap_destroy() to protect sk->sk_user_data, but release_sock() is called after sock_put() releases the last refcnt.
[0]: BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:96 [inline] BUG: KASAN: slab-use-after-free in atomic_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:541 [inline] BUG: KASAN: slab-use-after-free in queued_spin_lock include/asm-generic/qspinlock.h:111 [inline] BUG: KASAN: slab-use-after-free in do_raw_spin_lock include/linux/spinlock.h:186 [inline] BUG: KASAN: slab-use-after-free in __raw_spin_lock_bh include/linux/spinlock_api_smp.h:127 [inline] BUG: KASAN: slab-use-after-free in _raw_spin_lock_bh+0x75/0xe0 kernel/locking/spinlock.c:178 Write of size 4 at addr ffff88800dbef398 by task syz-executor.2/2401
CPU: 1 PID: 2401 Comm: syz-executor.2 Not tainted 6.4.0-rc5-01219-gfa0e21fa4443 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x72/0xa0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:351 [inline] print_report+0xcc/0x620 mm/kasan/report.c:462 kasan_report+0xb2/0xe0 mm/kasan/report.c:572 check_region_inline mm/kasan/generic.c:181 [inline] kasan_check_range+0x39/0x1c0 mm/kasan/generic.c:187 instrument_atomic_read_write include/linux/instrumented.h:96 [inline] atomic_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:541 [inline] queued_spin_lock include/asm-generic/qspinlock.h:111 [inline] do_raw_spin_lock include/linux/spinlock.h:186 [inline] __raw_spin_lock_bh include/linux/spinlock_api_smp.h:127 [inline] _raw_spin_lock_bh+0x75/0xe0 kernel/locking/spinlock.c:178 spin_lock_bh include/linux/spinlock.h:355 [inline] release_sock+0x1f/0x1a0 net/core/sock.c:3526 gtp_encap_disable_sock drivers/net/gtp.c:651 [inline] gtp_encap_disable+0xb9/0x220 drivers/net/gtp.c:664 gtp_dev_uninit+0x19/0x50 drivers/net/gtp.c:728 unregister_netdevice_many_notify+0x97e/0x1520 net/core/dev.c:10841 rtnl_delete_link net/core/rtnetlink.c:3216 [inline] rtnl_dellink+0x3c0/0xb30 net/core/rtnetlink.c:3268 rtnetlink_rcv_msg+0x450/0xb10 net/core/rtnetlink.c:6423 netlink_rcv_skb+0x15d/0x450 net/netlink/af_netlink.c:2548 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x700/0x930 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x91c/0xe30 net/netlink/af_netlink.c:1913 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0x1b7/0x200 net/socket.c:747 ____sys_sendmsg+0x75a/0x990 net/socket.c:2493 ___sys_sendmsg+0x11d/0x1c0 net/socket.c:2547 __sys_sendmsg+0xfe/0x1d0 net/socket.c:2576 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc RIP: 0033:0x7f1168b1fe5d Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48 RSP: 002b:00007f1167edccc8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00000000004bbf80 RCX: 00007f1168b1fe5d RDX: 0000000000000000 RSI: 00000000200002c0 RDI: 0000000000000003 RBP: 00000000004bbf80 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007f1168b80530 R15: 0000000000000000 </TASK>
Allocated by task 1483: kasan_save_stack+0x22/0x50 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 __kasan_slab_alloc+0x59/0x70 mm/kasan/common.c:328 kasan_slab_alloc include/linux/kasan.h:186 [inline] slab_post_alloc_hook mm/slab.h:711 [inline] slab_alloc_node mm/slub.c:3451 [inline] slab_alloc mm/slub.c:3459 [inline] __kmem_cache_alloc_lru mm/slub.c:3466 [inline] kmem_cache_alloc+0x16d/0x340 mm/slub.c:3475 sk_prot_alloc+0x5f/0x280 net/core/sock.c:2073 sk_alloc+0x34/0x6c0 net/core/sock.c:2132 inet6_create net/ipv6/af_inet6.c:192 [inline] inet6_create+0x2c7/0xf20 net/ipv6/af_inet6.c:119 __sock_create+0x2a1/0x530 net/socket.c:1535 sock_create net/socket.c:1586 [inline] __sys_socket_create net/socket.c:1623 [inline] __sys_socket_create net/socket.c:1608 [inline] __sys_socket+0x137/0x250 net/socket.c:1651 __do_sys_socket net/socket.c:1664 [inline] __se_sys_socket net/socket.c:1662 [inline] __x64_sys_socket+0x72/0xb0 net/socket.c:1662 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
Freed by task 2401: kasan_save_stack+0x22/0x50 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2e/0x50 mm/kasan/generic.c:521 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free mm/kasan/common.c:200 [inline] __kasan_slab_free+0x10c/0x1b0 mm/kasan/common.c:244 kasan_slab_free include/linux/kasan.h:162 [inline] slab_free_hook mm/slub.c:1781 [inline] slab_free_freelist_hook mm/slub.c:1807 [inline] slab_free mm/slub.c:3786 [inline] kmem_cache_free+0xb4/0x490 mm/slub.c:3808 sk_prot_free net/core/sock.c:2113 [inline] __sk_destruct+0x500/0x720 net/core/sock.c:2207 sk_destruct+0xc1/0xe0 net/core/sock.c:2222 __sk_free+0xed/0x3d0 net/core/sock.c:2233 sk_free+0x7c/0xa0 net/core/sock.c:2244 sock_put include/net/sock.h:1981 [inline] __gtp_encap_destroy+0x165/0x1b0 drivers/net/gtp.c:634 gtp_encap_disable_sock drivers/net/gtp.c:651 [inline] gtp_encap_disable+0xb9/0x220 drivers/net/gtp.c:664 gtp_dev_uninit+0x19/0x50 drivers/net/gtp.c:728 unregister_netdevice_many_notify+0x97e/0x1520 net/core/dev.c:10841 rtnl_delete_link net/core/rtnetlink.c:3216 [inline] rtnl_dellink+0x3c0/0xb30 net/core/rtnetlink.c:3268 rtnetlink_rcv_msg+0x450/0xb10 net/core/rtnetlink.c:6423 netlink_rcv_skb+0x15d/0x450 net/netlink/af_netlink.c:2548 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x700/0x930 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x91c/0xe30 net/netlink/af_netlink.c:1913 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0x1b7/0x200 net/socket.c:747 ____sys_sendmsg+0x75a/0x990 net/socket.c:2493 ___sys_sendmsg+0x11d/0x1c0 net/socket.c:2547 __sys_sendmsg+0xfe/0x1d0 net/socket.c:2576 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
The buggy address belongs to the object at ffff88800dbef300 which belongs to the cache UDPv6 of size 1344 The buggy address is located 152 bytes inside of freed 1344-byte region [ffff88800dbef300, ffff88800dbef840)
The buggy address belongs to the physical page: page:00000000d31bfed5 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff88800dbeed40 pfn:0xdbe8 head:00000000d31bfed5 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 memcg:ffff888008ee0801 flags: 0x100000000010200(slab|head|node=0|zone=1) page_type: 0xffffffff() raw: 0100000000010200 ffff88800c7a3000 dead000000000122 0000000000000000 raw: ffff88800dbeed40 0000000080160015 00000001ffffffff ffff888008ee0801 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff88800dbef280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff88800dbef300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88800dbef380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^ ffff88800dbef400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88800dbef480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
Fixes: e198987e7dd7 ("gtp: fix suspicious RCU usage") Reported-by: syzkaller syzkaller@googlegroups.com Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: Pablo Neira Ayuso pablo@netfilter.org Link: https://lore.kernel.org/r/20230622213231.24651-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/gtp.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 30e0a10595a16..a3878aef0ea4a 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -298,7 +298,9 @@ static void __gtp_encap_destroy(struct sock *sk) gtp->sk1u = NULL; udp_sk(sk)->encap_type = 0; rcu_assign_sk_user_data(sk, NULL); + release_sock(sk); sock_put(sk); + return; } release_sock(sk); }
From: Maxim Kochetkov fido_max@inbox.ru
[ Upstream commit f1bc9fc4a06de0108e0dca2a9a7e99ba1fc632f9 ]
64-bit DMA detection will fail if axienet was started before (by boot loader, boot ROM, etc). In this state axienet will not start properly. XAXIDMA_TX_CDESC_OFFSET + 4 register (MM2S_CURDESC_MSB) is used to detect 64-bit DMA capability here. But datasheet says: When DMACR.RS is 1 (axienet is in enabled state), CURDESC_PTR becomes Read Only (RO) and is used to fetch the first descriptor. So iowrite32()/ioread32() trick to this register to detect 64-bit DMA will not work. So move axienet reset before 64-bit DMA detection.
Fixes: f735c40ed93c ("net: axienet: Autodetect 64-bit DMA capability") Signed-off-by: Maxim Kochetkov fido_max@inbox.ru Reviewed-by: Robert Hancock robert.hancock@calian.com Reviewed-by: Radhey Shyam Pandey radhey.shyam.pandey@amd.com Link: https://lore.kernel.org/r/20230622192245.116864-1-fido_max@inbox.ru Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index fbbbcfe0e891e..e7f6c29b8dd82 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -2075,6 +2075,11 @@ static int axienet_probe(struct platform_device *pdev) goto cleanup_clk; }
+ /* Reset core now that clocks are enabled, prior to accessing MDIO */ + ret = __axienet_device_reset(lp); + if (ret) + goto cleanup_clk; + /* Autodetect the need for 64-bit DMA pointers. * When the IP is configured for a bus width bigger than 32 bits, * writing the MSB registers is mandatory, even if they are all 0. @@ -2122,11 +2127,6 @@ static int axienet_probe(struct platform_device *pdev) lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD; lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
- /* Reset core now that clocks are enabled, prior to accessing MDIO */ - ret = __axienet_device_reset(lp); - if (ret) - goto cleanup_clk; - ret = axienet_mdio_setup(lp); if (ret) dev_warn(&pdev->dev,
From: Edward Cree ecree.xilinx@gmail.com
[ Upstream commit d1b355438b8325a486f087e506d412c4e852f37b ]
efx_net_stats() (.ndo_get_stats64) can be called during an ethtool selftest, during which time nic_data->mc_stats is NULL as the NIC has been fini'd. In this case do not attempt to fetch the latest stats from the hardware, else we will crash on a NULL dereference: BUG: kernel NULL pointer dereference, address: 0000000000000038 RIP efx_nic_update_stats abridged calltrace: efx_ef10_update_stats_pf efx_net_stats dev_get_stats dev_seq_printf_stats Skipping the read is safe, we will simply give out stale stats. To ensure that the free in efx_ef10_fini_nic() does not race against efx_ef10_update_stats_pf(), which could cause a TOCTTOU bug, take the efx->stats_lock in fini_nic (it is already held across update_stats).
Fixes: d3142c193dca ("sfc: refactor EF10 stats handling") Reviewed-by: Pieter Jansen van Vuuren pieter.jansen-van-vuuren@amd.com Signed-off-by: Edward Cree ecree.xilinx@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/sfc/ef10.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 302b97c2e617c..b20dbda37c7ef 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -1297,8 +1297,10 @@ static void efx_ef10_fini_nic(struct efx_nic *efx) { struct efx_ef10_nic_data *nic_data = efx->nic_data;
+ spin_lock_bh(&efx->stats_lock); kfree(nic_data->mc_stats); nic_data->mc_stats = NULL; + spin_unlock_bh(&efx->stats_lock); }
static int efx_ef10_init_nic(struct efx_nic *efx) @@ -1852,9 +1854,14 @@ static size_t efx_ef10_update_stats_pf(struct efx_nic *efx, u64 *full_stats,
efx_ef10_get_stat_mask(efx, mask);
- efx_nic_copy_stats(efx, nic_data->mc_stats); - efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, - mask, stats, nic_data->mc_stats, false); + /* If NIC was fini'd (probably resetting), then we can't read + * updated stats right now. + */ + if (nic_data->mc_stats) { + efx_nic_copy_stats(efx, nic_data->mc_stats); + efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, + mask, stats, nic_data->mc_stats, false); + }
/* Update derived statistics */ efx_nic_fix_nodesc_drop_stat(efx,
From: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com
[ Upstream commit ec10fd154d934cc4195da3cbd017a12817b41d51 ]
The llcp_sock_connect() error paths were using a mixed way of central exit (goto) and cleanup
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: David S. Miller davem@davemloft.net Stable-dep-of: 6709d4b7bc2e ("net: nfc: Fix use-after-free caused by nfc_llcp_find_local") Signed-off-by: Sasha Levin sashal@kernel.org --- net/nfc/llcp_sock.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c index 0b93a17b9f11f..fdf0856182c65 100644 --- a/net/nfc/llcp_sock.c +++ b/net/nfc/llcp_sock.c @@ -712,10 +712,8 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, llcp_sock->local = nfc_llcp_local_get(local); llcp_sock->ssap = nfc_llcp_get_local_ssap(local); if (llcp_sock->ssap == LLCP_SAP_MAX) { - nfc_llcp_local_put(llcp_sock->local); - llcp_sock->local = NULL; ret = -ENOMEM; - goto put_dev; + goto sock_llcp_put_local; }
llcp_sock->reserved_ssap = llcp_sock->ssap; @@ -760,8 +758,11 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
sock_llcp_release: nfc_llcp_put_ssap(local, llcp_sock->ssap); + +sock_llcp_put_local: nfc_llcp_local_put(llcp_sock->local); llcp_sock->local = NULL; + llcp_sock->dev = NULL;
put_dev: nfc_put_device(dev);
From: Lin Ma linma@zju.edu.cn
[ Upstream commit 6709d4b7bc2e079241fdef15d1160581c5261c10 ]
This commit fixes several use-after-free that caused by function nfc_llcp_find_local(). For example, one UAF can happen when below buggy time window occurs.
// nfc_genl_llc_get_params | // nfc_unregister_device | dev = nfc_get_device(idx); | device_lock(...) if (!dev) | dev->shutting_down = true; return -ENODEV; | device_unlock(...); | device_lock(...); | // nfc_llcp_unregister_device | nfc_llcp_find_local() nfc_llcp_find_local(...); | | local_cleanup() if (!local) { | rc = -ENODEV; | // nfc_llcp_local_put goto exit; | kref_put(.., local_release) } | | // local_release | list_del(&local->list) // nfc_genl_send_params | kfree() local->dev->idx !!!UAF!!! | |
and the crash trace for the one of the discussed UAF like:
BUG: KASAN: slab-use-after-free in nfc_genl_llc_get_params+0x72f/0x780 net/nfc/netlink.c:1045 Read of size 8 at addr ffff888105b0e410 by task 20114
Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x72/0xa0 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:319 [inline] print_report+0xcc/0x620 mm/kasan/report.c:430 kasan_report+0xb2/0xe0 mm/kasan/report.c:536 nfc_genl_send_params net/nfc/netlink.c:999 [inline] nfc_genl_llc_get_params+0x72f/0x780 net/nfc/netlink.c:1045 genl_family_rcv_msg_doit.isra.0+0x1ee/0x2e0 net/netlink/genetlink.c:968 genl_family_rcv_msg net/netlink/genetlink.c:1048 [inline] genl_rcv_msg+0x503/0x7d0 net/netlink/genetlink.c:1065 netlink_rcv_skb+0x161/0x430 net/netlink/af_netlink.c:2548 genl_rcv+0x28/0x40 net/netlink/genetlink.c:1076 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x644/0x900 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x934/0xe70 net/netlink/af_netlink.c:1913 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0x1b6/0x200 net/socket.c:747 ____sys_sendmsg+0x6e9/0x890 net/socket.c:2501 ___sys_sendmsg+0x110/0x1b0 net/socket.c:2555 __sys_sendmsg+0xf7/0x1d0 net/socket.c:2584 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc RIP: 0033:0x7f34640a2389 RSP: 002b:00007f3463415168 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00007f34641c1f80 RCX: 00007f34640a2389 RDX: 0000000000000000 RSI: 0000000020000240 RDI: 0000000000000006 RBP: 00007f34640ed493 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007ffe38449ecf R14: 00007f3463415300 R15: 0000000000022000 </TASK>
Allocated by task 20116: kasan_save_stack+0x22/0x50 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:374 [inline] __kasan_kmalloc+0x7f/0x90 mm/kasan/common.c:383 kmalloc include/linux/slab.h:580 [inline] kzalloc include/linux/slab.h:720 [inline] nfc_llcp_register_device+0x49/0xa40 net/nfc/llcp_core.c:1567 nfc_register_device+0x61/0x260 net/nfc/core.c:1124 nci_register_device+0x776/0xb20 net/nfc/nci/core.c:1257 virtual_ncidev_open+0x147/0x230 drivers/nfc/virtual_ncidev.c:148 misc_open+0x379/0x4a0 drivers/char/misc.c:165 chrdev_open+0x26c/0x780 fs/char_dev.c:414 do_dentry_open+0x6c4/0x12a0 fs/open.c:920 do_open fs/namei.c:3560 [inline] path_openat+0x24fe/0x37e0 fs/namei.c:3715 do_filp_open+0x1ba/0x410 fs/namei.c:3742 do_sys_openat2+0x171/0x4c0 fs/open.c:1356 do_sys_open fs/open.c:1372 [inline] __do_sys_openat fs/open.c:1388 [inline] __se_sys_openat fs/open.c:1383 [inline] __x64_sys_openat+0x143/0x200 fs/open.c:1383 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
Freed by task 20115: kasan_save_stack+0x22/0x50 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2e/0x50 mm/kasan/generic.c:521 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free mm/kasan/common.c:200 [inline] __kasan_slab_free+0x10a/0x190 mm/kasan/common.c:244 kasan_slab_free include/linux/kasan.h:162 [inline] slab_free_hook mm/slub.c:1781 [inline] slab_free_freelist_hook mm/slub.c:1807 [inline] slab_free mm/slub.c:3787 [inline] __kmem_cache_free+0x7a/0x190 mm/slub.c:3800 local_release net/nfc/llcp_core.c:174 [inline] kref_put include/linux/kref.h:65 [inline] nfc_llcp_local_put net/nfc/llcp_core.c:182 [inline] nfc_llcp_local_put net/nfc/llcp_core.c:177 [inline] nfc_llcp_unregister_device+0x206/0x290 net/nfc/llcp_core.c:1620 nfc_unregister_device+0x160/0x1d0 net/nfc/core.c:1179 virtual_ncidev_close+0x52/0xa0 drivers/nfc/virtual_ncidev.c:163 __fput+0x252/0xa20 fs/file_table.c:321 task_work_run+0x174/0x270 kernel/task_work.c:179 resume_user_mode_work include/linux/resume_user_mode.h:49 [inline] exit_to_user_mode_loop kernel/entry/common.c:171 [inline] exit_to_user_mode_prepare+0x108/0x110 kernel/entry/common.c:204 __syscall_exit_to_user_mode_work kernel/entry/common.c:286 [inline] syscall_exit_to_user_mode+0x21/0x50 kernel/entry/common.c:297 do_syscall_64+0x4c/0x90 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x72/0xdc
Last potentially related work creation: kasan_save_stack+0x22/0x50 mm/kasan/common.c:45 __kasan_record_aux_stack+0x95/0xb0 mm/kasan/generic.c:491 kvfree_call_rcu+0x29/0xa80 kernel/rcu/tree.c:3328 drop_sysctl_table+0x3be/0x4e0 fs/proc/proc_sysctl.c:1735 unregister_sysctl_table.part.0+0x9c/0x190 fs/proc/proc_sysctl.c:1773 unregister_sysctl_table+0x24/0x30 fs/proc/proc_sysctl.c:1753 neigh_sysctl_unregister+0x5f/0x80 net/core/neighbour.c:3895 addrconf_notify+0x140/0x17b0 net/ipv6/addrconf.c:3684 notifier_call_chain+0xbe/0x210 kernel/notifier.c:87 call_netdevice_notifiers_info+0xb5/0x150 net/core/dev.c:1937 call_netdevice_notifiers_extack net/core/dev.c:1975 [inline] call_netdevice_notifiers net/core/dev.c:1989 [inline] dev_change_name+0x3c3/0x870 net/core/dev.c:1211 dev_ifsioc+0x800/0xf70 net/core/dev_ioctl.c:376 dev_ioctl+0x3d9/0xf80 net/core/dev_ioctl.c:542 sock_do_ioctl+0x160/0x260 net/socket.c:1213 sock_ioctl+0x3f9/0x670 net/socket.c:1316 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:870 [inline] __se_sys_ioctl fs/ioctl.c:856 [inline] __x64_sys_ioctl+0x19e/0x210 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
The buggy address belongs to the object at ffff888105b0e400 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 16 bytes inside of freed 1024-byte region [ffff888105b0e400, ffff888105b0e800)
The buggy address belongs to the physical page: head:ffffea000416c200 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0x200000000010200(slab|head|node=0|zone=2) raw: 0200000000010200 ffff8881000430c0 ffffea00044c7010 ffffea0004510e10 raw: 0000000000000000 00000000000a000a 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff888105b0e300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff888105b0e380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff888105b0e400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^ ffff888105b0e480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888105b0e500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
In summary, this patch solves those use-after-free by
1. Re-implement the nfc_llcp_find_local(). The current version does not grab the reference when getting the local from the linked list. For example, the llcp_sock_bind() gets the reference like below:
// llcp_sock_bind()
local = nfc_llcp_find_local(dev); // A ..... \ | raceable ..... / llcp_sock->local = nfc_llcp_local_get(local); // B
There is an apparent race window that one can drop the reference and free the local object fetched in (A) before (B) gets the reference.
2. Some callers of the nfc_llcp_find_local() do not grab the reference at all. For example, the nfc_genl_llc_{{get/set}_params/sdreq} functions. We add the nfc_llcp_local_put() for them. Moreover, we add the necessary error handling function to put the reference.
3. Add the nfc_llcp_remove_local() helper. The local object is removed from the linked list in local_release() when all reference is gone. This patch removes it when nfc_llcp_unregister_device() is called.
Therefore, every caller of nfc_llcp_find_local() will get a reference even when the nfc_llcp_unregister_device() is called. This promises no use-after-free for the local object is ever possible.
Fixes: 52feb444a903 ("NFC: Extend netlink interface for LTO, RW, and MIUX parameters support") Fixes: c7aa12252f51 ("NFC: Take a reference on the LLCP local pointer when creating a socket") Signed-off-by: Lin Ma linma@zju.edu.cn Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/nfc/llcp.h | 1 - net/nfc/llcp_commands.c | 12 +++++++--- net/nfc/llcp_core.c | 49 +++++++++++++++++++++++++++++++++++------ net/nfc/llcp_sock.c | 18 ++++++++------- net/nfc/netlink.c | 20 ++++++++++++----- net/nfc/nfc.h | 1 + 6 files changed, 77 insertions(+), 24 deletions(-)
diff --git a/net/nfc/llcp.h b/net/nfc/llcp.h index d49d4bf2e37c8..a81893bc06ce8 100644 --- a/net/nfc/llcp.h +++ b/net/nfc/llcp.h @@ -202,7 +202,6 @@ void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *s); void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *s); void nfc_llcp_socket_remote_param_init(struct nfc_llcp_sock *sock); struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); -struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local); int nfc_llcp_local_put(struct nfc_llcp_local *local); u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, struct nfc_llcp_sock *sock); diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c index bb9f40563ff63..5b8754ae7d3af 100644 --- a/net/nfc/llcp_commands.c +++ b/net/nfc/llcp_commands.c @@ -361,6 +361,7 @@ int nfc_llcp_send_symm(struct nfc_dev *dev) struct sk_buff *skb; struct nfc_llcp_local *local; u16 size = 0; + int err;
pr_debug("Sending SYMM\n");
@@ -372,8 +373,10 @@ int nfc_llcp_send_symm(struct nfc_dev *dev) size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE;
skb = alloc_skb(size, GFP_KERNEL); - if (skb == NULL) - return -ENOMEM; + if (skb == NULL) { + err = -ENOMEM; + goto out; + }
skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
@@ -383,8 +386,11 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
nfc_llcp_send_to_raw_sock(local, skb, NFC_DIRECTION_TX);
- return nfc_data_exchange(dev, local->target_idx, skb, + err = nfc_data_exchange(dev, local->target_idx, skb, nfc_llcp_recv, local); +out: + nfc_llcp_local_put(local); + return err; }
int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c index fd43e75abd948..ddfd159f64e13 100644 --- a/net/nfc/llcp_core.c +++ b/net/nfc/llcp_core.c @@ -17,6 +17,8 @@ static u8 llcp_magic[3] = {0x46, 0x66, 0x6d};
static LIST_HEAD(llcp_devices); +/* Protects llcp_devices list */ +static DEFINE_SPINLOCK(llcp_devices_lock);
static void nfc_llcp_rx_skb(struct nfc_llcp_local *local, struct sk_buff *skb);
@@ -143,7 +145,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device, write_unlock(&local->raw_sockets.lock); }
-struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) +static struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) { kref_get(&local->ref);
@@ -171,7 +173,6 @@ static void local_release(struct kref *ref)
local = container_of(ref, struct nfc_llcp_local, ref);
- list_del(&local->list); local_cleanup(local); kfree(local); } @@ -284,12 +285,33 @@ static void nfc_llcp_sdreq_timer(struct timer_list *t) struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev) { struct nfc_llcp_local *local; + struct nfc_llcp_local *res = NULL;
+ spin_lock(&llcp_devices_lock); list_for_each_entry(local, &llcp_devices, list) - if (local->dev == dev) + if (local->dev == dev) { + res = nfc_llcp_local_get(local); + break; + } + spin_unlock(&llcp_devices_lock); + + return res; +} + +static struct nfc_llcp_local *nfc_llcp_remove_local(struct nfc_dev *dev) +{ + struct nfc_llcp_local *local, *tmp; + + spin_lock(&llcp_devices_lock); + list_for_each_entry_safe(local, tmp, &llcp_devices, list) + if (local->dev == dev) { + list_del(&local->list); + spin_unlock(&llcp_devices_lock); return local; + } + spin_unlock(&llcp_devices_lock);
- pr_debug("No device found\n"); + pr_warn("Shutting down device not found\n");
return NULL; } @@ -610,12 +632,15 @@ u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len)
*general_bytes_len = local->gb_len;
+ nfc_llcp_local_put(local); + return local->gb; }
int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len) { struct nfc_llcp_local *local; + int err;
if (gb_len < 3 || gb_len > NFC_MAX_GT_LEN) return -EINVAL; @@ -632,12 +657,16 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
if (memcmp(local->remote_gb, llcp_magic, 3)) { pr_err("MAC does not support LLCP\n"); - return -EINVAL; + err = -EINVAL; + goto out; }
- return nfc_llcp_parse_gb_tlv(local, + err = nfc_llcp_parse_gb_tlv(local, &local->remote_gb[3], local->remote_gb_len - 3); +out: + nfc_llcp_local_put(local); + return err; }
static u8 nfc_llcp_dsap(const struct sk_buff *pdu) @@ -1527,6 +1556,8 @@ int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb)
__nfc_llcp_recv(local, skb);
+ nfc_llcp_local_put(local); + return 0; }
@@ -1543,6 +1574,8 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
/* Close and purge all existing sockets */ nfc_llcp_socket_release(local, true, 0); + + nfc_llcp_local_put(local); }
void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, @@ -1568,6 +1601,8 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, mod_timer(&local->link_timer, jiffies + msecs_to_jiffies(local->remote_lto)); } + + nfc_llcp_local_put(local); }
int nfc_llcp_register_device(struct nfc_dev *ndev) @@ -1618,7 +1653,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
void nfc_llcp_unregister_device(struct nfc_dev *dev) { - struct nfc_llcp_local *local = nfc_llcp_find_local(dev); + struct nfc_llcp_local *local = nfc_llcp_remove_local(dev);
if (local == NULL) { pr_debug("No such device\n"); diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c index fdf0856182c65..6e1fba2084930 100644 --- a/net/nfc/llcp_sock.c +++ b/net/nfc/llcp_sock.c @@ -99,7 +99,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) }
llcp_sock->dev = dev; - llcp_sock->local = nfc_llcp_local_get(local); + llcp_sock->local = local; llcp_sock->nfc_protocol = llcp_addr.nfc_protocol; llcp_sock->service_name_len = min_t(unsigned int, llcp_addr.service_name_len, @@ -181,7 +181,7 @@ static int llcp_raw_sock_bind(struct socket *sock, struct sockaddr *addr, }
llcp_sock->dev = dev; - llcp_sock->local = nfc_llcp_local_get(local); + llcp_sock->local = local; llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
nfc_llcp_sock_link(&local->raw_sockets, sk); @@ -698,22 +698,22 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, if (dev->dep_link_up == false) { ret = -ENOLINK; device_unlock(&dev->dev); - goto put_dev; + goto sock_llcp_put_local; } device_unlock(&dev->dev);
if (local->rf_mode == NFC_RF_INITIATOR && addr->target_idx != local->target_idx) { ret = -ENOLINK; - goto put_dev; + goto sock_llcp_put_local; }
llcp_sock->dev = dev; - llcp_sock->local = nfc_llcp_local_get(local); + llcp_sock->local = local; llcp_sock->ssap = nfc_llcp_get_local_ssap(local); if (llcp_sock->ssap == LLCP_SAP_MAX) { ret = -ENOMEM; - goto sock_llcp_put_local; + goto sock_llcp_nullify; }
llcp_sock->reserved_ssap = llcp_sock->ssap; @@ -759,11 +759,13 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, sock_llcp_release: nfc_llcp_put_ssap(local, llcp_sock->ssap);
-sock_llcp_put_local: - nfc_llcp_local_put(llcp_sock->local); +sock_llcp_nullify: llcp_sock->local = NULL; llcp_sock->dev = NULL;
+sock_llcp_put_local: + nfc_llcp_local_put(local); + put_dev: nfc_put_device(dev);
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 9bc0ab759ea44..eb4f70a827e4d 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -1039,11 +1039,14 @@ static int nfc_genl_llc_get_params(struct sk_buff *skb, struct genl_info *info) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) { rc = -ENOMEM; - goto exit; + goto put_local; }
rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq);
+put_local: + nfc_llcp_local_put(local); + exit: device_unlock(&dev->dev);
@@ -1105,7 +1108,7 @@ static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) { if (dev->dep_link_up) { rc = -EINPROGRESS; - goto exit; + goto put_local; }
local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]); @@ -1117,6 +1120,9 @@ static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) local->miux = cpu_to_be16(miux);
+put_local: + nfc_llcp_local_put(local); + exit: device_unlock(&dev->dev);
@@ -1172,7 +1178,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
if (rc != 0) { rc = -EINVAL; - goto exit; + goto put_local; }
if (!sdp_attrs[NFC_SDP_ATTR_URI]) @@ -1191,7 +1197,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info) sdreq = nfc_llcp_build_sdreq_tlv(tid, uri, uri_len); if (sdreq == NULL) { rc = -ENOMEM; - goto exit; + goto put_local; }
tlvs_len += sdreq->tlv_len; @@ -1201,10 +1207,14 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
if (hlist_empty(&sdreq_list)) { rc = -EINVAL; - goto exit; + goto put_local; }
rc = nfc_llcp_send_snl_sdreq(local, &sdreq_list, tlvs_len); + +put_local: + nfc_llcp_local_put(local); + exit: device_unlock(&dev->dev);
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index de2ec66d7e83a..0b1e6466f4fbf 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h @@ -52,6 +52,7 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len); u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb); struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); +int nfc_llcp_local_put(struct nfc_llcp_local *local); int __init nfc_llcp_init(void); void nfc_llcp_exit(void); void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp);
From: Jeremy Sowden jeremy@azazel.net
[ Upstream commit 6f67fbf8192da80c4db01a1800c7fceaca9cf1f9 ]
The `shift` variable which indicates the offset in the string at which to start matching the pattern is initialized to `bm->patlen - 1`, but it is not reset when a new block is retrieved. This means the implemen- tation may start looking at later and later positions in each successive block and miss occurrences of the pattern at the beginning. E.g., consider a HTTP packet held in a non-linear skb, where the HTTP request line occurs in the second block:
[... 52 bytes of packet headers ...] GET /bmtest HTTP/1.1\r\nHost: www.example.com\r\n\r\n
and the pattern is "GET /bmtest".
Once the first block comprising the packet headers has been examined, `shift` will be pointing to somewhere near the end of the block, and so when the second block is examined the request line at the beginning will be missed.
Reinitialize the variable for each new block.
Fixes: 8082e4ed0a61 ("[LIB]: Boyer-Moore extension for textsearch infrastructure strike #2") Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1390 Signed-off-by: Jeremy Sowden jeremy@azazel.net Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/ts_bm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/ts_bm.c b/lib/ts_bm.c index 4cf250031f0f0..352ae837e0317 100644 --- a/lib/ts_bm.c +++ b/lib/ts_bm.c @@ -60,10 +60,12 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state) struct ts_bm *bm = ts_config_priv(conf); unsigned int i, text_len, consumed = state->offset; const u8 *text; - int shift = bm->patlen - 1, bs; + int bs; const u8 icase = conf->flags & TS_IGNORECASE;
for (;;) { + int shift = bm->patlen - 1; + text_len = conf->get_next_block(consumed, &text, conf, state);
if (unlikely(text_len == 0))
From: Florian Westphal fw@strlen.de
[ Upstream commit ff0a3a7d52ff7282dbd183e7fc29a1fe386b0c30 ]
Eric Dumazet says: nf_conntrack_dccp_packet() has an unique:
dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
And nothing more is 'pulled' from the packet, depending on the content. dh->dccph_doff, and/or dh->dccph_x ...) So dccp_ack_seq() is happily reading stuff past the _dh buffer.
BUG: KASAN: stack-out-of-bounds in nf_conntrack_dccp_packet+0x1134/0x11c0 Read of size 4 at addr ffff000128f66e0c by task syz-executor.2/29371 [..]
Fix this by increasing the stack buffer to also include room for the extra sequence numbers and all the known dccp packet type headers, then pull again after the initial validation of the basic header.
While at it, mark packets invalid that lack 48bit sequence bit but where RFC says the type MUST use them.
Compile tested only.
v2: first skb_header_pointer() now needs to adjust the size to only pull the generic header. (Eric)
Heads-up: I intend to remove dccp conntrack support later this year.
Fixes: 2bc780499aa3 ("[NETFILTER]: nf_conntrack: add DCCP protocol support") Reported-by: Eric Dumazet edumazet@google.com Signed-off-by: Florian Westphal fw@strlen.de Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nf_conntrack_proto_dccp.c | 52 +++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c index c1557d47ccd1e..d4fd626d2b8c3 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c @@ -432,9 +432,19 @@ static bool dccp_error(const struct dccp_hdr *dh, struct sk_buff *skb, unsigned int dataoff, const struct nf_hook_state *state) { + static const unsigned long require_seq48 = 1 << DCCP_PKT_REQUEST | + 1 << DCCP_PKT_RESPONSE | + 1 << DCCP_PKT_CLOSEREQ | + 1 << DCCP_PKT_CLOSE | + 1 << DCCP_PKT_RESET | + 1 << DCCP_PKT_SYNC | + 1 << DCCP_PKT_SYNCACK; unsigned int dccp_len = skb->len - dataoff; unsigned int cscov; const char *msg; + u8 type; + + BUILD_BUG_ON(DCCP_PKT_INVALID >= BITS_PER_LONG);
if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) || dh->dccph_doff * 4 > dccp_len) { @@ -459,34 +469,70 @@ static bool dccp_error(const struct dccp_hdr *dh, goto out_invalid; }
- if (dh->dccph_type >= DCCP_PKT_INVALID) { + type = dh->dccph_type; + if (type >= DCCP_PKT_INVALID) { msg = "nf_ct_dccp: reserved packet type "; goto out_invalid; } + + if (test_bit(type, &require_seq48) && !dh->dccph_x) { + msg = "nf_ct_dccp: type lacks 48bit sequence numbers"; + goto out_invalid; + } + return false; out_invalid: nf_l4proto_log_invalid(skb, state, IPPROTO_DCCP, "%s", msg); return true; }
+struct nf_conntrack_dccp_buf { + struct dccp_hdr dh; /* generic header part */ + struct dccp_hdr_ext ext; /* optional depending dh->dccph_x */ + union { /* depends on header type */ + struct dccp_hdr_ack_bits ack; + struct dccp_hdr_request req; + struct dccp_hdr_response response; + struct dccp_hdr_reset rst; + } u; +}; + +static struct dccp_hdr * +dccp_header_pointer(const struct sk_buff *skb, int offset, const struct dccp_hdr *dh, + struct nf_conntrack_dccp_buf *buf) +{ + unsigned int hdrlen = __dccp_hdr_len(dh); + + if (hdrlen > sizeof(*buf)) + return NULL; + + return skb_header_pointer(skb, offset, hdrlen, buf); +} + int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb, unsigned int dataoff, enum ip_conntrack_info ctinfo, const struct nf_hook_state *state) { enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); - struct dccp_hdr _dh, *dh; + struct nf_conntrack_dccp_buf _dh; u_int8_t type, old_state, new_state; enum ct_dccp_roles role; unsigned int *timeouts; + struct dccp_hdr *dh;
- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh); + dh = skb_header_pointer(skb, dataoff, sizeof(*dh), &_dh.dh); if (!dh) return NF_DROP;
if (dccp_error(dh, skb, dataoff, state)) return -NF_ACCEPT;
+ /* pull again, including possible 48 bit sequences and subtype header */ + dh = dccp_header_pointer(skb, dataoff, dh, &_dh); + if (!dh) + return NF_DROP; + type = dh->dccph_type; if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh, state)) return -NF_ACCEPT;
From: Ilia.Gavrilov Ilia.Gavrilov@infotecs.ru
[ Upstream commit f188d30087480eab421cd8ca552fb15f55d57f4d ]
ct_sip_parse_numerical_param() returns only 0 or 1 now. But process_register_request() and process_register_response() imply checking for a negative value if parsing of a numerical header parameter failed. The invocation in nf_nat_sip() looks correct: if (ct_sip_parse_numerical_param(...) > 0 && ...) { ... }
Make the return value of the function ct_sip_parse_numerical_param() a tristate to fix all the cases a) return 1 if value is found; *val is set b) return 0 if value is not found; *val is unchanged c) return -1 on error; *val is undefined
Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 0f32a40fc91a ("[NETFILTER]: nf_conntrack_sip: create signalling expectations") Signed-off-by: Ilia.Gavrilov Ilia.Gavrilov@infotecs.ru Reviewed-by: Simon Horman simon.horman@corigine.com Reviewed-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nf_conntrack_sip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 78fd9122b70c7..751df19fe0f8a 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -611,7 +611,7 @@ int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr, start += strlen(name); *val = simple_strtoul(start, &end, 0); if (start == end) - return 0; + return -1; if (matchoff && matchlen) { *matchoff = start - dptr; *matchlen = end - start;
From: Cambda Zhu cambda@linux.alibaba.com
[ Upstream commit 8a9922e7be6d042fa00f894c376473b17a162b66 ]
ipvlan_queue_xmit() should return NET_XMIT_XXX, but ipvlan_xmit_mode_l2/l3() returns rx_handler_result_t or NET_RX_XXX in some cases. ipvlan_rcv_frame() will only return RX_HANDLER_CONSUMED in ipvlan_xmit_mode_l2/l3() because 'local' is true. It's equal to NET_XMIT_SUCCESS. But dev_forward_skb() can return NET_RX_SUCCESS or NET_RX_DROP, and returning NET_RX_DROP(NET_XMIT_DROP) will increase both ipvlan and ipvlan->phy_dev drops counter.
The skb to forward can be treated as xmitted successfully. This patch makes ipvlan_queue_xmit() return NET_XMIT_SUCCESS for forward skb.
Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.") Signed-off-by: Cambda Zhu cambda@linux.alibaba.com Link: https://lore.kernel.org/r/20230626093347.7492-1-cambda@linux.alibaba.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ipvlan/ipvlan_core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index 1f5125698e83a..e10cb98b0f4f5 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -586,7 +586,8 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev) consume_skb(skb); return NET_XMIT_DROP; } - return ipvlan_rcv_frame(addr, &skb, true); + ipvlan_rcv_frame(addr, &skb, true); + return NET_XMIT_SUCCESS; } } out: @@ -612,7 +613,8 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) consume_skb(skb); return NET_XMIT_DROP; } - return ipvlan_rcv_frame(addr, &skb, true); + ipvlan_rcv_frame(addr, &skb, true); + return NET_XMIT_SUCCESS; } } skb = skb_share_check(skb, GFP_ATOMIC); @@ -624,7 +626,8 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) * the skb for the main-dev. At the RX side we just return * RX_PASS for it to be processed further on the stack. */ - return dev_forward_skb(ipvlan->phy_dev, skb); + dev_forward_skb(ipvlan->phy_dev, skb); + return NET_XMIT_SUCCESS;
} else if (is_multicast_ether_addr(eth->h_dest)) { skb_reset_mac_header(skb);
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit 25a9c8a4431c364f97f75558cb346d2ad3f53fbb ]
syzbot reported a warning in __local_bh_enable_ip(). [0]
Commit 8d61f926d420 ("netlink: fix potential deadlock in netlink_set_err()") converted read_lock(&nl_table_lock) to read_lock_irqsave() in __netlink_diag_dump() to prevent a deadlock.
However, __netlink_diag_dump() calls sock_i_ino() that uses read_lock_bh() and read_unlock_bh(). If CONFIG_TRACE_IRQFLAGS=y, read_unlock_bh() finally enables IRQ even though it should stay disabled until the following read_unlock_irqrestore().
Using read_lock() in sock_i_ino() would trigger a lockdep splat in another place that was fixed in commit f064af1e500a ("net: fix a lockdep splat"), so let's add __sock_i_ino() that would be safe to use under BH disabled.
[0]: WARNING: CPU: 0 PID: 5012 at kernel/softirq.c:376 __local_bh_enable_ip+0xbe/0x130 kernel/softirq.c:376 Modules linked in: CPU: 0 PID: 5012 Comm: syz-executor487 Not tainted 6.4.0-rc7-syzkaller-00202-g6f68fc395f49 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023 RIP: 0010:__local_bh_enable_ip+0xbe/0x130 kernel/softirq.c:376 Code: 45 bf 01 00 00 00 e8 91 5b 0a 00 e8 3c 15 3d 00 fb 65 8b 05 ec e9 b5 7e 85 c0 74 58 5b 5d c3 65 8b 05 b2 b6 b4 7e 85 c0 75 a2 <0f> 0b eb 9e e8 89 15 3d 00 eb 9f 48 89 ef e8 6f 49 18 00 eb a8 0f RSP: 0018:ffffc90003a1f3d0 EFLAGS: 00010046 RAX: 0000000000000000 RBX: 0000000000000201 RCX: 1ffffffff1cf5996 RDX: 0000000000000000 RSI: 0000000000000201 RDI: ffffffff8805c6f3 RBP: ffffffff8805c6f3 R08: 0000000000000001 R09: ffff8880152b03a3 R10: ffffed1002a56074 R11: 0000000000000005 R12: 00000000000073e4 R13: dffffc0000000000 R14: 0000000000000002 R15: 0000000000000000 FS: 0000555556726300(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000000045ad50 CR3: 000000007c646000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> sock_i_ino+0x83/0xa0 net/core/sock.c:2559 __netlink_diag_dump+0x45c/0x790 net/netlink/diag.c:171 netlink_diag_dump+0xd6/0x230 net/netlink/diag.c:207 netlink_dump+0x570/0xc50 net/netlink/af_netlink.c:2269 __netlink_dump_start+0x64b/0x910 net/netlink/af_netlink.c:2374 netlink_dump_start include/linux/netlink.h:329 [inline] netlink_diag_handler_dump+0x1ae/0x250 net/netlink/diag.c:238 __sock_diag_cmd net/core/sock_diag.c:238 [inline] sock_diag_rcv_msg+0x31e/0x440 net/core/sock_diag.c:269 netlink_rcv_skb+0x165/0x440 net/netlink/af_netlink.c:2547 sock_diag_rcv+0x2a/0x40 net/core/sock_diag.c:280 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x547/0x7f0 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x925/0xe30 net/netlink/af_netlink.c:1914 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0xde/0x190 net/socket.c:747 ____sys_sendmsg+0x71c/0x900 net/socket.c:2503 ___sys_sendmsg+0x110/0x1b0 net/socket.c:2557 __sys_sendmsg+0xf7/0x1c0 net/socket.c:2586 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f5303aaabb9 Code: 28 c3 e8 2a 14 00 00 66 2e 0f 1f 84 00 00 00 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffc7506e548 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f5303aaabb9 RDX: 0000000000000000 RSI: 0000000020000180 RDI: 0000000000000003 RBP: 00007f5303a6ed60 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007f5303a6edf0 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 </TASK>
Fixes: 8d61f926d420 ("netlink: fix potential deadlock in netlink_set_err()") Reported-by: syzbot+5da61cf6a9bc1902d422@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=5da61cf6a9bc1902d422 Suggested-by: Eric Dumazet edumazet@google.com Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: Eric Dumazet edumazet@google.com Link: https://lore.kernel.org/r/20230626164313.52528-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/sock.h | 1 + net/core/sock.c | 17 ++++++++++++++--- net/netlink/diag.c | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h index 0eb6a4d07a4d1..93a6717213aeb 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2004,6 +2004,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) }
kuid_t sock_i_uid(struct sock *sk); +unsigned long __sock_i_ino(struct sock *sk); unsigned long sock_i_ino(struct sock *sk);
static inline kuid_t sock_net_uid(const struct net *net, const struct sock *sk) diff --git a/net/core/sock.c b/net/core/sock.c index 93fb3d64f48ee..cf1e437ae4875 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2324,13 +2324,24 @@ kuid_t sock_i_uid(struct sock *sk) } EXPORT_SYMBOL(sock_i_uid);
-unsigned long sock_i_ino(struct sock *sk) +unsigned long __sock_i_ino(struct sock *sk) { unsigned long ino;
- read_lock_bh(&sk->sk_callback_lock); + read_lock(&sk->sk_callback_lock); ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0; - read_unlock_bh(&sk->sk_callback_lock); + read_unlock(&sk->sk_callback_lock); + return ino; +} +EXPORT_SYMBOL(__sock_i_ino); + +unsigned long sock_i_ino(struct sock *sk) +{ + unsigned long ino; + + local_bh_disable(); + ino = __sock_i_ino(sk); + local_bh_enable(); return ino; } EXPORT_SYMBOL(sock_i_ino); diff --git a/net/netlink/diag.c b/net/netlink/diag.c index 4143b2ea4195a..e4f21b1067bcc 100644 --- a/net/netlink/diag.c +++ b/net/netlink/diag.c @@ -168,7 +168,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NLM_F_MULTI, - sock_i_ino(sk)) < 0) { + __sock_i_ino(sk)) < 0) { ret = 1; break; }
From: Wesley Chalmers Wesley.Chalmers@amd.com
[ Upstream commit cd8f067a46d34dee3188da184912ae3d64d98444 ]
[WHY] Add log entry for when display refresh from MALL settings are sent to SMU.
Fixes: 1664641ea946 ("drm/amd/display: Add logger for SMU msg") Signed-off-by: Wesley Chalmers Wesley.Chalmers@amd.com Acked-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 --- .../drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c index 8ecc708bcd9ec..766759420eebb 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr_smu_msg.c @@ -302,6 +302,9 @@ void dcn30_smu_set_display_refresh_from_mall(struct clk_mgr_internal *clk_mgr, b /* bits 8:7 for cache timer scale, bits 6:1 for cache timer delay, bit 0 = 1 for enable, = 0 for disable */ uint32_t param = (cache_timer_scale << 7) | (cache_timer_delay << 1) | (enable ? 1 : 0);
+ smu_print("SMU Set display refresh from mall: enable = %d, cache_timer_delay = %d, cache_timer_scale = %d\n", + enable, cache_timer_delay, cache_timer_scale); + dcn30_smu_send_msg_with_param(clk_mgr, DALSMC_MSG_SetDisplayRefreshFromMall, param, NULL); }
From: Nikita Zhandarovich n.zhandarovich@fintech.ru
[ Upstream commit 20c3dffdccbd494e0dd631d1660aeecbff6775f2 ]
Several calls to ci_dpm_fini() will attempt to free resources that either have been freed before or haven't been allocated yet. This may lead to undefined or dangerous behaviour.
For instance, if r600_parse_extended_power_table() fails, it might call r600_free_extended_power_table() as will ci_dpm_fini() later during error handling.
Fix this by only freeing pointers to objects previously allocated.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
Fixes: cc8dbbb4f62a ("drm/radeon: add dpm support for CI dGPUs (v2)") Co-developed-by: Natalia Petrova n.petrova@fintech.ru Signed-off-by: Nikita Zhandarovich n.zhandarovich@fintech.ru Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/radeon/ci_dpm.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index f0cfb58da4672..4f93cc81ca7a0 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -5520,6 +5520,7 @@ static int ci_parse_power_table(struct radeon_device *rdev) u8 frev, crev; u8 *power_state_offset; struct ci_ps *ps; + int ret;
if (!atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset)) @@ -5549,11 +5550,15 @@ static int ci_parse_power_table(struct radeon_device *rdev) non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; - if (!rdev->pm.power_state[i].clock_info) - return -EINVAL; + if (!rdev->pm.power_state[i].clock_info) { + ret = -EINVAL; + goto err_free_ps; + } ps = kzalloc(sizeof(struct ci_ps), GFP_KERNEL); - if (ps == NULL) - return -ENOMEM; + if (ps == NULL) { + ret = -ENOMEM; + goto err_free_ps; + } rdev->pm.dpm.ps[i].ps_priv = ps; ci_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i], non_clock_info, @@ -5593,6 +5598,12 @@ static int ci_parse_power_table(struct radeon_device *rdev) }
return 0; + +err_free_ps: + for (i = 0; i < rdev->pm.dpm.num_ps; i++) + kfree(rdev->pm.dpm.ps[i].ps_priv); + kfree(rdev->pm.dpm.ps); + return ret; }
static int ci_get_vbios_boot_values(struct radeon_device *rdev, @@ -5681,25 +5692,26 @@ int ci_dpm_init(struct radeon_device *rdev)
ret = ci_get_vbios_boot_values(rdev, &pi->vbios_boot_state); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); return ret; }
ret = r600_get_platform_caps(rdev); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); return ret; }
ret = r600_parse_extended_power_table(rdev); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); return ret; }
ret = ci_parse_power_table(rdev); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); + r600_free_extended_power_table(rdev); return ret; }
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit 710cc1e7cd461446a9325c9bd1e9a54daa462952 ]
[Why] The bit for flip addr is being set causing the determination for FAST vs MEDIUM to always return MEDIUM when plane info is provided as a surface update. This causes extreme stuttering for the typical atomic update path on Linux.
[How] Don't use update_flags->raw for determining FAST vs MEDIUM. It's too fragile to changes like this.
Explicitly specify the update type per update flag instead. It's not as clever as checking the bits itself but at least it's correct.
Fixes: aa5fdb1ab5b6 ("drm/amd/display: Explicitly specify update type per plane info change") Reviewed-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 220a26e45a284..634640d5c0ff4 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2111,9 +2111,6 @@ static enum surface_update_type det_surface_update(const struct dc *dc, enum surface_update_type overall_type = UPDATE_TYPE_FAST; union surface_update_flags *update_flags = &u->surface->update_flags;
- if (u->flip_addr) - update_flags->bits.addr_update = 1; - if (!is_surface_in_context(context, u->surface) || u->surface->force_full_update) { update_flags->raw = 0xFFFFFFFF; return UPDATE_TYPE_FULL;
From: Luca Weiss luca@z3ntu.xyz
[ Upstream commit efef661dfa6bf8cbafe4cd6a97433fcef0118967 ]
When doing the initial startup there's no need to poll without any delay and spam the I2C bus.
Let's sleep 15ms between each attempt, which is the same time as used in the vendor driver.
Fixes: 7132fe4f5687 ("Input: drv260x - add TI drv260x haptics driver") Signed-off-by: Luca Weiss luca@z3ntu.xyz Link: https://lore.kernel.org/r/20230430-drv260x-improvements-v1-2-1fb28b4cc698@z3... Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/misc/drv260x.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index 0efe56f49aa94..1923924fdd444 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c @@ -435,6 +435,7 @@ static int drv260x_init(struct drv260x_data *haptics) }
do { + usleep_range(15000, 15500); error = regmap_read(haptics->regmap, DRV260X_GO, &cal_buf); if (error) { dev_err(&haptics->client->dev,
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit 75a8aeac2573ab258c53676eba9b3796ea691988 ]
Always enable HS video mode setting the TXMD bit, without this change no video output is present with DSI sinks that are setting MIPI_DSI_MODE_LPM flag (tested with LT8912B DSI-HDMI bridge).
Previously the driver was enabling HS mode only when the DSI sink was not explicitly setting the MIPI_DSI_MODE_LPM, however this is not correct.
The MIPI_DSI_MODE_LPM is supposed to indicate that the sink is willing to receive data in low power mode, however clearing the TC358768_DSI_CONTROL_TXMD bit will make the TC358768 send video in LP mode that is not the intended behavior.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index a3db532bbdd16..8de7d9764ba88 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -819,8 +819,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) val = TC358768_DSI_CONFW_MODE_SET | TC358768_DSI_CONFW_ADDR_DSI_CONTROL; val |= (dsi_dev->lanes - 1) << 1;
- if (!(dsi_dev->mode_flags & MIPI_DSI_MODE_LPM)) - val |= TC358768_DSI_CONTROL_TXMD; + val |= TC358768_DSI_CONTROL_TXMD;
if (!(dsi_dev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) val |= TC358768_DSI_CONTROL_HSCKMD;
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit 6a4020b4c63911977aaf8047f904a300d15de739 ]
According to Toshiba documentation the PLL input clock after the divider should be not less than 4MHz, fix the PLL parameters computation accordingly.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 8de7d9764ba88..e09e007a2749c 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -329,13 +329,17 @@ static int tc358768_calc_pll(struct tc358768_priv *priv, u32 fbd;
for (fbd = 0; fbd < 512; ++fbd) { - u32 pll, diff; + u32 pll, diff, pll_in;
pll = (u32)div_u64((u64)refclk * (fbd + 1), divisor);
if (pll >= max_pll || pll < min_pll) continue;
+ pll_in = (u32)div_u64((u64)refclk, prd + 1); + if (pll_in < 4000000) + continue; + diff = max(pll, target_pll) - min(pll, target_pll);
if (diff < best_diff) {
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit ffd2e4bbea626d565b9817312b0fcfb382fecb88 ]
Correctly compute the PLL target frequency, the current formula works correctly only when the input bus width is 24bit, actually to properly compute the PLL target frequency what is relevant is the bits-per-pixel on the DSI link.
No regression expected since the DSI format is currently hard-coded as MIPI_DSI_FMT_RGB888.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index e09e007a2749c..e302310d4acec 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -147,6 +147,7 @@ struct tc358768_priv {
u32 pd_lines; /* number of Parallel Port Input Data Lines */ u32 dsi_lanes; /* number of DSI Lanes */ + u32 dsi_bpp; /* number of Bits Per Pixel over DSI */
/* Parameters for PLL programming */ u32 fbd; /* PLL feedback divider */ @@ -279,12 +280,12 @@ static void tc358768_hw_disable(struct tc358768_priv *priv)
static u32 tc358768_pll_to_pclk(struct tc358768_priv *priv, u32 pll_clk) { - return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->pd_lines); + return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->dsi_bpp); }
static u32 tc358768_pclk_to_pll(struct tc358768_priv *priv, u32 pclk) { - return (u32)div_u64((u64)pclk * priv->pd_lines, priv->dsi_lanes); + return (u32)div_u64((u64)pclk * priv->dsi_bpp, priv->dsi_lanes); }
static int tc358768_calc_pll(struct tc358768_priv *priv, @@ -421,6 +422,7 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host, priv->output.panel = panel;
priv->dsi_lanes = dev->lanes; + priv->dsi_bpp = mipi_dsi_pixel_format_to_bpp(dev->format);
/* get input ep (port0/endpoint0) */ ret = -EINVAL; @@ -432,7 +434,7 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host, }
if (ret) - priv->pd_lines = mipi_dsi_pixel_format_to_bpp(dev->format); + priv->pd_lines = priv->dsi_bpp;
drm_bridge_add(&priv->bridge);
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit f9cf811374f42fca31ac34aaf59ee2ae72b89879 ]
Correct computation of TCLK_ZEROCNT register.
This register must be set to a value that ensure that (TCLK-PREPARECNT + TCLK-ZERO) > 300ns
with the actual value of (TCLK-PREPARECNT + TCLK-ZERO) being
(1 to 2) + (TCLK_ZEROCNT + 1)) x HSByteClkCycle + (PHY output delay)
with PHY output delay being about
(2 to 3) x MIPIBitClk cycle in the BitClk conversion.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index e302310d4acec..fa06c06e41ebe 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -725,10 +725,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
/* 38ns < TCLK_PREPARE < 95ns */ val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1; - /* TCLK_PREPARE > 300ns */ - val2 = tc358768_ns_to_cnt(300 + tc358768_to_ns(3 * ui_nsk), - dsibclk_nsk); - val |= (val2 - tc358768_to_ns(phy_delay_nsk - dsibclk_nsk)) << 8; + /* TCLK_PREPARE + TCLK_ZERO > 300ns */ + val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk), + dsibclk_nsk) - 2; + val |= val2 << 8; dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val); tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit cec5ccef85bd0128cf895612de54a9d21d2015d0 ]
Add atomic_get_input_bus_fmts() implementation, tc358768 has a parallel RGB input interface with the actual bus format depending on the amount of parallel input data lines.
Without this change when the tc358768 is used with less than 24bit the color mapping is completely wrong.
Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230330095941.428122-7-france... Stable-dep-of: ee18698e212b ("drm/bridge: tc358768: fix TCLK_TRAILCNT computation") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index fa06c06e41ebe..6e95dd4b7aef7 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -9,6 +9,7 @@ #include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/kernel.h> +#include <linux/media-bus-format.h> #include <linux/module.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> @@ -871,6 +872,44 @@ static void tc358768_bridge_enable(struct drm_bridge *bridge) } }
+#define MAX_INPUT_SEL_FORMATS 1 + +static u32 * +tc358768_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + struct tc358768_priv *priv = bridge_to_tc358768(bridge); + u32 *input_fmts; + + *num_input_fmts = 0; + + input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts), + GFP_KERNEL); + if (!input_fmts) + return NULL; + + switch (priv->pd_lines) { + case 16: + input_fmts[0] = MEDIA_BUS_FMT_RGB565_1X16; + break; + case 18: + input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X18; + break; + default: + case 24: + input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24; + break; + }; + + *num_input_fmts = MAX_INPUT_SEL_FORMATS; + + return input_fmts; +} + static const struct drm_bridge_funcs tc358768_bridge_funcs = { .attach = tc358768_bridge_attach, .mode_valid = tc358768_bridge_mode_valid, @@ -878,6 +917,11 @@ static const struct drm_bridge_funcs tc358768_bridge_funcs = { .enable = tc358768_bridge_enable, .disable = tc358768_bridge_disable, .post_disable = tc358768_bridge_post_disable, + + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_get_input_bus_fmts = tc358768_atomic_get_input_bus_fmts, };
static const struct drm_bridge_timings default_tc358768_timings = {
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit ee18698e212b1659dd0850d7e2ae0f22e16ed3d3 ]
Correct computation of TCLK_TRAILCNT register.
The driver does not implement non-continuous clock mode, so the actual value doesn't make a practical difference yet. However this change also ensures that the value does not write to reserved registers bits in case of under/overflow.
This register must be set to a value that ensures that
TCLK-TRAIL > 60ns and TEOT <= (105 ns + 12 x UI)
with the actual value of TCLK-TRAIL being
(TCLK_TRAILCNT + (1 to 2)) xHSByteClkCycle + (2 + (1 to 2)) * HSBYTECLKCycle - (PHY output delay)
with PHY output delay being about
(2 to 3) x MIPIBitClk cycle in the BitClk conversion.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-2-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-3-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-4-frances... Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-5-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 6e95dd4b7aef7..de4022c864034 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -10,6 +10,7 @@ #include <linux/i2c.h> #include <linux/kernel.h> #include <linux/media-bus-format.h> +#include <linux/minmax.h> #include <linux/module.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> @@ -633,6 +634,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) struct tc358768_priv *priv = bridge_to_tc358768(bridge); struct mipi_dsi_device *dsi_dev = priv->output.dev; u32 val, val2, lptxcnt, hact, data_type; + s32 raw_val; const struct drm_display_mode *mode; u32 dsibclk_nsk, dsiclk_nsk, ui_nsk, phy_delay_nsk; u32 dsiclk, dsibclk; @@ -733,9 +735,9 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val); tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
- /* TCLK_TRAIL > 60ns + 3*UI */ - val = 60 + tc358768_to_ns(3 * ui_nsk); - val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 5; + /* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */ + raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), dsibclk_nsk) - 5; + val = clamp(raw_val, 0, 127); dev_dbg(priv->dev, "TCLK_TRAILCNT: 0x%x\n", val); tc358768_write(priv, TC358768_TCLK_TRAILCNT, val);
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit 77a089328da791118af9692543a5eedc79eb5fd4 ]
Correct computation of THS_ZEROCNT register.
This register must be set to a value that ensure that THS_PREPARE + THS_ZERO > 145ns + 10*UI
with the actual value of (THS_PREPARE + THS_ZERO) being
((1 to 2) + 1 + (TCLK_ZEROCNT + 1) + (3 to 4)) x ByteClk cycle + + HSByteClk x (2 + (1 to 2)) + (PHY delay)
with PHY delay being about
(8 + (5 to 6)) x MIPIBitClk cycle in the BitClk conversion.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-7-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index de4022c864034..151eecbf6027d 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -744,9 +744,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) /* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */ val = 50 + tc358768_to_ns(4 * ui_nsk); val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1; - /* THS_ZERO > 145ns + 10*UI */ - val2 = tc358768_ns_to_cnt(145 - tc358768_to_ns(ui_nsk), dsibclk_nsk); - val |= (val2 - tc358768_to_ns(phy_delay_nsk)) << 8; + /* THS_PREPARE + THS_ZERO > 145ns + 10*UI */ + raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), dsibclk_nsk) - 10; + val2 = clamp(raw_val, 0, 127); + val |= val2 << 8; dev_dbg(priv->dev, "THS_HEADERCNT: 0x%x\n", val); tc358768_write(priv, TC358768_THS_HEADERCNT, val);
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit 3666aad8185af8d0ce164fd3c4974235417d6d0b ]
Correct computation of TXTAGOCNT register.
This register must be set to a value that ensure that the TTA-GO period = (4 x TLPX)
with the actual value of TTA-GO being
4 x (TXTAGOCNT + 1) x (HSByteClk cycle)
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-8-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 151eecbf6027d..c9c2e15c6f4a2 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -779,7 +779,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4); - val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1; + val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1; val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk), dsibclk_nsk) - 2; val |= val2 << 16;
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit bac7842cd179572e8e0fc2d7b5254e40c6e9e057 ]
Correct computation of THS_TRAILCNT register.
This register must be set to a value that ensure that THS_TRAIL > 60 ns + 4 x UI and THS_TRAIL > 8 x UI and THS_TRAIL < TEOT with TEOT = 105 ns + (12 x UI)
with the actual value of THS_TRAIL being
(1 + THS_TRAILCNT) x ByteClk cycle + ((1 to 2) + 2) xHSBYTECLK cycle + - (PHY output delay)
with PHY output delay being about
(8 + (5 to 6)) x MIPIBitClk cycle in the BitClk conversion.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230427142934.55435-9-frances... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358768.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index c9c2e15c6f4a2..8b1bdffc5005d 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -763,9 +763,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) dev_dbg(priv->dev, "TCLK_POSTCNT: 0x%x\n", val); tc358768_write(priv, TC358768_TCLK_POSTCNT, val);
- /* 60ns + 4*UI < THS_PREPARE < 105ns + 12*UI */ - val = tc358768_ns_to_cnt(60 + tc358768_to_ns(15 * ui_nsk), - dsibclk_nsk) - 5; + /* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */ + raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk), + dsibclk_nsk) - 4; + val = clamp(raw_val, 0, 15); dev_dbg(priv->dev, "THS_TRAILCNT: 0x%x\n", val); tc358768_write(priv, TC358768_THS_TRAILCNT, val);
From: Luc Ma luc@sietium.com
[ Upstream commit b8e392245105b50706f18418054821e71e637288 ]
Refer to drmm_vram_helper_init() instead of the non-existent drmm_vram_helper_alloc_mm().
Fixes: a5f23a72355d ("drm/vram-helper: Managed vram helpers") Signed-off-by: Luc Ma luc@sietium.com Reviewed-by: Thomas Zimmermann tzimmermann@suse.de Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/64583db2.630a0220.eb75d.8f51@m... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_gem_vram_helper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 43cf7e887d1a5..aaf4f7dcc581d 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -43,7 +43,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs; * the frame's scanout buffer or the cursor image. If there's no more space * left in VRAM, inactive GEM objects can be moved to system memory. * - * To initialize the VRAM helper library call drmm_vram_helper_alloc_mm(). + * To initialize the VRAM helper library call drmm_vram_helper_init(). * The function allocates and initializes an instance of &struct drm_vram_mm * in &struct drm_device.vram_mm . Use &DRM_GEM_VRAM_DRIVER to initialize * &struct drm_driver and &DRM_VRAM_MM_FILE_OPERATIONS to initialize @@ -71,7 +71,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs; * // setup device, vram base and size * // ... * - * ret = drmm_vram_helper_alloc_mm(dev, vram_base, vram_size); + * ret = drmm_vram_helper_init(dev, vram_base, vram_size); * if (ret) * return ret; * return 0; @@ -84,7 +84,7 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs; * to userspace. * * You don't have to clean up the instance of VRAM MM. - * drmm_vram_helper_alloc_mm() is a managed interface that installs a + * drmm_vram_helper_init() is a managed interface that installs a * clean-up handler to run during the DRM device's release. * * For drawing or scanout operations, rsp. buffer objects have to be pinned
From: Rafał Miłecki rafal@milecki.pl
[ Upstream commit d3c8e2c5757153bbfad70019ec1decbca86f3def ]
There is no such property in the SPI controller binding documentation. Also Linux driver doesn't look for it.
This fixes: arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: spi@18029200: Unevaluated properties are not allowed ('clock-names' was unexpected) From schema: Documentation/devicetree/bindings/spi/brcm,spi-bcm-qspi.yaml
Signed-off-by: Rafał Miłecki rafal@milecki.pl Link: https://lore.kernel.org/r/20230503122830.3200-1-zajec5@gmail.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm5301x.dtsi | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi index 30217948ef827..b4b73ab996264 100644 --- a/arch/arm/boot/dts/bcm5301x.dtsi +++ b/arch/arm/boot/dts/bcm5301x.dtsi @@ -542,7 +542,6 @@ spi@18029200 { "spi_lr_session_done", "spi_lr_overread"; clocks = <&iprocmed>; - clock-names = "iprocmed"; num-cs = <2>; #address-cells = <1>; #size-cells = <0>;
From: hfdevel@gmx.net hfdevel@gmx.net
[ Upstream commit d542ce8d4769cdef6a7bc3437e59cfed9c68f0e4 ]
With the current device tree for meson8b, uarts B (e.g. available on pins 8/10 on Odroid-C1) and C (pins 3/5 on Odroid-C1) do not work, because they are relying on incorrect clocks. Change the references of pclk to the correct CLKID, to allow use of the two uarts.
Fixes: 3375aa77135f ("ARM: dts: meson8b: Fix the UART device-tree schema validation") Signed-off-by: Hans-Frieder Vogt hfdevel@gmx.net Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Link: https://lore.kernel.org/r/trinity-bf20bcb9-790b-4ab9-99e3-0831ef8257f4-16808... Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/meson8b.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi index 94f1c03deccef..cfd4a909a7a70 100644 --- a/arch/arm/boot/dts/meson8b.dtsi +++ b/arch/arm/boot/dts/meson8b.dtsi @@ -737,13 +737,13 @@ &uart_A {
&uart_B { compatible = "amlogic,meson8b-uart"; - clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; + clocks = <&xtal>, <&clkc CLKID_UART1>, <&clkc CLKID_CLK81>; clock-names = "xtal", "pclk", "baud"; };
&uart_C { compatible = "amlogic,meson8b-uart"; - clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; + clocks = <&xtal>, <&clkc CLKID_UART2>, <&clkc CLKID_CLK81>; clock-names = "xtal", "pclk", "baud"; };
From: Marek Vasut marex@denx.de
[ Upstream commit e96220bce5176ed2309f77f061dcc0430b82b25e ]
Instead of hardcoding IRQ trigger type to IRQF_TRIGGER_HIGH, let's respect the settings specified in the firmware description.
Fixes: e27c729219ad ("Input: add driver for ADXL345/346 Digital Accelerometers") Signed-off-by: Marek Vasut marex@denx.de Acked-by: Michael Hennerich michael.hennerich@analog.com Link: https://lore.kernel.org/r/20230509203555.549158-1-marex@denx.de Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/misc/adxl34x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index 4cc4e8ff42b33..ad035c342cd3b 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -811,8 +811,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, AC_WRITE(ac, POWER_CTL, 0);
err = request_threaded_irq(ac->irq, NULL, adxl34x_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - dev_name(dev), ac); + IRQF_ONESHOT, dev_name(dev), ac); if (err) { dev_err(dev, "irq %d busy?\n", ac->irq); goto err_free_mem;
From: XuDong Liu m202071377@hust.edu.cn
[ Upstream commit 123ee07ba5b7123e0ce0e0f9d64938026c16a2ce ]
Smatch reports: drivers/gpu/drm/sun4i/sun4i_tcon.c:805 sun4i_tcon_init_clocks() warn: 'tcon->clk' from clk_prepare_enable() not released on lines: 792,801.
In the function sun4i_tcon_init_clocks(), tcon->clk and tcon->sclk0 are not disabled in the error handling, which affects the release of these variable. Although sun4i_tcon_bind(), which calls sun4i_tcon_init_clocks(), use sun4i_tcon_free_clocks to disable the variables mentioned, but the error handling branch of sun4i_tcon_init_clocks() ignores the required disable process.
To fix this issue, use the devm_clk_get_enabled to automatically balance enable and disabled calls. As original implementation use sun4i_tcon_free_clocks() to disable clk explicitly, we delete the related calls and error handling that are no longer needed.
Fixes: 9026e0d122ac ("drm: Add Allwinner A10 Display Engine support") Fixes: b14e945bda8a ("drm/sun4i: tcon: Prepare and enable TCON channel 0 clock at init") Fixes: 8e9240472522 ("drm/sun4i: support TCONs without channel 1") Fixes: 34d698f6e349 ("drm/sun4i: Add has_channel_0 TCON quirk") Signed-off-by: XuDong Liu m202071377@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Signed-off-by: Maxime Ripard maxime@cerno.tech Link: https://patchwork.freedesktop.org/patch/msgid/20230430112347.4689-1-m2020713... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 9f06dec0fc61d..bb43196d5d83e 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -777,21 +777,19 @@ static irqreturn_t sun4i_tcon_handler(int irq, void *private) static int sun4i_tcon_init_clocks(struct device *dev, struct sun4i_tcon *tcon) { - tcon->clk = devm_clk_get(dev, "ahb"); + tcon->clk = devm_clk_get_enabled(dev, "ahb"); if (IS_ERR(tcon->clk)) { dev_err(dev, "Couldn't get the TCON bus clock\n"); return PTR_ERR(tcon->clk); } - clk_prepare_enable(tcon->clk);
if (tcon->quirks->has_channel_0) { - tcon->sclk0 = devm_clk_get(dev, "tcon-ch0"); + tcon->sclk0 = devm_clk_get_enabled(dev, "tcon-ch0"); if (IS_ERR(tcon->sclk0)) { dev_err(dev, "Couldn't get the TCON channel 0 clock\n"); return PTR_ERR(tcon->sclk0); } } - clk_prepare_enable(tcon->sclk0);
if (tcon->quirks->has_channel_1) { tcon->sclk1 = devm_clk_get(dev, "tcon-ch1"); @@ -804,12 +802,6 @@ static int sun4i_tcon_init_clocks(struct device *dev, return 0; }
-static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon) -{ - clk_disable_unprepare(tcon->sclk0); - clk_disable_unprepare(tcon->clk); -} - static int sun4i_tcon_init_irq(struct device *dev, struct sun4i_tcon *tcon) { @@ -1224,14 +1216,14 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, ret = sun4i_tcon_init_regmap(dev, tcon); if (ret) { dev_err(dev, "Couldn't init our TCON regmap\n"); - goto err_free_clocks; + goto err_assert_reset; }
if (tcon->quirks->has_channel_0) { ret = sun4i_dclk_create(dev, tcon); if (ret) { dev_err(dev, "Couldn't create our TCON dot clock\n"); - goto err_free_clocks; + goto err_assert_reset; } }
@@ -1294,8 +1286,6 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, err_free_dotclock: if (tcon->quirks->has_channel_0) sun4i_dclk_free(tcon); -err_free_clocks: - sun4i_tcon_free_clocks(tcon); err_assert_reset: reset_control_assert(tcon->lcd_rst); return ret; @@ -1309,7 +1299,6 @@ static void sun4i_tcon_unbind(struct device *dev, struct device *master, list_del(&tcon->list); if (tcon->quirks->has_channel_0) sun4i_dclk_free(tcon); - sun4i_tcon_free_clocks(tcon); }
static const struct component_ops sun4i_tcon_ops = {
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit dee23b2c9e3ff46d59c5d45e1436eceb878e7c9a ]
Using current settings causes panel flickering on APQ8074 dragonboard. Adjust panel settings to follow the vendor-provided mode. This also enables MIPI_DSI_MODE_VIDEO_SYNC_PULSE, which is also specified by the vendor dtsi for the mentioned dragonboard.
Fixes: ee0172383190 ("drm/panel: Add Sharp LS043T1LE01 MIPI DSI panel") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20230507172639.2320934-1-dmitr... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c index 25829a0a8e801..e2f1e983ef7eb 100644 --- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c +++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c @@ -192,15 +192,15 @@ static int sharp_nt_panel_enable(struct drm_panel *panel) }
static const struct drm_display_mode default_mode = { - .clock = 41118, + .clock = (540 + 48 + 32 + 80) * (960 + 3 + 10 + 15) * 60 / 1000, .hdisplay = 540, .hsync_start = 540 + 48, - .hsync_end = 540 + 48 + 80, - .htotal = 540 + 48 + 80 + 32, + .hsync_end = 540 + 48 + 32, + .htotal = 540 + 48 + 32 + 80, .vdisplay = 960, .vsync_start = 960 + 3, - .vsync_end = 960 + 3 + 15, - .vtotal = 960 + 3 + 15 + 1, + .vsync_end = 960 + 3 + 10, + .vtotal = 960 + 3 + 10 + 15, };
static int sharp_nt_panel_get_modes(struct drm_panel *panel, @@ -280,6 +280,7 @@ static int sharp_nt_panel_probe(struct mipi_dsi_device *dsi) dsi->lanes = 2; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_NO_EOT_PACKET;
From: Marek Vasut marex@denx.de
[ Upstream commit 9660efc2af37f3c12dc6e6a5511ad99e0addc297 ]
The ethernet MAC EEPROM is not populated on the SoM itself, it has to be populated on each carrier board. Move the EEPROM into the correct place in DTs, i.e. the carrier board DTs. Add label to the EEPROM too.
Fixes: 7e76f82acd9e1 ("ARM: dts: stm32: Split Avenger96 into DHCOR SoM and Avenger96 board") Signed-off-by: Marek Vasut marex@denx.de Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 6 ++++++ arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi index d3375ad8c91fc..7fe93cdc82bbb 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi @@ -267,6 +267,12 @@ adv7513_i2s0: endpoint { }; }; }; + + dh_mac_eeprom: eeprom@53 { + compatible = "atmel,24c02"; + reg = <0x53>; + pagesize = <16>; + }; };
<dc { diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi index 44ecc47085871..108d934a186b4 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi @@ -171,12 +171,6 @@ watchdog { status = "disabled"; }; }; - - eeprom@53 { - compatible = "atmel,24c02"; - reg = <0x53>; - pagesize = <16>; - }; };
&iwdg2 {
From: Tony Lindgren tony@atomide.com
[ Upstream commit f620596fa347170852da499e778a5736d79a4b79 ]
Fix warning drivers/bus/ti-sysc.c:1806 sysc_quirk_dispc() warn: masking a bool.
While at it let's add a comment for what were doing to make the code a bit easier to follow.
Fixes: 7324a7a0d5e2 ("bus: ti-sysc: Implement display subsystem reset quirk") Reported-by: Dan Carpenter dan.carpenter@linaro.org Closes: https://lore.kernel.org/linux-omap/a8ec8a68-9c2c-4076-bf47-09fccce7659f@kili... Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/ti-sysc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index e93912e56f28c..7d508f9050038 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -1759,7 +1759,7 @@ static u32 sysc_quirk_dispc(struct sysc *ddata, int dispc_offset, if (!ddata->module_va) return -EIO;
- /* DISP_CONTROL */ + /* DISP_CONTROL, shut down lcd and digit on disable if enabled */ val = sysc_read(ddata, dispc_offset + 0x40); lcd_en = val & lcd_en_mask; digit_en = val & digit_en_mask; @@ -1771,7 +1771,7 @@ static u32 sysc_quirk_dispc(struct sysc *ddata, int dispc_offset, else irq_mask |= BIT(2) | BIT(3); /* EVSYNC bits */ } - if (disable & (lcd_en | digit_en)) + if (disable && (lcd_en || digit_en)) sysc_write(ddata, dispc_offset + 0x40, val & ~(lcd_en_mask | digit_en_mask));
From: Robert Marko robert.marko@sartura.hr
[ Upstream commit 70be83708c925b3f72c508e4756e48ad2330c830 ]
PSCI is not implemented on SparX-5 at all, there is no ATF and U-boot that is shipped does not implement it as well.
I have tried flashing the latest BSP 2022.12 U-boot which did not work. After contacting Microchip, they confirmed that there is no ATF for the SoC nor PSCI implementation which is unfortunate in 2023.
So, disable PSCI as otherwise kernel crashes as soon as it tries probing PSCI with, and the crash is only visible if earlycon is used.
Since PSCI is not implemented, switch core bringup to use spin-tables which are implemented in the vendor U-boot and actually work.
Tested on PCB134 with eMMC (VSC5640EV).
Fixes: 6694aee00a4b ("arm64: dts: sparx5: Add basic cpu support") Signed-off-by: Robert Marko robert.marko@sartura.hr Acked-by: Steen Hegelund Steen.Hegelund@microchip.com Link: https://lore.kernel.org/r/20230221105039.316819-1-robert.marko@sartura.hr Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/microchip/sparx5.dtsi | 2 +- arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi index 787ebcec121d6..a6405059636c3 100644 --- a/arch/arm64/boot/dts/microchip/sparx5.dtsi +++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi @@ -61,7 +61,7 @@ arm-pmu { interrupt-affinity = <&cpu0>, <&cpu1>; };
- psci { + psci: psci { compatible = "arm,psci-0.2"; method = "smc"; }; diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi index 9d1a082de3e29..32bb76b3202a0 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb_common.dtsi @@ -6,6 +6,18 @@ /dts-v1/; #include "sparx5.dtsi"
+&psci { + status = "disabled"; +}; + +&cpu0 { + enable-method = "spin-table"; +}; + +&cpu1 { + enable-method = "spin-table"; +}; + &uart0 { status = "okay"; };
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit 632c60ecd25dbacee54d5581fe3aeb834b57010a ]
This loop is freeing "clk" so it needs to use list_for_each_entry_safe(). Otherwise it dereferences a freed variable to get the next item on the loop.
Fixes: 77d8f3068c63 ("clk: imx: scu: add two cells binding support") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/0793fbd1-d2b5-4ec2-9403-3c39343a3e2d@kili.mountain Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-scu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index dc933fd5d5a0f..1cee88b073fa2 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -702,11 +702,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
void imx_clk_scu_unregister(void) { - struct imx_scu_clk_node *clk; + struct imx_scu_clk_node *clk, *n; int i;
for (i = 0; i < IMX_SC_R_LAST; i++) { - list_for_each_entry(clk, &imx_scu_clks[i], node) { + list_for_each_entry_safe(clk, n, &imx_scu_clks[i], node) { clk_hw_unregister(clk->hw); kfree(clk); }
From: Selvin Xavier selvin.xavier@broadcom.com
[ Upstream commit ab112ee7899d6171da5acd77a7ed7ae103f488de ]
When the ulp hook to start the IRQ fails because the rings are not available, tasklets are not enabled. In this case when the driver is unloaded, driver calls CREQ tasklet_kill. This causes an indefinite hang as the tasklet is not enabled.
Driver shouldn't call tasklet_kill if it is not enabled. So using the creq->requested and nq->requested flags to identify if both tasklets/irqs are registered. Checking this flag while scheduling the tasklet from ISR. Also, added a cleanup for disabling tasklet, in case request_irq fails during start_irq.
Check for return value for bnxt_qplib_rcfw_start_irq and in case the bnxt_qplib_rcfw_start_irq fails, return bnxt_re_start_irq without attempting to start NQ IRQs.
Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Link: https://lore.kernel.org/r/1684478897-12247-2-git-send-email-selvin.xavier@br... Signed-off-by: Kalesh AP kalesh-anakkur.purayil@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/main.c | 12 +++++++++--- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 16 ++++++++++------ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 14 +++++++++----- 3 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c index 66268e41b470e..634e81b288454 100644 --- a/drivers/infiniband/hw/bnxt_re/main.c +++ b/drivers/infiniband/hw/bnxt_re/main.c @@ -331,15 +331,21 @@ static void bnxt_re_start_irq(void *handle, struct bnxt_msix_entry *ent) for (indx = 0; indx < rdev->num_msix; indx++) rdev->msix_entries[indx].vector = ent[indx].vector;
- bnxt_qplib_rcfw_start_irq(rcfw, msix_ent[BNXT_RE_AEQ_IDX].vector, - false); + rc = bnxt_qplib_rcfw_start_irq(rcfw, msix_ent[BNXT_RE_AEQ_IDX].vector, + false); + if (rc) { + ibdev_warn(&rdev->ibdev, "Failed to reinit CREQ\n"); + return; + } for (indx = BNXT_RE_NQ_IDX ; indx < rdev->num_msix; indx++) { nq = &rdev->nq[indx - 1]; rc = bnxt_qplib_nq_start_irq(nq, indx - 1, msix_ent[indx].vector, false); - if (rc) + if (rc) { ibdev_warn(&rdev->ibdev, "Failed to reinit NQ index %d\n", indx - 1); + return; + } } }
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index b26a89187a192..9eba4b39c7032 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -404,6 +404,9 @@ static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill) { + if (!nq->requested) + return; + tasklet_disable(&nq->nq_tasklet); /* Mask h/w interrupt */ bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, false); @@ -411,11 +414,10 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill) synchronize_irq(nq->msix_vec); if (kill) tasklet_kill(&nq->nq_tasklet); - if (nq->requested) { - irq_set_affinity_hint(nq->msix_vec, NULL); - free_irq(nq->msix_vec, nq); - nq->requested = false; - } + + irq_set_affinity_hint(nq->msix_vec, NULL); + free_irq(nq->msix_vec, nq); + nq->requested = false; }
void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq) @@ -454,8 +456,10 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx,
snprintf(nq->name, sizeof(nq->name), "bnxt_qplib_nq-%d", nq_indx); rc = request_irq(nq->msix_vec, bnxt_qplib_nq_irq, 0, nq->name, nq); - if (rc) + if (rc) { + tasklet_disable(&nq->nq_tasklet); return rc; + }
cpumask_clear(&nq->mask); cpumask_set_cpu(nq_indx, &nq->mask); diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index d2d39126f1852..2be30068574ce 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -637,6 +637,10 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill) struct bnxt_qplib_creq_ctx *creq;
creq = &rcfw->creq; + + if (!creq->requested) + return; + tasklet_disable(&creq->creq_tasklet); /* Mask h/w interrupts */ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, false); @@ -645,10 +649,8 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill) if (kill) tasklet_kill(&creq->creq_tasklet);
- if (creq->requested) { - free_irq(creq->msix_vec, rcfw); - creq->requested = false; - } + free_irq(creq->msix_vec, rcfw); + creq->requested = false; }
void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw) @@ -694,8 +696,10 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector, tasklet_enable(&creq->creq_tasklet); rc = request_irq(creq->msix_vec, bnxt_qplib_creq_irq, 0, "bnxt_qplib_creq", rcfw); - if (rc) + if (rc) { + tasklet_disable(&creq->creq_tasklet); return rc; + } creq->requested = true;
bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, true);
From: Kalesh AP kalesh-anakkur.purayil@broadcom.com
[ Upstream commit 9b3ee47796f529e5bc31a355d6cb756d68a7079a ]
If there is no cleanup needed then just return directly. This cleans up the code and improve readability.
Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Link: https://lore.kernel.org/r/1684478897-12247-3-git-send-email-selvin.xavier@br... Reviewed-by: Kashyap Desai kashyap.desai@broadcom.com Reviewed-by: Saravanan Vajravel saravanan.vajravel@broadcom.com Signed-off-by: Kalesh AP kalesh-anakkur.purayil@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index 9eba4b39c7032..b4b180652c0a0 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -1603,7 +1603,7 @@ static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp, il_src = (void *)wqe->sg_list[indx].addr; t_len += len; if (t_len > qp->max_inline_data) - goto bad; + return -ENOMEM; while (len) { if (pull_dst) { pull_dst = false; @@ -1627,8 +1627,6 @@ static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp, }
return t_len; -bad: - return -ENOMEM; }
static u32 bnxt_qplib_put_sges(struct bnxt_qplib_hwq *hwq, @@ -2058,7 +2056,7 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq) hwq_attr.sginfo = &cq->sg_info; rc = bnxt_qplib_alloc_init_hwq(&cq->hwq, &hwq_attr); if (rc) - goto exit; + return rc;
RCFW_CMD_PREP(req, CREATE_CQ, cmd_flags);
@@ -2099,7 +2097,6 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq)
fail: bnxt_qplib_free_hwq(res, &cq->hwq); -exit: return rc; }
From: Kalesh AP kalesh-anakkur.purayil@broadcom.com
[ Upstream commit ff2e4bfd162cf66a112a81509e419805add44d64 ]
bnxt_re currently uses the names "bnxt_qplib_creq" and "bnxt_qplib_nq-0" while registering IRQs. There is no way to distinguish the IRQs of different device ports when there are multiple IB devices registered. This could make the scenarios worse where one want to pin IRQs of a device port to certain CPUs.
Fixed the code to use unique names which has PCI BDF information while registering interrupts like: "bnxt_re-nq-0@pci:0000:65:00.0" and "bnxt_re-creq@pci:0000:65:00.1".
Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Link: https://lore.kernel.org/r/1684478897-12247-4-git-send-email-selvin.xavier@br... Reviewed-by: Bhargava Chenna Marreddy bhargava.marreddy@broadcom.com Signed-off-by: Kalesh AP kalesh-anakkur.purayil@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 12 ++++++++++-- drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 +- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 15 +++++++++++++-- drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 1 + 4 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index b4b180652c0a0..d6b7c0d1f6766 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -417,6 +417,8 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
irq_set_affinity_hint(nq->msix_vec, NULL); free_irq(nq->msix_vec, nq); + kfree(nq->name); + nq->name = NULL; nq->requested = false; }
@@ -443,6 +445,7 @@ void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq) int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, int msix_vector, bool need_init) { + struct bnxt_qplib_res *res = nq->res; int rc;
if (nq->requested) @@ -454,9 +457,14 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, else tasklet_enable(&nq->nq_tasklet);
- snprintf(nq->name, sizeof(nq->name), "bnxt_qplib_nq-%d", nq_indx); + nq->name = kasprintf(GFP_KERNEL, "bnxt_re-nq-%d@pci:%s", + nq_indx, pci_name(res->pdev)); + if (!nq->name) + return -ENOMEM; rc = request_irq(nq->msix_vec, bnxt_qplib_nq_irq, 0, nq->name, nq); if (rc) { + kfree(nq->name); + nq->name = NULL; tasklet_disable(&nq->nq_tasklet); return rc; } @@ -470,7 +478,7 @@ int bnxt_qplib_nq_start_irq(struct bnxt_qplib_nq *nq, int nq_indx, nq->msix_vec, nq_indx); } nq->requested = true; - bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, true); + bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, res->cctx, true);
return rc; } diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h index 0375019525431..f859710f9a7f4 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h @@ -471,7 +471,7 @@ typedef int (*srqn_handler_t)(struct bnxt_qplib_nq *nq, struct bnxt_qplib_nq { struct pci_dev *pdev; struct bnxt_qplib_res *res; - char name[32]; + char *name; struct bnxt_qplib_hwq hwq; struct bnxt_qplib_nq_db nq_db; u16 ring_id; diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index 2be30068574ce..d72f36d2bd496 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -650,6 +650,8 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill) tasklet_kill(&creq->creq_tasklet);
free_irq(creq->msix_vec, rcfw); + kfree(creq->irq_name); + creq->irq_name = NULL; creq->requested = false; }
@@ -682,9 +684,11 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector, bool need_init) { struct bnxt_qplib_creq_ctx *creq; + struct bnxt_qplib_res *res; int rc;
creq = &rcfw->creq; + res = rcfw->res;
if (creq->requested) return -EFAULT; @@ -694,15 +698,22 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector, tasklet_setup(&creq->creq_tasklet, bnxt_qplib_service_creq); else tasklet_enable(&creq->creq_tasklet); + + creq->irq_name = kasprintf(GFP_KERNEL, "bnxt_re-creq@pci:%s", + pci_name(res->pdev)); + if (!creq->irq_name) + return -ENOMEM; rc = request_irq(creq->msix_vec, bnxt_qplib_creq_irq, 0, - "bnxt_qplib_creq", rcfw); + creq->irq_name, rcfw); if (rc) { + kfree(creq->irq_name); + creq->irq_name = NULL; tasklet_disable(&creq->creq_tasklet); return rc; } creq->requested = true;
- bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, true); + bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, res->cctx, true);
return 0; } diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h index 0c6d0b70ce890..2acdec55a667e 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h @@ -174,6 +174,7 @@ struct bnxt_qplib_creq_ctx { u16 ring_id; int msix_vec; bool requested; /*irq handler installed */ + char *irq_name; };
/* RCFW Communication Channels */
From: Kalesh AP kalesh-anakkur.purayil@broadcom.com
[ Upstream commit b989f90cef0af48aa5679b6a75476371705ec53c ]
The NULL check inside bnxt_re_update_gid() always return false. If sgid_tbl->tbl is not allocated, then dev_init would have failed.
Fixes: 5fac5b1b297f ("RDMA/bnxt_re: Add vlan tag for untagged RoCE traffic when PFC is configured") Link: https://lore.kernel.org/r/1684478897-12247-5-git-send-email-selvin.xavier@br... Reviewed-by: Saravanan Vajravel saravanan.vajravel@broadcom.com Reviewed-by: Damodharam Ammepalli damodharam.ammepalli@broadcom.com Reviewed-by: Ajit Khaparde ajit.khaparde@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Kalesh AP kalesh-anakkur.purayil@broadcom.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/main.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c index 634e81b288454..7b85eef113fc0 100644 --- a/drivers/infiniband/hw/bnxt_re/main.c +++ b/drivers/infiniband/hw/bnxt_re/main.c @@ -1179,12 +1179,6 @@ static int bnxt_re_update_gid(struct bnxt_re_dev *rdev) if (!ib_device_try_get(&rdev->ibdev)) return 0;
- if (!sgid_tbl) { - ibdev_err(&rdev->ibdev, "QPLIB: SGID table not allocated"); - rc = -EINVAL; - goto out; - } - for (index = 0; index < sgid_tbl->active; index++) { gid_idx = sgid_tbl->hw_id[index];
@@ -1202,7 +1196,7 @@ static int bnxt_re_update_gid(struct bnxt_re_dev *rdev) rc = bnxt_qplib_update_sgid(sgid_tbl, &gid, gid_idx, rdev->qplib_res.netdev->dev_addr); } -out: + ib_device_put(&rdev->ibdev); return rc; }
From: Kalesh AP kalesh-anakkur.purayil@broadcom.com
[ Upstream commit 43774bc156614346fe5dacabc8e8c229167f2536 ]
During destroy_qp, driver sets the qp handle in the existing CQEs belonging to the QP being destroyed to NULL. As a result, a poll_cq after destroy_qp can report unnecessary messages. Remove this noise from system logs.
Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Link: https://lore.kernel.org/r/1684478897-12247-6-git-send-email-selvin.xavier@br... Signed-off-by: Kalesh AP kalesh-anakkur.purayil@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index d6b7c0d1f6766..d44b6a5c90b57 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -2732,11 +2732,8 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq,
qp = (struct bnxt_qplib_qp *)((unsigned long) le64_to_cpu(hwcqe->qp_handle)); - if (!qp) { - dev_err(&cq->hwq.pdev->dev, - "FP: CQ Process terminal qp is NULL\n"); + if (!qp) return -EINVAL; - }
/* Must block new posting of SQ and RQ */ qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 1e0a97f84d73ea1182740f62069690c7f3271abb ]
If the dispcc uses CLK_OPS_PARENT_ENABLE (e.g. on QCM2290), CCF can try enabling VCO before the rate has been programmed. This can cause clock lockups and/or other boot issues. Program the VCO to the minimal PLL rate if the read rate is 0 Hz.
Cc: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reported-by: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org Reported-by: Konrad Dybcio konrad.dybcio@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Fixes: f079f6d999cb ("drm/msm/dsi: Add PHY/PLL for 8x96") Patchwork: https://patchwork.freedesktop.org/patch/534813/ Link: https://lore.kernel.org/r/20230501011257.3460103-1-dmitry.baryshkov@linaro.o... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 6d3abcdc57bfb..66507eb713048 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -541,6 +541,9 @@ static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw) if (unlikely(pll_14nm->phy->pll_on)) return 0;
+ if (dsi_pll_14nm_vco_recalc_rate(hw, VCO_REF_CLK_RATE) == 0) + dsi_pll_14nm_vco_set_rate(hw, pll_14nm->phy->cfg->min_pll_rate, VCO_REF_CLK_RATE); + dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1);
From: Vinod Polimera quic_vpolimer@quicinc.com
[ Upstream commit e3969eadc8ee78a5bdca65b8ed0a421a359e4090 ]
Recommended way of reading the interface timing gen status is via status register. Timing gen status register will give a reliable status of the interface especially during ON/OFF transitions. This support was added from DPU version 5.0.0.
Signed-off-by: Vinod Polimera quic_vpolimer@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/524724/ Link: https://lore.kernel.org/r/1677774797-31063-6-git-send-email-quic_vpolimer@qu... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Stable-dep-of: a7129231edf3 ("drm/msm/dpu: Set DPU_DATA_HCTL_EN for in INTF_SC7180_MASK") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 12 +++++++----- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 8 +++++++- 3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 4c65259eecb9d..70d14b0db50fa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -53,7 +53,8 @@
#define INTF_SDM845_MASK (0)
-#define INTF_SC7180_MASK BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) +#define INTF_SC7180_MASK \ + (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | BIT(DPU_INTF_STATUS_SUPPORTED))
#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index d2a945a27cfaa..321b7599fe2d0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -191,17 +191,19 @@ enum {
/** * INTF sub-blocks - * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which - * pixel data arrives to this INTF - * @DPU_INTF_TE INTF block has TE configuration support - * @DPU_DATA_HCTL_EN Allows data to be transferred at different rate - than video timing + * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which + * pixel data arrives to this INTF + * @DPU_INTF_TE INTF block has TE configuration support + * @DPU_DATA_HCTL_EN Allows data to be transferred at different rate + * than video timing + * @DPU_INTF_STATUS_SUPPORTED INTF block has INTF_STATUS register * @DPU_INTF_MAX */ enum { DPU_INTF_INPUT_CTRL = 0x1, DPU_INTF_TE, DPU_DATA_HCTL_EN, + DPU_INTF_STATUS_SUPPORTED, DPU_INTF_MAX };
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 916e2a4756c09..7c09d30a62b8d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -54,6 +54,7 @@ #define INTF_PROG_FETCH_START 0x170 #define INTF_PROG_ROT_START 0x174 #define INTF_MUX 0x25C +#define INTF_STATUS 0x26C
static const struct dpu_intf_cfg *_intf_offset(enum dpu_intf intf, const struct dpu_mdss_cfg *m, @@ -259,8 +260,13 @@ static void dpu_hw_intf_get_status( struct intf_status *s) { struct dpu_hw_blk_reg_map *c = &intf->hw; + unsigned long cap = intf->cap->features; + + if (cap & BIT(DPU_INTF_STATUS_SUPPORTED)) + s->is_en = DPU_REG_READ(c, INTF_STATUS) & BIT(0); + else + s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN);
- s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN); s->is_prog_fetch_en = !!(DPU_REG_READ(c, INTF_CONFIG) & BIT(31)); if (s->is_en) { s->frame_count = DPU_REG_READ(c, INTF_FRAME_COUNT);
From: Konrad Dybcio konrad.dybcio@linaro.org
[ Upstream commit a7129231edf329a00e92dbd2d741f6da728a4a06 ]
DPU5 and newer targets enable this unconditionally. Move it from the SC7280 mask to the SC7180 one.
Fixes: 7e6ee55320f0 ("drm/msm/disp/dpu1: enable DATA_HCTL_EN for sc7280 target") Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Konrad Dybcio konrad.dybcio@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Patchwork: https://patchwork.freedesktop.org/patch/538159/ Link: https://lore.kernel.org/r/20230508-topic-hctl_en-v2-1-e7bea9f1f5dd@linaro.or... [DB: removed BIT(DPU_INTF_DATA_COMPRESS), which is not yet merged] Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 70d14b0db50fa..951aa1aafa96a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -54,9 +54,12 @@ #define INTF_SDM845_MASK (0)
#define INTF_SC7180_MASK \ - (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | BIT(DPU_INTF_STATUS_SUPPORTED)) + (BIT(DPU_INTF_INPUT_CTRL) | \ + BIT(DPU_INTF_TE) | \ + BIT(DPU_INTF_STATUS_SUPPORTED) | \ + BIT(DPU_DATA_HCTL_EN))
-#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) +#define INTF_SC7280_MASK (INTF_SC7180_MASK)
#define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \
From: Tony Lindgren tony@atomide.com
[ Upstream commit 4ffec92e70ac5097b9f67ec154065305b16a3b46 ]
The model property should be at the top level, let's move it out of the pinctrl node.
Fixes: d2eaf949d2c3 ("ARM: dts: omap3-gta04a5one: define GTA04A5 variant with OneNAND") Cc: Andreas Kemnade andreas@kemnade.info Cc: H. Nikolaus Schaller hns@goldelico.com Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/omap3-gta04a5one.dts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/omap3-gta04a5one.dts b/arch/arm/boot/dts/omap3-gta04a5one.dts index 9db9fe67cd63b..95df45cc70c09 100644 --- a/arch/arm/boot/dts/omap3-gta04a5one.dts +++ b/arch/arm/boot/dts/omap3-gta04a5one.dts @@ -5,9 +5,11 @@
#include "omap3-gta04a5.dts"
-&omap3_pmx_core { +/ { model = "Goldelico GTA04A5/Letux 2804 with OneNAND"; +};
+&omap3_pmx_core { gpmc_pins: pinmux_gpmc_pins { pinctrl-single,pins = <
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 48798d992ce276cf0d57bf75318daf8eabd02aa4 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/camss@1b00000: simple-bus unit address format error, expected "1b0ac00"
Fixes: 58f479f90a7c ("arm64: dts: qcom: msm8916: Add CAMSS support") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-2-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index b967dbfba3b84..aa79e08075ea7 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -1064,7 +1064,7 @@ dsi_phy0: dsi-phy@1a98300 { }; };
- camss: camss@1b00000 { + camss: camss@1b0ac00 { compatible = "qcom,msm8916-camss"; reg = <0x01b0ac00 0x200>, <0x01b00030 0x4>,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 24f0f6a8059c7108d4ee3476c95db1e7ff4feb79 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc/spmi@fc4c0000: simple-bus unit address format error, expected "fc4cf000"
Fixes: b0ad598f8ec0 ("arm64: dts: qcom: msm8994: Add SPMI PMIC arbiter device") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-8-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8994.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi index a8dc8163ee82d..4447ed146b3ac 100644 --- a/arch/arm64/boot/dts/qcom/msm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi @@ -725,7 +725,7 @@ restart@fc4ab000 { reg = <0xfc4ab000 0x4>; };
- spmi_bus: spmi@fc4c0000 { + spmi_bus: spmi@fc4cf000 { compatible = "qcom,spmi-pmic-arb"; reg = <0xfc4cf000 0x1000>, <0xfc4cb000 0x1000>,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit e959ced1d0e5ef0b1f66a0c2d0e1ae80790e5ca5 ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc/camss@a00000: simple-bus unit address format error, expected "a34000"
Fixes: e0531312e78f ("arm64: dts: qcom: msm8996: Add CAMSS support") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-9-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index cd66bb16c7392..893c241f72030 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -1771,7 +1771,7 @@ ufsphy_lane: phy@627400 { }; };
- camss: camss@a00000 { + camss: camss@a34000 { compatible = "qcom,msm8996-camss"; reg = <0x00a34000 0x1000>, <0x00a00030 0x4>,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit c8b7faa7e9913a94444b3f00b6480e53a174fcfd ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc/camss@ca00000: simple-bus unit address format error, expected "ca00020"
Fixes: f3d5d3cc6971 ("arm64: dts: qcom: sdm630: Configure the camera subsystem") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-10-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi index c2e1a0d9a2725..e00c0577cef70 100644 --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -1834,7 +1834,7 @@ pil-reloc@94c { }; };
- camss: camss@ca00000 { + camss: camss@ca00020 { compatible = "qcom,sdm660-camss"; reg = <0x0c824000 0x1000>, <0x0ca00120 0x4>,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit a05b913a27e46926ba60ba2bcacc7ec7a8403e4c ]
Match unit-address to reg entry to fix dtbs W=1 warnings:
Warning (simple_bus_reg): /soc@0/camss@a00000: simple-bus unit address format error, expected "acb3000"
Fixes: d48a6698a6b7 ("arm64: dts: qcom: sdm845: Add CAMSS ISP node") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230419211856.79332-11-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index d973aa39e410b..a0489a45aafbd 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -3921,7 +3921,7 @@ videocc: clock-controller@ab00000 { #reset-cells = <1>; };
- camss: camss@a00000 { + camss: camss@acb3000 { compatible = "qcom,sdm845-camss";
reg = <0 0xacb3000 0 0x1000>,
From: Yassine Oudjana y.oudjana@protonmail.com
[ Upstream commit c57b4247faaf6d17a319c91d5eb736c3bc65aca2 ]
Move blsp1_uart2_default and blsp1_uart2_sleep to the SoC device tree to avoid duplicating them in other device trees.
Signed-off-by: Yassine Oudjana y.oudjana@protonmail.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210901193214.250375-2-y.oudjana@protonmail.com Stable-dep-of: e27654df20d7 ("arm64: dts: qcom: apq8016-sbc: Fix regulator constraints") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi | 29 -------------------- arch/arm64/boot/dts/qcom/msm8996.dtsi | 17 ++++++++++++ 2 files changed, 17 insertions(+), 29 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi index 51e17094d7b18..eca428ab2517a 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi @@ -148,9 +148,6 @@ &blsp1_spi1 { &blsp1_uart2 { label = "BT-UART"; status = "okay"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp1_uart2_default>; - pinctrl-1 = <&blsp1_uart2_sleep>;
bluetooth { compatible = "qcom,qca6174-bt"; @@ -437,32 +434,6 @@ config { }; };
- blsp1_uart2_default: blsp1_uart2_default { - mux { - pins = "gpio41", "gpio42", "gpio43", "gpio44"; - function = "blsp_uart2"; - }; - - config { - pins = "gpio41", "gpio42", "gpio43", "gpio44"; - drive-strength = <16>; - bias-disable; - }; - }; - - blsp1_uart2_sleep: blsp1_uart2_sleep { - mux { - pins = "gpio41", "gpio42", "gpio43", "gpio44"; - function = "gpio"; - }; - - config { - pins = "gpio41", "gpio42", "gpio43", "gpio44"; - drive-strength = <2>; - bias-disable; - }; - }; - hdmi_hpd_active: hdmi_hpd_active { mux { pins = "gpio34"; diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 893c241f72030..ec3ef14048cc0 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -1228,6 +1228,20 @@ wake { }; };
+ blsp1_uart2_default: blsp1-uart2-default { + pins = "gpio41", "gpio42", "gpio43", "gpio44"; + function = "blsp_uart2"; + drive-strength = <16>; + bias-disable; + }; + + blsp1_uart2_sleep: blsp1-uart2-sleep { + pins = "gpio41", "gpio42", "gpio43", "gpio44"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + blsp1_i2c3_default: blsp1-i2c2-default { pins = "gpio47", "gpio48"; function = "blsp_i2c3"; @@ -2724,6 +2738,9 @@ blsp1_uart2: serial@7570000 { clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>; clock-names = "core", "iface"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&blsp1_uart2_default>; + pinctrl-1 = <&blsp1_uart2_sleep>; dmas = <&blsp1_dma 2>, <&blsp1_dma 3>; dma-names = "tx", "rx"; status = "disabled";
From: Bjorn Andersson bjorn.andersson@linaro.org
[ Upstream commit 0f6b380d580cd081d5e385d349f55dfc52e3d68c ]
The firmware for the modem and WiFi subsystems platform specific and is signed with a OEM specific key (or a test key). In order to support more than a single device it is therefor not possible to rely on the default path and stash these files directly in the firmware directory.
This has already been addressed for other platforms, but the APQ8016 SBC (aka db410c) was never finished upstream.
Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Reviewed-by: Stephan Gerhold stephan@gerhold.net Tested-by: Stephan Gerhold stephan@gerhold.net Link: https://lore.kernel.org/r/20210531224453.783218-1-bjorn.andersson@linaro.org Stable-dep-of: e27654df20d7 ("arm64: dts: qcom: apq8016-sbc: Fix regulator constraints") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 12 ++++++++++++ arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index f8d8f3e3664ec..351c68d29afb7 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -305,6 +305,12 @@ &mdss { status = "okay"; };
+&mpss { + status = "okay"; + + firmware-name = "qcom/msm8916/mba.mbn", "qcom/msm8916/modem.mbn"; +}; + &pm8916_resin { status = "okay"; linux,code = <KEY_VOLUMEDOWN>; @@ -312,6 +318,8 @@ &pm8916_resin {
&pronto { status = "okay"; + + firmware-name = "qcom/msm8916/wcnss.mbn"; };
&sdhc_1 { @@ -394,6 +402,10 @@ &wcd_codec { qcom,mbhc-vthreshold-high = <75 150 237 450 500>; };
+&wcnss_ctrl { + firmware-name = "qcom/msm8916/WCNSS_qcom_wlan_nv.bin"; +}; + /* Enable CoreSight */ &cti0 { status = "okay"; }; &cti1 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index aa79e08075ea7..fcc9f757c9e14 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -1771,7 +1771,7 @@ smd-edge {
label = "pronto";
- wcnss { + wcnss_ctrl: wcnss { compatible = "qcom,wcnss"; qcom,smd-channels = "WCNSS_CTRL";
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit 2533786f46d074d67a4bca04c2d44d3825594415 ]
Commit 0f6b380d580c ("arm64: dts: qcom: apq8016-sbc: Update modem and WiFi firmware path") added "firmware-name"s to the APQ8016 SBC (DB410c) device tree to separate the (test key)-signed firmware from other devices.
However, the added names are a bit confusing. The "modem" firmware used by DB410c is actually a simplified version for APQ8016 that lacks most of the modem functionality (phone calls, SMS etc) that is available on MSM8916. Placing it in "qcom/msm8916/modem.mbn" suggests that it supports all functionality for MSM and not just the reduced functionality for APQ.
Request the firmware from "qcom/apq8016/modem.mbn" instead to clarify this. Do the same for "wcnss.mbn" for consistency (although the WCNSS firmware works just fine on MSM8916).
Finally, add a "_sbc" suffix to the WCNSS_qcom_wlan_nv.bin firmware file. It seems like the nv.bin firmware is somewhat board specific and can therefore vary a bit from device to device. This makes it more clear which board it is intended to be used for.
Signed-off-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210922195853.95574-1-stephan@gerhold.net Stable-dep-of: e27654df20d7 ("arm64: dts: qcom: apq8016-sbc: Fix regulator constraints") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 351c68d29afb7..0e4a1f0040211 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -308,7 +308,7 @@ &mdss { &mpss { status = "okay";
- firmware-name = "qcom/msm8916/mba.mbn", "qcom/msm8916/modem.mbn"; + firmware-name = "qcom/apq8016/mba.mbn", "qcom/apq8016/modem.mbn"; };
&pm8916_resin { @@ -319,7 +319,7 @@ &pm8916_resin { &pronto { status = "okay";
- firmware-name = "qcom/msm8916/wcnss.mbn"; + firmware-name = "qcom/apq8016/wcnss.mbn"; };
&sdhc_1 { @@ -403,7 +403,7 @@ &wcd_codec { };
&wcnss_ctrl { - firmware-name = "qcom/msm8916/WCNSS_qcom_wlan_nv.bin"; + firmware-name = "qcom/apq8016/WCNSS_qcom_wlan_nv_sbc.bin"; };
/* Enable CoreSight */
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit a4344427eadd6caf0dc9e5384b023083e567221d ]
The majority of device tree nodes for mpps use xxxx-state as pinctrl nodes. Change names of mpps pinctrl nodes for the apq8016-sbc board to follow that pattern.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20211008012524.481877-13-dmitry.baryshkov@linaro.o... Stable-dep-of: e27654df20d7 ("arm64: dts: qcom: apq8016-sbc: Fix regulator constraints") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 0e4a1f0040211..1c097098f1e0f 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -821,7 +821,7 @@ &pm8916_mpps { pinctrl-names = "default"; pinctrl-0 = <&ls_exp_gpio_f>;
- ls_exp_gpio_f: pm8916-mpp4 { + ls_exp_gpio_f: pm8916-mpp4-state { pins = "mpp4"; function = "digital";
@@ -829,7 +829,7 @@ ls_exp_gpio_f: pm8916-mpp4 { power-source = <PM8916_MPP_L5>; // 1.8V };
- pm8916_mpps_leds: pm8916-mpps-leds { + pm8916_mpps_leds: pm8916-mpps-state { pins = "mpp2", "mpp3"; function = "digital";
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit 442ee1fc60c47539253fafd4cbbe2f1ec22e2a46 ]
For some reason apq8016-sbc, apq8096-db820c, msm8916-mtp and msm8996-mtp were added as separate .dts and .dtsi files where the first only contains the model name and the latter contains most of the actual definitions. Perhaps this was done with the expectation that there would be other devices also making use of exactly the same. However, this has not been the case until now and it also seems unlikely in the future. Having the extra .dtsi only clutters the file list and provides little benefit.
Move the contents of the .dtsi into the .dts file to make this consistent with most other devices that simply define everything in the .dts.
There are no functional changes introduced by this patch: The compiled ".dtb"s are completely identical.
Signed-off-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20211018133656.32649-1-stephan@gerhold.net Stable-dep-of: e27654df20d7 ("arm64: dts: qcom: apq8016-sbc: Fix regulator constraints") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 832 +++++++++++++- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 838 -------------- arch/arm64/boot/dts/qcom/apq8096-db820c.dts | 1070 ++++++++++++++++- arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi | 1076 ------------------ arch/arm64/boot/dts/qcom/msm8916-mtp.dts | 15 +- arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi | 21 - arch/arm64/boot/dts/qcom/msm8996-mtp.dts | 24 +- arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi | 30 - 8 files changed, 1937 insertions(+), 1969 deletions(-) delete mode 100644 arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi delete mode 100644 arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi delete mode 100644 arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi delete mode 100644 arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts index f3c0dbfd0a232..a5320d6d30e7b 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts @@ -5,9 +5,839 @@
/dts-v1/;
-#include "apq8016-sbc.dtsi" +#include "msm8916-pm8916.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +#include <dt-bindings/pinctrl/qcom,pmic-mpp.h> +#include <dt-bindings/sound/apq8016-lpass.h>
/ { model = "Qualcomm Technologies, Inc. APQ 8016 SBC"; compatible = "qcom,apq8016-sbc", "qcom,apq8016"; + + aliases { + serial0 = &blsp1_uart2; + serial1 = &blsp1_uart1; + usid0 = &pm8916_0; + i2c0 = &blsp_i2c2; + i2c1 = &blsp_i2c6; + i2c3 = &blsp_i2c4; + spi0 = &blsp_spi5; + spi1 = &blsp_spi3; + }; + + chosen { + stdout-path = "serial0"; + }; + + camera_vdddo_1v8: camera-vdddo-1v8 { + compatible = "regulator-fixed"; + regulator-name = "camera_vdddo"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + camera_vdda_2v8: camera-vdda-2v8 { + compatible = "regulator-fixed"; + regulator-name = "camera_vdda"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + }; + + camera_vddd_1v5: camera-vddd-1v5 { + compatible = "regulator-fixed"; + regulator-name = "camera_vddd"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + }; + + reserved-memory { + ramoops@bff00000 { + compatible = "ramoops"; + reg = <0x0 0xbff00000 0x0 0x100000>; + + record-size = <0x20000>; + console-size = <0x20000>; + ftrace-size = <0x20000>; + }; + }; + + usb2513 { + compatible = "smsc,usb3503"; + reset-gpios = <&pm8916_gpios 3 GPIO_ACTIVE_LOW>; + initial-mode = <1>; + }; + + usb_id: usb-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_id_default>; + }; + + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&adv7533_out>; + }; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; + + pinctrl-names = "default"; + pinctrl-0 = <&msm_key_volp_n_default>; + + button@0 { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + pinctrl-names = "default"; + pinctrl-0 = <&msmgpio_leds>, + <&pm8916_gpios_leds>, + <&pm8916_mpps_leds>; + + compatible = "gpio-leds"; + + led@1 { + label = "apq8016-sbc:green:user1"; + gpios = <&msmgpio 21 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + default-state = "off"; + }; + + led@2 { + label = "apq8016-sbc:green:user2"; + gpios = <&msmgpio 120 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc0"; + default-state = "off"; + }; + + led@3 { + label = "apq8016-sbc:green:user3"; + gpios = <&pm8916_gpios 1 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc1"; + default-state = "off"; + }; + + led@4 { + label = "apq8016-sbc:green:user4"; + gpios = <&pm8916_gpios 2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "none"; + panic-indicator; + default-state = "off"; + }; + + led@5 { + label = "apq8016-sbc:yellow:wlan"; + gpios = <&pm8916_mpps 2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "phy0tx"; + default-state = "off"; + }; + + led@6 { + label = "apq8016-sbc:blue:bt"; + gpios = <&pm8916_mpps 3 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "bluetooth-power"; + default-state = "off"; + }; + }; +}; + +&blsp_dma { + status = "okay"; +}; + +&blsp_i2c2 { + /* On Low speed expansion */ + status = "okay"; + label = "LS-I2C0"; +}; + +&blsp_i2c4 { + /* On High speed expansion */ + status = "okay"; + label = "HS-I2C2"; + + adv_bridge: bridge@39 { + status = "okay"; + + compatible = "adi,adv7533"; + reg = <0x39>; + + interrupt-parent = <&msmgpio>; + interrupts = <31 IRQ_TYPE_EDGE_FALLING>; + + adi,dsi-lanes = <4>; + clocks = <&rpmcc RPM_SMD_BB_CLK2>; + clock-names = "cec"; + + pd-gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>; + + avdd-supply = <&pm8916_l6>; + v1p2-supply = <&pm8916_l6>; + v3p3-supply = <&pm8916_l17>; + + pinctrl-names = "default","sleep"; + pinctrl-0 = <&adv7533_int_active &adv7533_switch_active>; + pinctrl-1 = <&adv7533_int_suspend &adv7533_switch_suspend>; + #sound-dai-cells = <1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7533_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + adv7533_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; +}; + +&blsp_i2c6 { + /* On Low speed expansion */ + status = "okay"; + label = "LS-I2C1"; +}; + +&blsp_spi3 { + /* On High speed expansion */ + status = "okay"; + label = "HS-SPI1"; +}; + +&blsp_spi5 { + /* On Low speed expansion */ + status = "okay"; + label = "LS-SPI0"; +}; + +&blsp1_uart1 { + status = "okay"; + label = "LS-UART0"; +}; + +&blsp1_uart2 { + status = "okay"; + label = "LS-UART1"; +}; + +&camss { + status = "okay"; + ports { + port@0 { + reg = <0>; + csiphy0_ep: endpoint { + clock-lanes = <1>; + data-lanes = <0 2>; + remote-endpoint = <&ov5640_ep>; + status = "okay"; + }; + }; + }; +}; + +&cci { + status = "okay"; +}; + +&cci_i2c0 { + camera_rear@3b { + compatible = "ovti,ov5640"; + reg = <0x3b>; + + enable-gpios = <&msmgpio 34 GPIO_ACTIVE_HIGH>; + reset-gpios = <&msmgpio 35 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&camera_rear_default>; + + clocks = <&gcc GCC_CAMSS_MCLK0_CLK>; + clock-names = "xclk"; + clock-frequency = <23880000>; + + vdddo-supply = <&camera_vdddo_1v8>; + vdda-supply = <&camera_vdda_2v8>; + vddd-supply = <&camera_vddd_1v5>; + + /* No camera mezzanine by default */ + status = "disabled"; + + port { + ov5640_ep: endpoint { + clock-lanes = <1>; + data-lanes = <0 2>; + remote-endpoint = <&csiphy0_ep>; + }; + }; + }; +}; + +&dsi0_out { + data-lanes = <0 1 2 3>; + remote-endpoint = <&adv7533_in>; +}; + +&lpass { + status = "okay"; +}; + +&mdss { + status = "okay"; +}; + +&mpss { + status = "okay"; + + firmware-name = "qcom/apq8016/mba.mbn", "qcom/apq8016/modem.mbn"; +}; + +&pm8916_resin { + status = "okay"; + linux,code = <KEY_VOLUMEDOWN>; +}; + +&pronto { + status = "okay"; + + firmware-name = "qcom/apq8016/wcnss.mbn"; +}; + +&sdhc_1 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; +}; + +&sdhc_2 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + + cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>; +}; + +&sound { + status = "okay"; + + pinctrl-0 = <&cdc_pdm_lines_act &ext_sec_tlmm_lines_act &ext_mclk_tlmm_lines_act>; + pinctrl-1 = <&cdc_pdm_lines_sus &ext_sec_tlmm_lines_sus &ext_mclk_tlmm_lines_sus>; + pinctrl-names = "default", "sleep"; + qcom,model = "DB410c"; + qcom,audio-routing = + "AMIC2", "MIC BIAS Internal2", + "AMIC3", "MIC BIAS External1"; + + external-dai-link@0 { + link-name = "ADV7533"; + cpu { + sound-dai = <&lpass MI2S_QUATERNARY>; + }; + codec { + sound-dai = <&adv_bridge 0>; + }; + }; + + internal-codec-playback-dai-link@0 { + link-name = "WCD"; + cpu { + sound-dai = <&lpass MI2S_PRIMARY>; + }; + codec { + sound-dai = <&lpass_codec 0>, <&wcd_codec 0>; + }; + }; + + internal-codec-capture-dai-link@0 { + link-name = "WCD-Capture"; + cpu { + sound-dai = <&lpass MI2S_TERTIARY>; + }; + codec { + sound-dai = <&lpass_codec 1>, <&wcd_codec 1>; + }; + }; +}; + +&usb { + status = "okay"; + extcon = <&usb_id>, <&usb_id>; + + pinctrl-names = "default", "device"; + pinctrl-0 = <&usb_sw_sel_pm &usb_hub_reset_pm>; + pinctrl-1 = <&usb_sw_sel_pm_device &usb_hub_reset_pm_device>; +}; + +&usb_hs_phy { + extcon = <&usb_id>; +}; + +&wcd_codec { + clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>; + clock-names = "mclk"; + qcom,mbhc-vthreshold-low = <75 150 237 450 500>; + qcom,mbhc-vthreshold-high = <75 150 237 450 500>; +}; + +&wcnss_ctrl { + firmware-name = "qcom/apq8016/WCNSS_qcom_wlan_nv_sbc.bin"; +}; + +/* Enable CoreSight */ +&cti0 { status = "okay"; }; +&cti1 { status = "okay"; }; +&cti12 { status = "okay"; }; +&cti13 { status = "okay"; }; +&cti14 { status = "okay"; }; +&cti15 { status = "okay"; }; +&debug0 { status = "okay"; }; +&debug1 { status = "okay"; }; +&debug2 { status = "okay"; }; +&debug3 { status = "okay"; }; +&etf { status = "okay"; }; +&etm0 { status = "okay"; }; +&etm1 { status = "okay"; }; +&etm2 { status = "okay"; }; +&etm3 { status = "okay"; }; +&etr { status = "okay"; }; +&funnel0 { status = "okay"; }; +&funnel1 { status = "okay"; }; +&replicator { status = "okay"; }; +&stm { status = "okay"; }; +&tpiu { status = "okay"; }; + +&smd_rpm_regulators { + vdd_l1_l2_l3-supply = <&pm8916_s3>; + vdd_l4_l5_l6-supply = <&pm8916_s4>; + vdd_l7-supply = <&pm8916_s4>; + + s3 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1562000>; + }; + + s4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-always-on; + regulator-boot-on; + }; + + l1 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + + l2 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + l4 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l5 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + l7 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l8 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l9 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l10 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l11 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + regulator-allow-set-load; + regulator-system-load = <200000>; + }; + + l12 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l13 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l14 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + /** + * 1.8v required on LS expansion + * for mezzanine boards + */ + l15 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + regulator-always-on; + }; + + l16 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l17 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + l18 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; +}; + +/* + * 2mA drive strength is not enough when connecting multiple + * I2C devices with different pull up resistors. + */ +&i2c2_default { + drive-strength = <16>; +}; + +&i2c4_default { + drive-strength = <16>; +}; + +&i2c6_default { + drive-strength = <16>; +}; + +/* + * GPIO name legend: proper name = the GPIO line is used as GPIO + * NC = not connected (pin out but not routed from the chip to + * anything the board) + * "[PER]" = pin is muxed for [peripheral] (not GPIO) + * LSEC = Low Speed External Connector + * HSEC = High Speed External Connector + * + * Line names are taken from the schematic "DragonBoard410c" + * dated monday, august 31, 2015. Page 5 in particular. + * + * For the lines routed to the external connectors the + * lines are named after the 96Boards CE Specification 1.0, + * Appendix "Expansion Connector Signal Description". + * + * When the 96Board naming of a line and the schematic name of + * the same line are in conflict, the 96Board specification + * takes precedence, which means that the external UART on the + * LSEC is named UART0 while the schematic and SoC names this + * UART3. This is only for the informational lines i.e. "[FOO]", + * the GPIO named lines "GPIO-A" thru "GPIO-L" are the only + * ones actually used for GPIO. + */ + +&msmgpio { + gpio-line-names = + "[UART0_TX]", /* GPIO_0, LSEC pin 5 */ + "[UART0_RX]", /* GPIO_1, LSEC pin 7 */ + "[UART0_CTS_N]", /* GPIO_2, LSEC pin 3 */ + "[UART0_RTS_N]", /* GPIO_3, LSEC pin 9 */ + "[UART1_TX]", /* GPIO_4, LSEC pin 11 */ + "[UART1_RX]", /* GPIO_5, LSEC pin 13 */ + "[I2C0_SDA]", /* GPIO_8, LSEC pin 17 */ + "[I2C0_SCL]", /* GPIO_7, LSEC pin 15 */ + "[SPI1_DOUT]", /* SPI1_MOSI, HSEC pin 1 */ + "[SPI1_DIN]", /* SPI1_MISO, HSEC pin 11 */ + "[SPI1_CS]", /* SPI1_CS_N, HSEC pin 7 */ + "[SPI1_SCLK]", /* SPI1_CLK, HSEC pin 9 */ + "GPIO-B", /* LS_EXP_GPIO_B, LSEC pin 24 */ + "GPIO-C", /* LS_EXP_GPIO_C, LSEC pin 25 */ + "[I2C3_SDA]", /* HSEC pin 38 */ + "[I2C3_SCL]", /* HSEC pin 36 */ + "[SPI0_MOSI]", /* LSEC pin 14 */ + "[SPI0_MISO]", /* LSEC pin 10 */ + "[SPI0_CS_N]", /* LSEC pin 12 */ + "[SPI0_CLK]", /* LSEC pin 8 */ + "HDMI_HPD_N", /* GPIO 20 */ + "USR_LED_1_CTRL", + "[I2C1_SDA]", /* GPIO_22, LSEC pin 21 */ + "[I2C1_SCL]", /* GPIO_23, LSEC pin 19 */ + "GPIO-G", /* LS_EXP_GPIO_G, LSEC pin 29 */ + "GPIO-H", /* LS_EXP_GPIO_H, LSEC pin 30 */ + "[CSI0_MCLK]", /* HSEC pin 15 */ + "[CSI1_MCLK]", /* HSEC pin 17 */ + "GPIO-K", /* LS_EXP_GPIO_K, LSEC pin 33 */ + "[I2C2_SDA]", /* HSEC pin 34 */ + "[I2C2_SCL]", /* HSEC pin 32 */ + "DSI2HDMI_INT_N", + "DSI_SW_SEL_APQ", + "GPIO-L", /* LS_EXP_GPIO_L, LSEC pin 34 */ + "GPIO-J", /* LS_EXP_GPIO_J, LSEC pin 32 */ + "GPIO-I", /* LS_EXP_GPIO_I, LSEC pin 31 */ + "GPIO-A", /* LS_EXP_GPIO_A, LSEC pin 23 */ + "FORCED_USB_BOOT", + "SD_CARD_DET_N", + "[WCSS_BT_SSBI]", + "[WCSS_WLAN_DATA_2]", /* GPIO 40 */ + "[WCSS_WLAN_DATA_1]", + "[WCSS_WLAN_DATA_0]", + "[WCSS_WLAN_SET]", + "[WCSS_WLAN_CLK]", + "[WCSS_FM_SSBI]", + "[WCSS_FM_SDI]", + "[WCSS_BT_DAT_CTL]", + "[WCSS_BT_DAT_STB]", + "NC", + "NC", /* GPIO 50 */ + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", /* GPIO 60 */ + "NC", + "NC", + "[CDC_PDM0_CLK]", + "[CDC_PDM0_SYNC]", + "[CDC_PDM0_TX0]", + "[CDC_PDM0_RX0]", + "[CDC_PDM0_RX1]", + "[CDC_PDM0_RX2]", + "GPIO-D", /* LS_EXP_GPIO_D, LSEC pin 26 */ + "NC", /* GPIO 70 */ + "NC", + "NC", + "NC", + "NC", /* GPIO 74 */ + "NC", + "NC", + "NC", + "NC", + "NC", + "BOOT_CONFIG_0", /* GPIO 80 */ + "BOOT_CONFIG_1", + "BOOT_CONFIG_2", + "BOOT_CONFIG_3", + "NC", + "NC", + "BOOT_CONFIG_5", + "NC", + "NC", + "NC", + "NC", /* GPIO 90 */ + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", /* GPIO 100 */ + "NC", + "NC", + "NC", + "SSBI_GPS", + "NC", + "NC", + "KEY_VOLP_N", + "NC", + "NC", + "[LS_EXP_MI2S_WS]", /* GPIO 110 */ + "NC", + "NC", + "[LS_EXP_MI2S_SCK]", + "[LS_EXP_MI2S_DATA0]", + "GPIO-E", /* LS_EXP_GPIO_E, LSEC pin 27 */ + "NC", + "[DSI2HDMI_MI2S_WS]", + "[DSI2HDMI_MI2S_SCK]", + "[DSI2HDMI_MI2S_DATA0]", + "USR_LED_2_CTRL", /* GPIO 120 */ + "SB_HS_ID"; + + msmgpio_leds: msmgpio-leds { + pins = "gpio21", "gpio120"; + function = "gpio"; + + output-low; + }; + + usb_id_default: usb-id-default { + pins = "gpio121"; + function = "gpio"; + + drive-strength = <8>; + input-enable; + bias-pull-up; + }; + + adv7533_int_active: adv533-int-active { + pins = "gpio31"; + function = "gpio"; + + drive-strength = <16>; + bias-disable; + }; + + adv7533_int_suspend: adv7533-int-suspend { + pins = "gpio31"; + function = "gpio"; + + drive-strength = <2>; + bias-disable; + }; + + adv7533_switch_active: adv7533-switch-active { + pins = "gpio32"; + function = "gpio"; + + drive-strength = <16>; + bias-disable; + }; + + adv7533_switch_suspend: adv7533-switch-suspend { + pins = "gpio32"; + function = "gpio"; + + drive-strength = <2>; + bias-disable; + }; + + msm_key_volp_n_default: msm-key-volp-n-default { + pins = "gpio107"; + function = "gpio"; + + drive-strength = <8>; + input-enable; + bias-pull-up; + }; +}; + +&pm8916_gpios { + gpio-line-names = + "USR_LED_3_CTRL", + "USR_LED_4_CTRL", + "USB_HUB_RESET_N_PM", + "USB_SW_SEL_PM"; + + usb_hub_reset_pm: usb-hub-reset-pm { + pins = "gpio3"; + function = PMIC_GPIO_FUNC_NORMAL; + + input-disable; + output-high; + }; + + usb_hub_reset_pm_device: usb-hub-reset-pm-device { + pins = "gpio3"; + function = PMIC_GPIO_FUNC_NORMAL; + + output-low; + }; + + usb_sw_sel_pm: usb-sw-sel-pm { + pins = "gpio4"; + function = PMIC_GPIO_FUNC_NORMAL; + + power-source = <PM8916_GPIO_VPH>; + input-disable; + output-high; + }; + + usb_sw_sel_pm_device: usb-sw-sel-pm-device { + pins = "gpio4"; + function = PMIC_GPIO_FUNC_NORMAL; + + power-source = <PM8916_GPIO_VPH>; + input-disable; + output-low; + }; + + pm8916_gpios_leds: pm8916-gpios-leds { + pins = "gpio1", "gpio2"; + function = PMIC_GPIO_FUNC_NORMAL; + + output-low; + }; +}; + +&pm8916_mpps { + gpio-line-names = + "VDD_PX_BIAS", + "WLAN_LED_CTRL", + "BT_LED_CTRL", + "GPIO-F"; /* LS_EXP_GPIO_F, LSEC pin 28 */ + + pinctrl-names = "default"; + pinctrl-0 = <&ls_exp_gpio_f>; + + ls_exp_gpio_f: pm8916-mpp4-state { + pins = "mpp4"; + function = "digital"; + + output-low; + power-source = <PM8916_MPP_L5>; // 1.8V + }; + + pm8916_mpps_leds: pm8916-mpps-state { + pins = "mpp2", "mpp3"; + function = "digital"; + + output-low; + }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi deleted file mode 100644 index 1c097098f1e0f..0000000000000 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ /dev/null @@ -1,838 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2015, The Linux Foundation. All rights reserved. - */ - -#include "msm8916-pm8916.dtsi" -#include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/input/input.h> -#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> -#include <dt-bindings/pinctrl/qcom,pmic-mpp.h> -#include <dt-bindings/sound/apq8016-lpass.h> - -/ { - aliases { - serial0 = &blsp1_uart2; - serial1 = &blsp1_uart1; - usid0 = &pm8916_0; - i2c0 = &blsp_i2c2; - i2c1 = &blsp_i2c6; - i2c3 = &blsp_i2c4; - spi0 = &blsp_spi5; - spi1 = &blsp_spi3; - }; - - chosen { - stdout-path = "serial0"; - }; - - camera_vdddo_1v8: camera-vdddo-1v8 { - compatible = "regulator-fixed"; - regulator-name = "camera_vdddo"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-always-on; - }; - - camera_vdda_2v8: camera-vdda-2v8 { - compatible = "regulator-fixed"; - regulator-name = "camera_vdda"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - regulator-always-on; - }; - - camera_vddd_1v5: camera-vddd-1v5 { - compatible = "regulator-fixed"; - regulator-name = "camera_vddd"; - regulator-min-microvolt = <1500000>; - regulator-max-microvolt = <1500000>; - regulator-always-on; - }; - - reserved-memory { - ramoops@bff00000 { - compatible = "ramoops"; - reg = <0x0 0xbff00000 0x0 0x100000>; - - record-size = <0x20000>; - console-size = <0x20000>; - ftrace-size = <0x20000>; - }; - }; - - usb2513 { - compatible = "smsc,usb3503"; - reset-gpios = <&pm8916_gpios 3 GPIO_ACTIVE_LOW>; - initial-mode = <1>; - }; - - usb_id: usb-id { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&usb_id_default>; - }; - - hdmi-out { - compatible = "hdmi-connector"; - type = "a"; - - port { - hdmi_con: endpoint { - remote-endpoint = <&adv7533_out>; - }; - }; - }; - - gpio-keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - autorepeat; - - pinctrl-names = "default"; - pinctrl-0 = <&msm_key_volp_n_default>; - - button@0 { - label = "Volume Up"; - linux,code = <KEY_VOLUMEUP>; - gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>; - }; - }; - - leds { - pinctrl-names = "default"; - pinctrl-0 = <&msmgpio_leds>, - <&pm8916_gpios_leds>, - <&pm8916_mpps_leds>; - - compatible = "gpio-leds"; - - led@1 { - label = "apq8016-sbc:green:user1"; - gpios = <&msmgpio 21 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - default-state = "off"; - }; - - led@2 { - label = "apq8016-sbc:green:user2"; - gpios = <&msmgpio 120 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "mmc0"; - default-state = "off"; - }; - - led@3 { - label = "apq8016-sbc:green:user3"; - gpios = <&pm8916_gpios 1 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "mmc1"; - default-state = "off"; - }; - - led@4 { - label = "apq8016-sbc:green:user4"; - gpios = <&pm8916_gpios 2 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "none"; - panic-indicator; - default-state = "off"; - }; - - led@5 { - label = "apq8016-sbc:yellow:wlan"; - gpios = <&pm8916_mpps 2 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "phy0tx"; - default-state = "off"; - }; - - led@6 { - label = "apq8016-sbc:blue:bt"; - gpios = <&pm8916_mpps 3 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "bluetooth-power"; - default-state = "off"; - }; - }; -}; - -&blsp_dma { - status = "okay"; -}; - -&blsp_i2c2 { - /* On Low speed expansion */ - status = "okay"; - label = "LS-I2C0"; -}; - -&blsp_i2c4 { - /* On High speed expansion */ - status = "okay"; - label = "HS-I2C2"; - - adv_bridge: bridge@39 { - status = "okay"; - - compatible = "adi,adv7533"; - reg = <0x39>; - - interrupt-parent = <&msmgpio>; - interrupts = <31 IRQ_TYPE_EDGE_FALLING>; - - adi,dsi-lanes = <4>; - clocks = <&rpmcc RPM_SMD_BB_CLK2>; - clock-names = "cec"; - - pd-gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>; - - avdd-supply = <&pm8916_l6>; - v1p2-supply = <&pm8916_l6>; - v3p3-supply = <&pm8916_l17>; - - pinctrl-names = "default","sleep"; - pinctrl-0 = <&adv7533_int_active &adv7533_switch_active>; - pinctrl-1 = <&adv7533_int_suspend &adv7533_switch_suspend>; - #sound-dai-cells = <1>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - adv7533_in: endpoint { - remote-endpoint = <&dsi0_out>; - }; - }; - - port@1 { - reg = <1>; - adv7533_out: endpoint { - remote-endpoint = <&hdmi_con>; - }; - }; - }; - }; -}; - -&blsp_i2c6 { - /* On Low speed expansion */ - status = "okay"; - label = "LS-I2C1"; -}; - -&blsp_spi3 { - /* On High speed expansion */ - status = "okay"; - label = "HS-SPI1"; -}; - -&blsp_spi5 { - /* On Low speed expansion */ - status = "okay"; - label = "LS-SPI0"; -}; - -&blsp1_uart1 { - status = "okay"; - label = "LS-UART0"; -}; - -&blsp1_uart2 { - status = "okay"; - label = "LS-UART1"; -}; - -&camss { - status = "okay"; - ports { - port@0 { - reg = <0>; - csiphy0_ep: endpoint { - clock-lanes = <1>; - data-lanes = <0 2>; - remote-endpoint = <&ov5640_ep>; - status = "okay"; - }; - }; - }; -}; - -&cci { - status = "okay"; -}; - -&cci_i2c0 { - camera_rear@3b { - compatible = "ovti,ov5640"; - reg = <0x3b>; - - enable-gpios = <&msmgpio 34 GPIO_ACTIVE_HIGH>; - reset-gpios = <&msmgpio 35 GPIO_ACTIVE_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&camera_rear_default>; - - clocks = <&gcc GCC_CAMSS_MCLK0_CLK>; - clock-names = "xclk"; - clock-frequency = <23880000>; - - vdddo-supply = <&camera_vdddo_1v8>; - vdda-supply = <&camera_vdda_2v8>; - vddd-supply = <&camera_vddd_1v5>; - - /* No camera mezzanine by default */ - status = "disabled"; - - port { - ov5640_ep: endpoint { - clock-lanes = <1>; - data-lanes = <0 2>; - remote-endpoint = <&csiphy0_ep>; - }; - }; - }; -}; - -&dsi0_out { - data-lanes = <0 1 2 3>; - remote-endpoint = <&adv7533_in>; -}; - -&lpass { - status = "okay"; -}; - -&mdss { - status = "okay"; -}; - -&mpss { - status = "okay"; - - firmware-name = "qcom/apq8016/mba.mbn", "qcom/apq8016/modem.mbn"; -}; - -&pm8916_resin { - status = "okay"; - linux,code = <KEY_VOLUMEDOWN>; -}; - -&pronto { - status = "okay"; - - firmware-name = "qcom/apq8016/wcnss.mbn"; -}; - -&sdhc_1 { - status = "okay"; - - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; - pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; -}; - -&sdhc_2 { - status = "okay"; - - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; - pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; - - cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>; -}; - -&sound { - status = "okay"; - - pinctrl-0 = <&cdc_pdm_lines_act &ext_sec_tlmm_lines_act &ext_mclk_tlmm_lines_act>; - pinctrl-1 = <&cdc_pdm_lines_sus &ext_sec_tlmm_lines_sus &ext_mclk_tlmm_lines_sus>; - pinctrl-names = "default", "sleep"; - qcom,model = "DB410c"; - qcom,audio-routing = - "AMIC2", "MIC BIAS Internal2", - "AMIC3", "MIC BIAS External1"; - - external-dai-link@0 { - link-name = "ADV7533"; - cpu { - sound-dai = <&lpass MI2S_QUATERNARY>; - }; - codec { - sound-dai = <&adv_bridge 0>; - }; - }; - - internal-codec-playback-dai-link@0 { - link-name = "WCD"; - cpu { - sound-dai = <&lpass MI2S_PRIMARY>; - }; - codec { - sound-dai = <&lpass_codec 0>, <&wcd_codec 0>; - }; - }; - - internal-codec-capture-dai-link@0 { - link-name = "WCD-Capture"; - cpu { - sound-dai = <&lpass MI2S_TERTIARY>; - }; - codec { - sound-dai = <&lpass_codec 1>, <&wcd_codec 1>; - }; - }; -}; - -&usb { - status = "okay"; - extcon = <&usb_id>, <&usb_id>; - - pinctrl-names = "default", "device"; - pinctrl-0 = <&usb_sw_sel_pm &usb_hub_reset_pm>; - pinctrl-1 = <&usb_sw_sel_pm_device &usb_hub_reset_pm_device>; -}; - -&usb_hs_phy { - extcon = <&usb_id>; -}; - -&wcd_codec { - clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>; - clock-names = "mclk"; - qcom,mbhc-vthreshold-low = <75 150 237 450 500>; - qcom,mbhc-vthreshold-high = <75 150 237 450 500>; -}; - -&wcnss_ctrl { - firmware-name = "qcom/apq8016/WCNSS_qcom_wlan_nv_sbc.bin"; -}; - -/* Enable CoreSight */ -&cti0 { status = "okay"; }; -&cti1 { status = "okay"; }; -&cti12 { status = "okay"; }; -&cti13 { status = "okay"; }; -&cti14 { status = "okay"; }; -&cti15 { status = "okay"; }; -&debug0 { status = "okay"; }; -&debug1 { status = "okay"; }; -&debug2 { status = "okay"; }; -&debug3 { status = "okay"; }; -&etf { status = "okay"; }; -&etm0 { status = "okay"; }; -&etm1 { status = "okay"; }; -&etm2 { status = "okay"; }; -&etm3 { status = "okay"; }; -&etr { status = "okay"; }; -&funnel0 { status = "okay"; }; -&funnel1 { status = "okay"; }; -&replicator { status = "okay"; }; -&stm { status = "okay"; }; -&tpiu { status = "okay"; }; - -&smd_rpm_regulators { - vdd_l1_l2_l3-supply = <&pm8916_s3>; - vdd_l4_l5_l6-supply = <&pm8916_s4>; - vdd_l7-supply = <&pm8916_s4>; - - s3 { - regulator-min-microvolt = <375000>; - regulator-max-microvolt = <1562000>; - }; - - s4 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - - regulator-always-on; - regulator-boot-on; - }; - - l1 { - regulator-min-microvolt = <375000>; - regulator-max-microvolt = <1525000>; - }; - - l2 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - }; - - l4 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - }; - - l5 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - }; - - l6 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - - l7 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - }; - - l8 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - }; - - l9 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - }; - - l10 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - }; - - l11 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - regulator-allow-set-load; - regulator-system-load = <200000>; - }; - - l12 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - }; - - l13 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - }; - - l14 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - }; - - /** - * 1.8v required on LS expansion - * for mezzanine boards - */ - l15 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - regulator-always-on; - }; - - l16 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - }; - - l17 { - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - l18 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; - }; -}; - -/* - * 2mA drive strength is not enough when connecting multiple - * I2C devices with different pull up resistors. - */ -&i2c2_default { - drive-strength = <16>; -}; - -&i2c4_default { - drive-strength = <16>; -}; - -&i2c6_default { - drive-strength = <16>; -}; - -/* - * GPIO name legend: proper name = the GPIO line is used as GPIO - * NC = not connected (pin out but not routed from the chip to - * anything the board) - * "[PER]" = pin is muxed for [peripheral] (not GPIO) - * LSEC = Low Speed External Connector - * HSEC = High Speed External Connector - * - * Line names are taken from the schematic "DragonBoard410c" - * dated monday, august 31, 2015. Page 5 in particular. - * - * For the lines routed to the external connectors the - * lines are named after the 96Boards CE Specification 1.0, - * Appendix "Expansion Connector Signal Description". - * - * When the 96Board naming of a line and the schematic name of - * the same line are in conflict, the 96Board specification - * takes precedence, which means that the external UART on the - * LSEC is named UART0 while the schematic and SoC names this - * UART3. This is only for the informational lines i.e. "[FOO]", - * the GPIO named lines "GPIO-A" thru "GPIO-L" are the only - * ones actually used for GPIO. - */ - -&msmgpio { - gpio-line-names = - "[UART0_TX]", /* GPIO_0, LSEC pin 5 */ - "[UART0_RX]", /* GPIO_1, LSEC pin 7 */ - "[UART0_CTS_N]", /* GPIO_2, LSEC pin 3 */ - "[UART0_RTS_N]", /* GPIO_3, LSEC pin 9 */ - "[UART1_TX]", /* GPIO_4, LSEC pin 11 */ - "[UART1_RX]", /* GPIO_5, LSEC pin 13 */ - "[I2C0_SDA]", /* GPIO_8, LSEC pin 17 */ - "[I2C0_SCL]", /* GPIO_7, LSEC pin 15 */ - "[SPI1_DOUT]", /* SPI1_MOSI, HSEC pin 1 */ - "[SPI1_DIN]", /* SPI1_MISO, HSEC pin 11 */ - "[SPI1_CS]", /* SPI1_CS_N, HSEC pin 7 */ - "[SPI1_SCLK]", /* SPI1_CLK, HSEC pin 9 */ - "GPIO-B", /* LS_EXP_GPIO_B, LSEC pin 24 */ - "GPIO-C", /* LS_EXP_GPIO_C, LSEC pin 25 */ - "[I2C3_SDA]", /* HSEC pin 38 */ - "[I2C3_SCL]", /* HSEC pin 36 */ - "[SPI0_MOSI]", /* LSEC pin 14 */ - "[SPI0_MISO]", /* LSEC pin 10 */ - "[SPI0_CS_N]", /* LSEC pin 12 */ - "[SPI0_CLK]", /* LSEC pin 8 */ - "HDMI_HPD_N", /* GPIO 20 */ - "USR_LED_1_CTRL", - "[I2C1_SDA]", /* GPIO_22, LSEC pin 21 */ - "[I2C1_SCL]", /* GPIO_23, LSEC pin 19 */ - "GPIO-G", /* LS_EXP_GPIO_G, LSEC pin 29 */ - "GPIO-H", /* LS_EXP_GPIO_H, LSEC pin 30 */ - "[CSI0_MCLK]", /* HSEC pin 15 */ - "[CSI1_MCLK]", /* HSEC pin 17 */ - "GPIO-K", /* LS_EXP_GPIO_K, LSEC pin 33 */ - "[I2C2_SDA]", /* HSEC pin 34 */ - "[I2C2_SCL]", /* HSEC pin 32 */ - "DSI2HDMI_INT_N", - "DSI_SW_SEL_APQ", - "GPIO-L", /* LS_EXP_GPIO_L, LSEC pin 34 */ - "GPIO-J", /* LS_EXP_GPIO_J, LSEC pin 32 */ - "GPIO-I", /* LS_EXP_GPIO_I, LSEC pin 31 */ - "GPIO-A", /* LS_EXP_GPIO_A, LSEC pin 23 */ - "FORCED_USB_BOOT", - "SD_CARD_DET_N", - "[WCSS_BT_SSBI]", - "[WCSS_WLAN_DATA_2]", /* GPIO 40 */ - "[WCSS_WLAN_DATA_1]", - "[WCSS_WLAN_DATA_0]", - "[WCSS_WLAN_SET]", - "[WCSS_WLAN_CLK]", - "[WCSS_FM_SSBI]", - "[WCSS_FM_SDI]", - "[WCSS_BT_DAT_CTL]", - "[WCSS_BT_DAT_STB]", - "NC", - "NC", /* GPIO 50 */ - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", /* GPIO 60 */ - "NC", - "NC", - "[CDC_PDM0_CLK]", - "[CDC_PDM0_SYNC]", - "[CDC_PDM0_TX0]", - "[CDC_PDM0_RX0]", - "[CDC_PDM0_RX1]", - "[CDC_PDM0_RX2]", - "GPIO-D", /* LS_EXP_GPIO_D, LSEC pin 26 */ - "NC", /* GPIO 70 */ - "NC", - "NC", - "NC", - "NC", /* GPIO 74 */ - "NC", - "NC", - "NC", - "NC", - "NC", - "BOOT_CONFIG_0", /* GPIO 80 */ - "BOOT_CONFIG_1", - "BOOT_CONFIG_2", - "BOOT_CONFIG_3", - "NC", - "NC", - "BOOT_CONFIG_5", - "NC", - "NC", - "NC", - "NC", /* GPIO 90 */ - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", /* GPIO 100 */ - "NC", - "NC", - "NC", - "SSBI_GPS", - "NC", - "NC", - "KEY_VOLP_N", - "NC", - "NC", - "[LS_EXP_MI2S_WS]", /* GPIO 110 */ - "NC", - "NC", - "[LS_EXP_MI2S_SCK]", - "[LS_EXP_MI2S_DATA0]", - "GPIO-E", /* LS_EXP_GPIO_E, LSEC pin 27 */ - "NC", - "[DSI2HDMI_MI2S_WS]", - "[DSI2HDMI_MI2S_SCK]", - "[DSI2HDMI_MI2S_DATA0]", - "USR_LED_2_CTRL", /* GPIO 120 */ - "SB_HS_ID"; - - msmgpio_leds: msmgpio-leds { - pins = "gpio21", "gpio120"; - function = "gpio"; - - output-low; - }; - - usb_id_default: usb-id-default { - pins = "gpio121"; - function = "gpio"; - - drive-strength = <8>; - input-enable; - bias-pull-up; - }; - - adv7533_int_active: adv533-int-active { - pins = "gpio31"; - function = "gpio"; - - drive-strength = <16>; - bias-disable; - }; - - adv7533_int_suspend: adv7533-int-suspend { - pins = "gpio31"; - function = "gpio"; - - drive-strength = <2>; - bias-disable; - }; - - adv7533_switch_active: adv7533-switch-active { - pins = "gpio32"; - function = "gpio"; - - drive-strength = <16>; - bias-disable; - }; - - adv7533_switch_suspend: adv7533-switch-suspend { - pins = "gpio32"; - function = "gpio"; - - drive-strength = <2>; - bias-disable; - }; - - msm_key_volp_n_default: msm-key-volp-n-default { - pins = "gpio107"; - function = "gpio"; - - drive-strength = <8>; - input-enable; - bias-pull-up; - }; -}; - -&pm8916_gpios { - gpio-line-names = - "USR_LED_3_CTRL", - "USR_LED_4_CTRL", - "USB_HUB_RESET_N_PM", - "USB_SW_SEL_PM"; - - usb_hub_reset_pm: usb-hub-reset-pm { - pins = "gpio3"; - function = PMIC_GPIO_FUNC_NORMAL; - - input-disable; - output-high; - }; - - usb_hub_reset_pm_device: usb-hub-reset-pm-device { - pins = "gpio3"; - function = PMIC_GPIO_FUNC_NORMAL; - - output-low; - }; - - usb_sw_sel_pm: usb-sw-sel-pm { - pins = "gpio4"; - function = PMIC_GPIO_FUNC_NORMAL; - - power-source = <PM8916_GPIO_VPH>; - input-disable; - output-high; - }; - - usb_sw_sel_pm_device: usb-sw-sel-pm-device { - pins = "gpio4"; - function = PMIC_GPIO_FUNC_NORMAL; - - power-source = <PM8916_GPIO_VPH>; - input-disable; - output-low; - }; - - pm8916_gpios_leds: pm8916-gpios-leds { - pins = "gpio1", "gpio2"; - function = PMIC_GPIO_FUNC_NORMAL; - - output-low; - }; -}; - -&pm8916_mpps { - gpio-line-names = - "VDD_PX_BIAS", - "WLAN_LED_CTRL", - "BT_LED_CTRL", - "GPIO-F"; /* LS_EXP_GPIO_F, LSEC pin 28 */ - - pinctrl-names = "default"; - pinctrl-0 = <&ls_exp_gpio_f>; - - ls_exp_gpio_f: pm8916-mpp4-state { - pins = "mpp4"; - function = "digital"; - - output-low; - power-source = <PM8916_MPP_L5>; // 1.8V - }; - - pm8916_mpps_leds: pm8916-mpps-state { - pins = "mpp2", "mpp3"; - function = "digital"; - - output-low; - }; -}; diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts index 757afa27424dd..d01a512634cfe 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts @@ -5,9 +5,1077 @@
/dts-v1/;
-#include "apq8096-db820c.dtsi" +#include "msm8996.dtsi" +#include "pm8994.dtsi" +#include "pmi8994.dtsi" +#include <dt-bindings/input/input.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +#include <dt-bindings/sound/qcom,q6afe.h> +#include <dt-bindings/sound/qcom,q6asm.h> + +/* + * GPIO name legend: proper name = the GPIO line is used as GPIO + * NC = not connected (pin out but not routed from the chip to + * anything the board) + * "[PER]" = pin is muxed for [peripheral] (not GPIO) + * LSEC = Low Speed External Connector + * P HSEC = Primary High Speed External Connector + * S HSEC = Secondary High Speed External Connector + * J14 = Camera Connector + * TP = Test Points + * + * Line names are taken from the schematic "DragonBoard 820c", + * drawing no: LM25-P2751-1 + * + * For the lines routed to the external connectors the + * lines are named after the 96Boards CE Specification 1.0, + * Appendix "Expansion Connector Signal Description". + * + * When the 96Board naming of a line and the schematic name of + * the same line are in conflict, the 96Board specification + * takes precedence, which means that the external UART on the + * LSEC is named UART0 while the schematic and SoC names this + * UART3. This is only for the informational lines i.e. "[FOO]", + * the GPIO named lines "GPIO-A" thru "GPIO-L" are the only + * ones actually used for GPIO. + */
/ { model = "Qualcomm Technologies, Inc. DB820c"; compatible = "arrow,apq8096-db820c", "qcom,apq8096-sbc", "qcom,apq8096"; + + aliases { + serial0 = &blsp2_uart2; + serial1 = &blsp2_uart3; + serial2 = &blsp1_uart2; + i2c0 = &blsp1_i2c3; + i2c1 = &blsp2_i2c1; + i2c2 = &blsp2_i2c1; + spi0 = &blsp1_spi1; + spi1 = &blsp2_spi6; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clocks { + compatible = "simple-bus"; + divclk4: divclk4 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "divclk4"; + + pinctrl-names = "default"; + pinctrl-0 = <&divclk4_pin_a>; + }; + + div1_mclk: divclk1 { + compatible = "gpio-gate-clock"; + pinctrl-0 = <&audio_mclk>; + pinctrl-names = "default"; + clocks = <&rpmcc RPM_SMD_DIV_CLK1>; + #clock-cells = <0>; + enable-gpios = <&pm8994_gpios 15 0>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; + + pinctrl-names = "default"; + pinctrl-0 = <&volume_up_gpio>; + + button@0 { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&pm8994_gpios 2 GPIO_ACTIVE_LOW>; + }; + }; + + usb2_id: usb2-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&pmi8994_gpios 6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb2_vbus_det_gpio>; + }; + + usb3_id: usb3-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&pm8994_gpios 22 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb3_vbus_det_gpio>; + }; + + vph_pwr: vph-pwr-regulator { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-always-on; + regulator-boot-on; + + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + }; + + wlan_en: wlan-en-1-8v { + pinctrl-names = "default"; + pinctrl-0 = <&wlan_en_gpios>; + compatible = "regulator-fixed"; + regulator-name = "wlan-en-regulator"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&pm8994_gpios 8 0>; + + /* WLAN card specific delay */ + startup-delay-us = <70000>; + enable-active-high; + }; +}; + +&blsp1_i2c3 { + /* On Low speed expansion */ + label = "LS-I2C0"; + status = "okay"; +}; + +&blsp1_spi1 { + /* On Low speed expansion */ + label = "LS-SPI0"; + status = "okay"; +}; + +&blsp1_uart2 { + label = "BT-UART"; + status = "okay"; + + bluetooth { + compatible = "qcom,qca6174-bt"; + + /* bt_disable_n gpio */ + enable-gpios = <&pm8994_gpios 19 GPIO_ACTIVE_HIGH>; + + clocks = <&divclk4>; + }; +}; + +&adsp_pil { + status = "okay"; +}; + +&blsp2_i2c1 { + /* On High speed expansion */ + label = "HS-I2C2"; + status = "okay"; +}; + +&blsp2_i2c1 { + /* On Low speed expansion */ + label = "LS-I2C1"; + status = "okay"; +}; + +&blsp2_spi6 { + /* On High speed expansion */ + label = "HS-SPI1"; + status = "okay"; +}; + +&blsp2_uart2 { + label = "LS-UART1"; + status = "okay"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&blsp2_uart2_2pins_default>; + pinctrl-1 = <&blsp2_uart2_2pins_sleep>; +}; + +&blsp2_uart3 { + label = "LS-UART0"; + status = "disabled"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&blsp2_uart3_4pins_default>; + pinctrl-1 = <&blsp2_uart3_4pins_sleep>; +}; + +&camss { + vdda-supply = <&vreg_l2a_1p25>; +}; + +&gpu { + status = "okay"; +}; + +&hdmi { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hdmi_hpd_active &hdmi_ddc_active>; + pinctrl-1 = <&hdmi_hpd_suspend &hdmi_ddc_suspend>; + + core-vdda-supply = <&vreg_l12a_1p8>; + core-vcc-supply = <&vreg_s4a_1p8>; +}; + +&hdmi_phy { + status = "okay"; + + vddio-supply = <&vreg_l12a_1p8>; + vcca-supply = <&vreg_l28a_0p925>; + #phy-cells = <0>; +}; + +&hsusb_phy1 { + status = "okay"; + + vdda-pll-supply = <&vreg_l12a_1p8>; + vdda-phy-dpdm-supply = <&vreg_l24a_3p075>; +}; + +&hsusb_phy2 { + status = "okay"; + + vdda-pll-supply = <&vreg_l12a_1p8>; + vdda-phy-dpdm-supply = <&vreg_l24a_3p075>; +}; + +&mdp { + status = "okay"; +}; + +&mdss { + status = "okay"; +}; + +&mmcc { + vdd-gfx-supply = <&vdd_gfx>; +}; + +&pm8994_resin { + status = "okay"; + linux,code = <KEY_VOLUMEDOWN>; +}; + +&tlmm { + gpio-line-names = + "[SPI0_DOUT]", /* GPIO_0, BLSP1_SPI_MOSI, LSEC pin 14 */ + "[SPI0_DIN]", /* GPIO_1, BLSP1_SPI_MISO, LSEC pin 10 */ + "[SPI0_CS]", /* GPIO_2, BLSP1_SPI_CS_N, LSEC pin 12 */ + "[SPI0_SCLK]", /* GPIO_3, BLSP1_SPI_CLK, LSEC pin 8 */ + "[UART1_TxD]", /* GPIO_4, BLSP8_UART_TX, LSEC pin 11 */ + "[UART1_RxD]", /* GPIO_5, BLSP8_UART_RX, LSEC pin 13 */ + "[I2C1_SDA]", /* GPIO_6, BLSP8_I2C_SDA, LSEC pin 21 */ + "[I2C1_SCL]", /* GPIO_7, BLSP8_I2C_SCL, LSEC pin 19 */ + "GPIO-H", /* GPIO_8, LCD0_RESET_N, LSEC pin 30 */ + "TP93", /* GPIO_9 */ + "GPIO-G", /* GPIO_10, MDP_VSYNC_P, LSEC pin 29 */ + "[MDP_VSYNC_S]", /* GPIO_11, S HSEC pin 55 */ + "NC", /* GPIO_12 */ + "[CSI0_MCLK]", /* GPIO_13, CAM_MCLK0, P HSEC pin 15 */ + "[CAM_MCLK1]", /* GPIO_14, J14 pin 11 */ + "[CSI1_MCLK]", /* GPIO_15, CAM_MCLK2, P HSEC pin 17 */ + "TP99", /* GPIO_16 */ + "[I2C2_SDA]", /* GPIO_17, CCI_I2C_SDA0, P HSEC pin 34 */ + "[I2C2_SCL]", /* GPIO_18, CCI_I2C_SCL0, P HSEC pin 32 */ + "[CCI_I2C_SDA1]", /* GPIO_19, S HSEC pin 38 */ + "[CCI_I2C_SCL1]", /* GPIO_20, S HSEC pin 36 */ + "FLASH_STROBE_EN", /* GPIO_21, S HSEC pin 5 */ + "FLASH_STROBE_TRIG", /* GPIO_22, S HSEC pin 1 */ + "GPIO-K", /* GPIO_23, CAM2_RST_N, LSEC pin 33 */ + "GPIO-D", /* GPIO_24, LSEC pin 26 */ + "GPIO-I", /* GPIO_25, CAM0_RST_N, LSEC pin 31 */ + "GPIO-J", /* GPIO_26, CAM0_STANDBY_N, LSEC pin 32 */ + "BLSP6_I2C_SDA", /* GPIO_27 */ + "BLSP6_I2C_SCL", /* GPIO_28 */ + "GPIO-B", /* GPIO_29, TS0_RESET_N, LSEC pin 24 */ + "GPIO30", /* GPIO_30, S HSEC pin 4 */ + "HDMI_CEC", /* GPIO_31 */ + "HDMI_DDC_CLOCK", /* GPIO_32 */ + "HDMI_DDC_DATA", /* GPIO_33 */ + "HDMI_HOT_PLUG_DETECT", /* GPIO_34 */ + "PCIE0_RST_N", /* GPIO_35 */ + "PCIE0_CLKREQ_N", /* GPIO_36 */ + "PCIE0_WAKE", /* GPIO_37 */ + "SD_CARD_DET_N", /* GPIO_38 */ + "TSIF1_SYNC", /* GPIO_39, S HSEC pin 48 */ + "W_DISABLE_N", /* GPIO_40 */ + "[BLSP9_UART_TX]", /* GPIO_41 */ + "[BLSP9_UART_RX]", /* GPIO_42 */ + "[BLSP2_UART_CTS_N]", /* GPIO_43 */ + "[BLSP2_UART_RFR_N]", /* GPIO_44 */ + "[BLSP3_UART_TX]", /* GPIO_45 */ + "[BLSP3_UART_RX]", /* GPIO_46 */ + "[I2C0_SDA]", /* GPIO_47, LS_I2C0_SDA, LSEC pin 17 */ + "[I2C0_SCL]", /* GPIO_48, LS_I2C0_SCL, LSEC pin 15 */ + "[UART0_TxD]", /* GPIO_49, BLSP9_UART_TX, LSEC pin 5 */ + "[UART0_RxD]", /* GPIO_50, BLSP9_UART_RX, LSEC pin 7 */ + "[UART0_CTS]", /* GPIO_51, BLSP9_UART_CTS_N, LSEC pin 3 */ + "[UART0_RTS]", /* GPIO_52, BLSP9_UART_RFR_N, LSEC pin 9 */ + "[CODEC_INT1_N]", /* GPIO_53 */ + "[CODEC_INT2_N]", /* GPIO_54 */ + "[BLSP7_I2C_SDA]", /* GPIO_55 */ + "[BLSP7_I2C_SCL]", /* GPIO_56 */ + "MI2S_MCLK", /* GPIO_57, S HSEC pin 3 */ + "[PCM_CLK]", /* GPIO_58, QUA_MI2S_SCK, LSEC pin 18 */ + "[PCM_FS]", /* GPIO_59, QUA_MI2S_WS, LSEC pin 16 */ + "[PCM_DO]", /* GPIO_60, QUA_MI2S_DATA0, LSEC pin 20 */ + "[PCM_DI]", /* GPIO_61, QUA_MI2S_DATA1, LSEC pin 22 */ + "GPIO-E", /* GPIO_62, LSEC pin 27 */ + "TP87", /* GPIO_63 */ + "[CODEC_RST_N]", /* GPIO_64 */ + "[PCM1_CLK]", /* GPIO_65 */ + "[PCM1_SYNC]", /* GPIO_66 */ + "[PCM1_DIN]", /* GPIO_67 */ + "[PCM1_DOUT]", /* GPIO_68 */ + "AUDIO_REF_CLK", /* GPIO_69 */ + "SLIMBUS_CLK", /* GPIO_70 */ + "SLIMBUS_DATA0", /* GPIO_71 */ + "SLIMBUS_DATA1", /* GPIO_72 */ + "NC", /* GPIO_73 */ + "NC", /* GPIO_74 */ + "NC", /* GPIO_75 */ + "NC", /* GPIO_76 */ + "TP94", /* GPIO_77 */ + "NC", /* GPIO_78 */ + "TP95", /* GPIO_79 */ + "GPIO-A", /* GPIO_80, MEMS_RESET_N, LSEC pin 23 */ + "TP88", /* GPIO_81 */ + "TP89", /* GPIO_82 */ + "TP90", /* GPIO_83 */ + "TP91", /* GPIO_84 */ + "[SD_DAT0]", /* GPIO_85, BLSP12_SPI_MOSI, P HSEC pin 1 */ + "[SD_CMD]", /* GPIO_86, BLSP12_SPI_MISO, P HSEC pin 11 */ + "[SD_DAT3]", /* GPIO_87, BLSP12_SPI_CS_N, P HSEC pin 7 */ + "[SD_SCLK]", /* GPIO_88, BLSP12_SPI_CLK, P HSEC pin 9 */ + "TSIF1_CLK", /* GPIO_89, S HSEC pin 42 */ + "TSIF1_EN", /* GPIO_90, S HSEC pin 46 */ + "TSIF1_DATA", /* GPIO_91, S HSEC pin 44 */ + "NC", /* GPIO_92 */ + "TSIF2_CLK", /* GPIO_93, S HSEC pin 52 */ + "TSIF2_EN", /* GPIO_94, S HSEC pin 56 */ + "TSIF2_DATA", /* GPIO_95, S HSEC pin 54 */ + "TSIF2_SYNC", /* GPIO_96, S HSEC pin 58 */ + "NC", /* GPIO_97 */ + "CAM1_STANDBY_N", /* GPIO_98 */ + "NC", /* GPIO_99 */ + "NC", /* GPIO_100 */ + "[LCD1_RESET_N]", /* GPIO_101, S HSEC pin 51 */ + "BOOT_CONFIG1", /* GPIO_102 */ + "USB_HUB_RESET", /* GPIO_103 */ + "CAM1_RST_N", /* GPIO_104 */ + "NC", /* GPIO_105 */ + "NC", /* GPIO_106 */ + "NC", /* GPIO_107 */ + "NC", /* GPIO_108 */ + "NC", /* GPIO_109 */ + "NC", /* GPIO_110 */ + "NC", /* GPIO_111 */ + "NC", /* GPIO_112 */ + "PMI8994_BUA", /* GPIO_113 */ + "PCIE2_RST_N", /* GPIO_114 */ + "PCIE2_CLKREQ_N", /* GPIO_115 */ + "PCIE2_WAKE", /* GPIO_116 */ + "SSC_IRQ_0", /* GPIO_117 */ + "SSC_IRQ_1", /* GPIO_118 */ + "SSC_IRQ_2", /* GPIO_119 */ + "NC", /* GPIO_120 */ + "GPIO121", /* GPIO_121, S HSEC pin 2 */ + "NC", /* GPIO_122 */ + "SSC_IRQ_6", /* GPIO_123 */ + "SSC_IRQ_7", /* GPIO_124 */ + "GPIO-C", /* GPIO_125, TS_INT0, LSEC pin 25 */ + "BOOT_CONFIG5", /* GPIO_126 */ + "NC", /* GPIO_127 */ + "NC", /* GPIO_128 */ + "BOOT_CONFIG7", /* GPIO_129 */ + "PCIE1_RST_N", /* GPIO_130 */ + "PCIE1_CLKREQ_N", /* GPIO_131 */ + "PCIE1_WAKE", /* GPIO_132 */ + "GPIO-L", /* GPIO_133, CAM2_STANDBY_N, LSEC pin 34 */ + "NC", /* GPIO_134 */ + "NC", /* GPIO_135 */ + "BOOT_CONFIG8", /* GPIO_136 */ + "NC", /* GPIO_137 */ + "NC", /* GPIO_138 */ + "GPS_SSBI2", /* GPIO_139 */ + "GPS_SSBI1", /* GPIO_140 */ + "NC", /* GPIO_141 */ + "NC", /* GPIO_142 */ + "NC", /* GPIO_143 */ + "BOOT_CONFIG6", /* GPIO_144 */ + "NC", /* GPIO_145 */ + "NC", /* GPIO_146 */ + "NC", /* GPIO_147 */ + "NC", /* GPIO_148 */ + "NC"; /* GPIO_149 */ + + sdc2_cd_on: sdc2_cd_on { + mux { + pins = "gpio38"; + function = "gpio"; + }; + + config { + pins = "gpio38"; + bias-pull-up; /* pull up */ + drive-strength = <16>; /* 16 MA */ + }; + }; + + sdc2_cd_off: sdc2_cd_off { + mux { + pins = "gpio38"; + function = "gpio"; + }; + + config { + pins = "gpio38"; + bias-pull-up; /* pull up */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + hdmi_hpd_active: hdmi_hpd_active { + mux { + pins = "gpio34"; + function = "hdmi_hot"; + }; + + config { + pins = "gpio34"; + bias-pull-down; + drive-strength = <16>; + }; + }; + + hdmi_hpd_suspend: hdmi_hpd_suspend { + mux { + pins = "gpio34"; + function = "hdmi_hot"; + }; + + config { + pins = "gpio34"; + bias-pull-down; + drive-strength = <2>; + }; + }; + + hdmi_ddc_active: hdmi_ddc_active { + mux { + pins = "gpio32", "gpio33"; + function = "hdmi_ddc"; + }; + + config { + pins = "gpio32", "gpio33"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + hdmi_ddc_suspend: hdmi_ddc_suspend { + mux { + pins = "gpio32", "gpio33"; + function = "hdmi_ddc"; + }; + + config { + pins = "gpio32", "gpio33"; + drive-strength = <2>; + bias-pull-down; + }; + }; +}; + +&pcie0 { + status = "okay"; + perst-gpio = <&tlmm 35 GPIO_ACTIVE_LOW>; + vddpe-3v3-supply = <&wlan_en>; + vdda-supply = <&vreg_l28a_0p925>; +}; + +&pcie1 { + status = "okay"; + perst-gpio = <&tlmm 130 GPIO_ACTIVE_LOW>; + vdda-supply = <&vreg_l28a_0p925>; +}; + +&pcie2 { + status = "okay"; + perst-gpio = <&tlmm 114 GPIO_ACTIVE_LOW>; + vdda-supply = <&vreg_l28a_0p925>; +}; + +&pcie_phy { + status = "okay"; + + vdda-phy-supply = <&vreg_l28a_0p925>; + vdda-pll-supply = <&vreg_l12a_1p8>; +}; + +&pm8994_gpios { + gpio-line-names = + "NC", + "KEY_VOLP_N", + "NC", + "BL1_PWM", + "GPIO-F", /* BL0_PWM, LSEC pin 28 */ + "BL1_EN", + "NC", + "WLAN_EN", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "DIVCLK1", + "DIVCLK2", + "DIVCLK3", + "DIVCLK4", + "BT_EN", + "PMIC_SLB", + "PMIC_BUA", + "USB_VBUS_DET"; + + pinctrl-names = "default"; + pinctrl-0 = <&ls_exp_gpio_f &bt_en_gpios>; + + ls_exp_gpio_f: pm8994_gpio5 { + pinconf { + pins = "gpio5"; + output-low; + power-source = <2>; // PM8994_GPIO_S4, 1.8V + }; + }; + + bt_en_gpios: bt_en_gpios { + pinconf { + pins = "gpio19"; + function = PMIC_GPIO_FUNC_NORMAL; + output-low; + power-source = <PM8994_GPIO_S4>; // 1.8V + qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>; + bias-pull-down; + }; + }; + + wlan_en_gpios: wlan_en_gpios { + pinconf { + pins = "gpio8"; + function = PMIC_GPIO_FUNC_NORMAL; + output-low; + power-source = <PM8994_GPIO_S4>; // 1.8V + qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>; + bias-pull-down; + }; + }; + + audio_mclk: clk_div1 { + pinconf { + pins = "gpio15"; + function = "func1"; + power-source = <PM8994_GPIO_S4>; // 1.8V + }; + }; + + volume_up_gpio: pm8996_gpio2 { + pinconf { + pins = "gpio2"; + function = "normal"; + input-enable; + drive-push-pull; + bias-pull-up; + qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>; + power-source = <PM8994_GPIO_S4>; // 1.8V + }; + }; + + divclk4_pin_a: divclk4 { + pinconf { + pins = "gpio18"; + function = PMIC_GPIO_FUNC_FUNC2; + + bias-disable; + power-source = <PM8994_GPIO_S4>; + }; + }; + + usb3_vbus_det_gpio: pm8996_gpio22 { + pinconf { + pins = "gpio22"; + function = PMIC_GPIO_FUNC_NORMAL; + input-enable; + bias-pull-down; + qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>; + power-source = <PM8994_GPIO_S4>; // 1.8V + }; + }; +}; + +&pm8994_mpps { + gpio-line-names = + "VDDPX_BIAS", + "WIFI_LED", + "NC", + "BT_LED", + "PM_MPP05", + "PM_MPP06", + "PM_MPP07", + "NC"; +}; + +&pm8994_spmi_regulators { + qcom,saw-reg = <&saw3>; + s9 { + qcom,saw-slave; + }; + s10 { + qcom,saw-slave; + }; + s11 { + qcom,saw-leader; + regulator-always-on; + regulator-min-microvolt = <980000>; + regulator-max-microvolt = <980000>; + }; +}; + +&pmi8994_gpios { + gpio-line-names = + "NC", + "SPKR_AMP_EN1", + "SPKR_AMP_EN2", + "TP61", + "NC", + "USB2_VBUS_DET", + "NC", + "NC", + "NC", + "NC"; + + usb2_vbus_det_gpio: pmi8996_gpio6 { + pinconf { + pins = "gpio6"; + function = PMIC_GPIO_FUNC_NORMAL; + input-enable; + bias-pull-down; + qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>; + power-source = <PM8994_GPIO_S4>; // 1.8V + }; + }; +}; + +&pmi8994_spmi_regulators { + vdd_gfx: s2@1700 { + reg = <0x1700 0x100>; + regulator-name = "VDD_GFX"; + regulator-min-microvolt = <980000>; + regulator-max-microvolt = <980000>; + }; +}; + +&rpm_requests { + pm8994-regulators { + compatible = "qcom,rpm-pm8994-regulators"; + + vdd_s1-supply = <&vph_pwr>; + vdd_s2-supply = <&vph_pwr>; + vdd_s3-supply = <&vph_pwr>; + vdd_s4-supply = <&vph_pwr>; + vdd_s5-supply = <&vph_pwr>; + vdd_s6-supply = <&vph_pwr>; + vdd_s7-supply = <&vph_pwr>; + vdd_s8-supply = <&vph_pwr>; + vdd_s9-supply = <&vph_pwr>; + vdd_s10-supply = <&vph_pwr>; + vdd_s11-supply = <&vph_pwr>; + vdd_s12-supply = <&vph_pwr>; + vdd_l1-supply = <&vreg_s1b_1p025>; + vdd_l2_l26_l28-supply = <&vreg_s3a_1p3>; + vdd_l3_l11-supply = <&vreg_s3a_1p3>; + vdd_l4_l27_l31-supply = <&vreg_s3a_1p3>; + vdd_l5_l7-supply = <&vreg_s5a_2p15>; + vdd_l6_l12_l32-supply = <&vreg_s5a_2p15>; + vdd_l8_l16_l30-supply = <&vph_pwr>; + vdd_l9_l10_l18_l22-supply = <&vph_pwr_bbyp>; + vdd_l13_l19_l23_l24-supply = <&vph_pwr_bbyp>; + vdd_l14_l15-supply = <&vreg_s5a_2p15>; + vdd_l17_l29-supply = <&vph_pwr_bbyp>; + vdd_l20_l21-supply = <&vph_pwr_bbyp>; + vdd_l25-supply = <&vreg_s3a_1p3>; + vdd_lvs1_lvs2-supply = <&vreg_s4a_1p8>; + + vreg_s3a_1p3: s3 { + regulator-name = "vreg_s3a_1p3"; + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <1300000>; + }; + + /** + * 1.8v required on LS expansion + * for mezzanine boards + */ + vreg_s4a_1p8: s4 { + regulator-name = "vreg_s4a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + vreg_s5a_2p15: s5 { + regulator-name = "vreg_s5a_2p15"; + regulator-min-microvolt = <2150000>; + regulator-max-microvolt = <2150000>; + }; + vreg_s7a_1p0: s7 { + regulator-name = "vreg_s7a_1p0"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + }; + + vreg_l1a_1p0: l1 { + regulator-name = "vreg_l1a_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + vreg_l2a_1p25: l2 { + regulator-name = "vreg_l2a_1p25"; + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + }; + vreg_l3a_0p875: l3 { + regulator-name = "vreg_l3a_0p875"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + }; + vreg_l4a_1p225: l4 { + regulator-name = "vreg_l4a_1p225"; + regulator-min-microvolt = <1225000>; + regulator-max-microvolt = <1225000>; + }; + vreg_l6a_1p2: l6 { + regulator-name = "vreg_l6a_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + vreg_l8a_1p8: l8 { + regulator-name = "vreg_l8a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + vreg_l9a_1p8: l9 { + regulator-name = "vreg_l9a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + vreg_l10a_1p8: l10 { + regulator-name = "vreg_l10a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + vreg_l11a_1p15: l11 { + regulator-name = "vreg_l11a_1p15"; + regulator-min-microvolt = <1150000>; + regulator-max-microvolt = <1150000>; + }; + vreg_l12a_1p8: l12 { + regulator-name = "vreg_l12a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + vreg_l13a_2p95: l13 { + regulator-name = "vreg_l13a_2p95"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; + }; + vreg_l14a_1p8: l14 { + regulator-name = "vreg_l14a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + vreg_l15a_1p8: l15 { + regulator-name = "vreg_l15a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + vreg_l16a_2p7: l16 { + regulator-name = "vreg_l16a_2p7"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + }; + vreg_l17a_2p8: l17 { + regulator-name = "vreg_l17a_2p8"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + }; + vreg_l18a_2p85: l18 { + regulator-name = "vreg_l18a_2p85"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2900000>; + }; + vreg_l19a_2p8: l19 { + regulator-name = "vreg_l19a_2p8"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + vreg_l20a_2p95: l20 { + regulator-name = "vreg_l20a_2p95"; + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + regulator-allow-set-load; + }; + vreg_l21a_2p95: l21 { + regulator-name = "vreg_l21a_2p95"; + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + regulator-allow-set-load; + regulator-system-load = <200000>; + }; + vreg_l22a_3p0: l22 { + regulator-name = "vreg_l22a_3p0"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + vreg_l23a_2p8: l23 { + regulator-name = "vreg_l23a_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + vreg_l24a_3p075: l24 { + regulator-name = "vreg_l24a_3p075"; + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3075000>; + }; + vreg_l25a_1p2: l25 { + regulator-name = "vreg_l25a_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-allow-set-load; + }; + vreg_l26a_0p8: l27 { + regulator-name = "vreg_l26a_0p8"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + vreg_l28a_0p925: l28 { + regulator-name = "vreg_l28a_0p925"; + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <925000>; + regulator-allow-set-load; + }; + vreg_l29a_2p8: l29 { + regulator-name = "vreg_l29a_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + vreg_l30a_1p8: l30 { + regulator-name = "vreg_l30a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + vreg_l32a_1p8: l32 { + regulator-name = "vreg_l32a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + vreg_lvs1a_1p8: lvs1 { + regulator-name = "vreg_lvs1a_1p8"; + }; + + vreg_lvs2a_1p8: lvs2 { + regulator-name = "vreg_lvs2a_1p8"; + }; + }; + + pmi8994-regulators { + compatible = "qcom,rpm-pmi8994-regulators"; + + vdd_s1-supply = <&vph_pwr>; + vdd_s2-supply = <&vph_pwr>; + vdd_s3-supply = <&vph_pwr>; + vdd_bst_byp-supply = <&vph_pwr>; + + vph_pwr_bbyp: boost-bypass { + regulator-name = "vph_pwr_bbyp"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + vreg_s1b_1p025: s1 { + regulator-name = "vreg_s1b_1p025"; + regulator-min-microvolt = <1025000>; + regulator-max-microvolt = <1025000>; + }; + }; +}; + +&sdhc2 { + /* External SD card */ + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc2_state_on &sdc2_cd_on>; + pinctrl-1 = <&sdc2_state_off &sdc2_cd_off>; + cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; + vmmc-supply = <&vreg_l21a_2p95>; + vqmmc-supply = <&vreg_l13a_2p95>; + status = "okay"; +}; + +&q6asmdai { + dai@0 { + reg = <0>; + }; + + dai@1 { + reg = <1>; + }; + + dai@2 { + reg = <2>; + }; +}; + +&sound { + compatible = "qcom,apq8096-sndcard"; + model = "DB820c"; + audio-routing = "RX_BIAS", "MCLK", + "MM_DL1", "MultiMedia1 Playback", + "MM_DL2", "MultiMedia2 Playback", + "MultiMedia3 Capture", "MM_UL3"; + + mm1-dai-link { + link-name = "MultiMedia1"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>; + }; + }; + + mm2-dai-link { + link-name = "MultiMedia2"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>; + }; + }; + + mm3-dai-link { + link-name = "MultiMedia3"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>; + }; + }; + + hdmi-dai-link { + link-name = "HDMI"; + cpu { + sound-dai = <&q6afedai HDMI_RX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&hdmi 0>; + }; + }; + + slim-dai-link { + link-name = "SLIM Playback"; + cpu { + sound-dai = <&q6afedai SLIMBUS_6_RX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&wcd9335 6>; + }; + }; + + slimcap-dai-link { + link-name = "SLIM Capture"; + cpu { + sound-dai = <&q6afedai SLIMBUS_0_TX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&wcd9335 1>; + }; + }; +}; + +&ufsphy { + status = "okay"; + + vdda-phy-supply = <&vreg_l28a_0p925>; + vdda-pll-supply = <&vreg_l12a_1p8>; + vddp-ref-clk-supply = <&vreg_l25a_1p2>; +}; + +&ufshc { + status = "okay"; + + vcc-supply = <&vreg_l20a_2p95>; + vccq-supply = <&vreg_l25a_1p2>; + vccq2-supply = <&vreg_s4a_1p8>; + + vcc-max-microamp = <600000>; + vccq-max-microamp = <450000>; + vccq2-max-microamp = <450000>; +}; + +&usb2 { + status = "okay"; + extcon = <&usb2_id>; + + dwc3@7600000 { + extcon = <&usb2_id>; + dr_mode = "otg"; + maximum-speed = "high-speed"; + }; +}; + +&usb3 { + status = "okay"; + extcon = <&usb3_id>; + + dwc3@6a00000 { + extcon = <&usb3_id>; + dr_mode = "otg"; + }; +}; + +&usb3phy { + status = "okay"; + + vdda-phy-supply = <&vreg_l28a_0p925>; + vdda-pll-supply = <&vreg_l12a_1p8>; + +}; + +&venus { + status = "okay"; +}; + +&wcd9335 { + clock-names = "mclk", "slimbus"; + clocks = <&div1_mclk>, + <&rpmcc RPM_SMD_BB_CLK1>; + + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; + vdd-rx-supply = <&vreg_s4a_1p8>; + vdd-io-supply = <&vreg_s4a_1p8>; }; diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi deleted file mode 100644 index eca428ab2517a..0000000000000 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi +++ /dev/null @@ -1,1076 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. - */ - -#include "msm8996.dtsi" -#include "pm8994.dtsi" -#include "pmi8994.dtsi" -#include <dt-bindings/input/input.h> -#include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> -#include <dt-bindings/sound/qcom,q6afe.h> -#include <dt-bindings/sound/qcom,q6asm.h> - -/* - * GPIO name legend: proper name = the GPIO line is used as GPIO - * NC = not connected (pin out but not routed from the chip to - * anything the board) - * "[PER]" = pin is muxed for [peripheral] (not GPIO) - * LSEC = Low Speed External Connector - * P HSEC = Primary High Speed External Connector - * S HSEC = Secondary High Speed External Connector - * J14 = Camera Connector - * TP = Test Points - * - * Line names are taken from the schematic "DragonBoard 820c", - * drawing no: LM25-P2751-1 - * - * For the lines routed to the external connectors the - * lines are named after the 96Boards CE Specification 1.0, - * Appendix "Expansion Connector Signal Description". - * - * When the 96Board naming of a line and the schematic name of - * the same line are in conflict, the 96Board specification - * takes precedence, which means that the external UART on the - * LSEC is named UART0 while the schematic and SoC names this - * UART3. This is only for the informational lines i.e. "[FOO]", - * the GPIO named lines "GPIO-A" thru "GPIO-L" are the only - * ones actually used for GPIO. - */ - -/ { - aliases { - serial0 = &blsp2_uart2; - serial1 = &blsp2_uart3; - serial2 = &blsp1_uart2; - i2c0 = &blsp1_i2c3; - i2c1 = &blsp2_i2c1; - i2c2 = &blsp2_i2c1; - spi0 = &blsp1_spi1; - spi1 = &blsp2_spi6; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - clocks { - compatible = "simple-bus"; - divclk4: divclk4 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32768>; - clock-output-names = "divclk4"; - - pinctrl-names = "default"; - pinctrl-0 = <&divclk4_pin_a>; - }; - - div1_mclk: divclk1 { - compatible = "gpio-gate-clock"; - pinctrl-0 = <&audio_mclk>; - pinctrl-names = "default"; - clocks = <&rpmcc RPM_SMD_DIV_CLK1>; - #clock-cells = <0>; - enable-gpios = <&pm8994_gpios 15 0>; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - autorepeat; - - pinctrl-names = "default"; - pinctrl-0 = <&volume_up_gpio>; - - button@0 { - label = "Volume Up"; - linux,code = <KEY_VOLUMEUP>; - gpios = <&pm8994_gpios 2 GPIO_ACTIVE_LOW>; - }; - }; - - usb2_id: usb2-id { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&pmi8994_gpios 6 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&usb2_vbus_det_gpio>; - }; - - usb3_id: usb3-id { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&pm8994_gpios 22 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&usb3_vbus_det_gpio>; - }; - - vph_pwr: vph-pwr-regulator { - compatible = "regulator-fixed"; - regulator-name = "vph_pwr"; - regulator-always-on; - regulator-boot-on; - - regulator-min-microvolt = <3700000>; - regulator-max-microvolt = <3700000>; - }; - - wlan_en: wlan-en-1-8v { - pinctrl-names = "default"; - pinctrl-0 = <&wlan_en_gpios>; - compatible = "regulator-fixed"; - regulator-name = "wlan-en-regulator"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - - gpio = <&pm8994_gpios 8 0>; - - /* WLAN card specific delay */ - startup-delay-us = <70000>; - enable-active-high; - }; -}; - -&blsp1_i2c3 { - /* On Low speed expansion */ - label = "LS-I2C0"; - status = "okay"; -}; - -&blsp1_spi1 { - /* On Low speed expansion */ - label = "LS-SPI0"; - status = "okay"; -}; - -&blsp1_uart2 { - label = "BT-UART"; - status = "okay"; - - bluetooth { - compatible = "qcom,qca6174-bt"; - - /* bt_disable_n gpio */ - enable-gpios = <&pm8994_gpios 19 GPIO_ACTIVE_HIGH>; - - clocks = <&divclk4>; - }; -}; - -&adsp_pil { - status = "okay"; -}; - -&blsp2_i2c1 { - /* On High speed expansion */ - label = "HS-I2C2"; - status = "okay"; -}; - -&blsp2_i2c1 { - /* On Low speed expansion */ - label = "LS-I2C1"; - status = "okay"; -}; - -&blsp2_spi6 { - /* On High speed expansion */ - label = "HS-SPI1"; - status = "okay"; -}; - -&blsp2_uart2 { - label = "LS-UART1"; - status = "okay"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp2_uart2_2pins_default>; - pinctrl-1 = <&blsp2_uart2_2pins_sleep>; -}; - -&blsp2_uart3 { - label = "LS-UART0"; - status = "disabled"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp2_uart3_4pins_default>; - pinctrl-1 = <&blsp2_uart3_4pins_sleep>; -}; - -&camss { - vdda-supply = <&vreg_l2a_1p25>; -}; - -&gpu { - status = "okay"; -}; - -&hdmi { - status = "okay"; - - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&hdmi_hpd_active &hdmi_ddc_active>; - pinctrl-1 = <&hdmi_hpd_suspend &hdmi_ddc_suspend>; - - core-vdda-supply = <&vreg_l12a_1p8>; - core-vcc-supply = <&vreg_s4a_1p8>; -}; - -&hdmi_phy { - status = "okay"; - - vddio-supply = <&vreg_l12a_1p8>; - vcca-supply = <&vreg_l28a_0p925>; - #phy-cells = <0>; -}; - -&hsusb_phy1 { - status = "okay"; - - vdda-pll-supply = <&vreg_l12a_1p8>; - vdda-phy-dpdm-supply = <&vreg_l24a_3p075>; -}; - -&hsusb_phy2 { - status = "okay"; - - vdda-pll-supply = <&vreg_l12a_1p8>; - vdda-phy-dpdm-supply = <&vreg_l24a_3p075>; -}; - -&mdp { - status = "okay"; -}; - -&mdss { - status = "okay"; -}; - -&mmcc { - vdd-gfx-supply = <&vdd_gfx>; -}; - -&pm8994_resin { - status = "okay"; - linux,code = <KEY_VOLUMEDOWN>; -}; - -&tlmm { - gpio-line-names = - "[SPI0_DOUT]", /* GPIO_0, BLSP1_SPI_MOSI, LSEC pin 14 */ - "[SPI0_DIN]", /* GPIO_1, BLSP1_SPI_MISO, LSEC pin 10 */ - "[SPI0_CS]", /* GPIO_2, BLSP1_SPI_CS_N, LSEC pin 12 */ - "[SPI0_SCLK]", /* GPIO_3, BLSP1_SPI_CLK, LSEC pin 8 */ - "[UART1_TxD]", /* GPIO_4, BLSP8_UART_TX, LSEC pin 11 */ - "[UART1_RxD]", /* GPIO_5, BLSP8_UART_RX, LSEC pin 13 */ - "[I2C1_SDA]", /* GPIO_6, BLSP8_I2C_SDA, LSEC pin 21 */ - "[I2C1_SCL]", /* GPIO_7, BLSP8_I2C_SCL, LSEC pin 19 */ - "GPIO-H", /* GPIO_8, LCD0_RESET_N, LSEC pin 30 */ - "TP93", /* GPIO_9 */ - "GPIO-G", /* GPIO_10, MDP_VSYNC_P, LSEC pin 29 */ - "[MDP_VSYNC_S]", /* GPIO_11, S HSEC pin 55 */ - "NC", /* GPIO_12 */ - "[CSI0_MCLK]", /* GPIO_13, CAM_MCLK0, P HSEC pin 15 */ - "[CAM_MCLK1]", /* GPIO_14, J14 pin 11 */ - "[CSI1_MCLK]", /* GPIO_15, CAM_MCLK2, P HSEC pin 17 */ - "TP99", /* GPIO_16 */ - "[I2C2_SDA]", /* GPIO_17, CCI_I2C_SDA0, P HSEC pin 34 */ - "[I2C2_SCL]", /* GPIO_18, CCI_I2C_SCL0, P HSEC pin 32 */ - "[CCI_I2C_SDA1]", /* GPIO_19, S HSEC pin 38 */ - "[CCI_I2C_SCL1]", /* GPIO_20, S HSEC pin 36 */ - "FLASH_STROBE_EN", /* GPIO_21, S HSEC pin 5 */ - "FLASH_STROBE_TRIG", /* GPIO_22, S HSEC pin 1 */ - "GPIO-K", /* GPIO_23, CAM2_RST_N, LSEC pin 33 */ - "GPIO-D", /* GPIO_24, LSEC pin 26 */ - "GPIO-I", /* GPIO_25, CAM0_RST_N, LSEC pin 31 */ - "GPIO-J", /* GPIO_26, CAM0_STANDBY_N, LSEC pin 32 */ - "BLSP6_I2C_SDA", /* GPIO_27 */ - "BLSP6_I2C_SCL", /* GPIO_28 */ - "GPIO-B", /* GPIO_29, TS0_RESET_N, LSEC pin 24 */ - "GPIO30", /* GPIO_30, S HSEC pin 4 */ - "HDMI_CEC", /* GPIO_31 */ - "HDMI_DDC_CLOCK", /* GPIO_32 */ - "HDMI_DDC_DATA", /* GPIO_33 */ - "HDMI_HOT_PLUG_DETECT", /* GPIO_34 */ - "PCIE0_RST_N", /* GPIO_35 */ - "PCIE0_CLKREQ_N", /* GPIO_36 */ - "PCIE0_WAKE", /* GPIO_37 */ - "SD_CARD_DET_N", /* GPIO_38 */ - "TSIF1_SYNC", /* GPIO_39, S HSEC pin 48 */ - "W_DISABLE_N", /* GPIO_40 */ - "[BLSP9_UART_TX]", /* GPIO_41 */ - "[BLSP9_UART_RX]", /* GPIO_42 */ - "[BLSP2_UART_CTS_N]", /* GPIO_43 */ - "[BLSP2_UART_RFR_N]", /* GPIO_44 */ - "[BLSP3_UART_TX]", /* GPIO_45 */ - "[BLSP3_UART_RX]", /* GPIO_46 */ - "[I2C0_SDA]", /* GPIO_47, LS_I2C0_SDA, LSEC pin 17 */ - "[I2C0_SCL]", /* GPIO_48, LS_I2C0_SCL, LSEC pin 15 */ - "[UART0_TxD]", /* GPIO_49, BLSP9_UART_TX, LSEC pin 5 */ - "[UART0_RxD]", /* GPIO_50, BLSP9_UART_RX, LSEC pin 7 */ - "[UART0_CTS]", /* GPIO_51, BLSP9_UART_CTS_N, LSEC pin 3 */ - "[UART0_RTS]", /* GPIO_52, BLSP9_UART_RFR_N, LSEC pin 9 */ - "[CODEC_INT1_N]", /* GPIO_53 */ - "[CODEC_INT2_N]", /* GPIO_54 */ - "[BLSP7_I2C_SDA]", /* GPIO_55 */ - "[BLSP7_I2C_SCL]", /* GPIO_56 */ - "MI2S_MCLK", /* GPIO_57, S HSEC pin 3 */ - "[PCM_CLK]", /* GPIO_58, QUA_MI2S_SCK, LSEC pin 18 */ - "[PCM_FS]", /* GPIO_59, QUA_MI2S_WS, LSEC pin 16 */ - "[PCM_DO]", /* GPIO_60, QUA_MI2S_DATA0, LSEC pin 20 */ - "[PCM_DI]", /* GPIO_61, QUA_MI2S_DATA1, LSEC pin 22 */ - "GPIO-E", /* GPIO_62, LSEC pin 27 */ - "TP87", /* GPIO_63 */ - "[CODEC_RST_N]", /* GPIO_64 */ - "[PCM1_CLK]", /* GPIO_65 */ - "[PCM1_SYNC]", /* GPIO_66 */ - "[PCM1_DIN]", /* GPIO_67 */ - "[PCM1_DOUT]", /* GPIO_68 */ - "AUDIO_REF_CLK", /* GPIO_69 */ - "SLIMBUS_CLK", /* GPIO_70 */ - "SLIMBUS_DATA0", /* GPIO_71 */ - "SLIMBUS_DATA1", /* GPIO_72 */ - "NC", /* GPIO_73 */ - "NC", /* GPIO_74 */ - "NC", /* GPIO_75 */ - "NC", /* GPIO_76 */ - "TP94", /* GPIO_77 */ - "NC", /* GPIO_78 */ - "TP95", /* GPIO_79 */ - "GPIO-A", /* GPIO_80, MEMS_RESET_N, LSEC pin 23 */ - "TP88", /* GPIO_81 */ - "TP89", /* GPIO_82 */ - "TP90", /* GPIO_83 */ - "TP91", /* GPIO_84 */ - "[SD_DAT0]", /* GPIO_85, BLSP12_SPI_MOSI, P HSEC pin 1 */ - "[SD_CMD]", /* GPIO_86, BLSP12_SPI_MISO, P HSEC pin 11 */ - "[SD_DAT3]", /* GPIO_87, BLSP12_SPI_CS_N, P HSEC pin 7 */ - "[SD_SCLK]", /* GPIO_88, BLSP12_SPI_CLK, P HSEC pin 9 */ - "TSIF1_CLK", /* GPIO_89, S HSEC pin 42 */ - "TSIF1_EN", /* GPIO_90, S HSEC pin 46 */ - "TSIF1_DATA", /* GPIO_91, S HSEC pin 44 */ - "NC", /* GPIO_92 */ - "TSIF2_CLK", /* GPIO_93, S HSEC pin 52 */ - "TSIF2_EN", /* GPIO_94, S HSEC pin 56 */ - "TSIF2_DATA", /* GPIO_95, S HSEC pin 54 */ - "TSIF2_SYNC", /* GPIO_96, S HSEC pin 58 */ - "NC", /* GPIO_97 */ - "CAM1_STANDBY_N", /* GPIO_98 */ - "NC", /* GPIO_99 */ - "NC", /* GPIO_100 */ - "[LCD1_RESET_N]", /* GPIO_101, S HSEC pin 51 */ - "BOOT_CONFIG1", /* GPIO_102 */ - "USB_HUB_RESET", /* GPIO_103 */ - "CAM1_RST_N", /* GPIO_104 */ - "NC", /* GPIO_105 */ - "NC", /* GPIO_106 */ - "NC", /* GPIO_107 */ - "NC", /* GPIO_108 */ - "NC", /* GPIO_109 */ - "NC", /* GPIO_110 */ - "NC", /* GPIO_111 */ - "NC", /* GPIO_112 */ - "PMI8994_BUA", /* GPIO_113 */ - "PCIE2_RST_N", /* GPIO_114 */ - "PCIE2_CLKREQ_N", /* GPIO_115 */ - "PCIE2_WAKE", /* GPIO_116 */ - "SSC_IRQ_0", /* GPIO_117 */ - "SSC_IRQ_1", /* GPIO_118 */ - "SSC_IRQ_2", /* GPIO_119 */ - "NC", /* GPIO_120 */ - "GPIO121", /* GPIO_121, S HSEC pin 2 */ - "NC", /* GPIO_122 */ - "SSC_IRQ_6", /* GPIO_123 */ - "SSC_IRQ_7", /* GPIO_124 */ - "GPIO-C", /* GPIO_125, TS_INT0, LSEC pin 25 */ - "BOOT_CONFIG5", /* GPIO_126 */ - "NC", /* GPIO_127 */ - "NC", /* GPIO_128 */ - "BOOT_CONFIG7", /* GPIO_129 */ - "PCIE1_RST_N", /* GPIO_130 */ - "PCIE1_CLKREQ_N", /* GPIO_131 */ - "PCIE1_WAKE", /* GPIO_132 */ - "GPIO-L", /* GPIO_133, CAM2_STANDBY_N, LSEC pin 34 */ - "NC", /* GPIO_134 */ - "NC", /* GPIO_135 */ - "BOOT_CONFIG8", /* GPIO_136 */ - "NC", /* GPIO_137 */ - "NC", /* GPIO_138 */ - "GPS_SSBI2", /* GPIO_139 */ - "GPS_SSBI1", /* GPIO_140 */ - "NC", /* GPIO_141 */ - "NC", /* GPIO_142 */ - "NC", /* GPIO_143 */ - "BOOT_CONFIG6", /* GPIO_144 */ - "NC", /* GPIO_145 */ - "NC", /* GPIO_146 */ - "NC", /* GPIO_147 */ - "NC", /* GPIO_148 */ - "NC"; /* GPIO_149 */ - - sdc2_cd_on: sdc2_cd_on { - mux { - pins = "gpio38"; - function = "gpio"; - }; - - config { - pins = "gpio38"; - bias-pull-up; /* pull up */ - drive-strength = <16>; /* 16 MA */ - }; - }; - - sdc2_cd_off: sdc2_cd_off { - mux { - pins = "gpio38"; - function = "gpio"; - }; - - config { - pins = "gpio38"; - bias-pull-up; /* pull up */ - drive-strength = <2>; /* 2 MA */ - }; - }; - - hdmi_hpd_active: hdmi_hpd_active { - mux { - pins = "gpio34"; - function = "hdmi_hot"; - }; - - config { - pins = "gpio34"; - bias-pull-down; - drive-strength = <16>; - }; - }; - - hdmi_hpd_suspend: hdmi_hpd_suspend { - mux { - pins = "gpio34"; - function = "hdmi_hot"; - }; - - config { - pins = "gpio34"; - bias-pull-down; - drive-strength = <2>; - }; - }; - - hdmi_ddc_active: hdmi_ddc_active { - mux { - pins = "gpio32", "gpio33"; - function = "hdmi_ddc"; - }; - - config { - pins = "gpio32", "gpio33"; - drive-strength = <2>; - bias-pull-up; - }; - }; - - hdmi_ddc_suspend: hdmi_ddc_suspend { - mux { - pins = "gpio32", "gpio33"; - function = "hdmi_ddc"; - }; - - config { - pins = "gpio32", "gpio33"; - drive-strength = <2>; - bias-pull-down; - }; - }; -}; - -&pcie0 { - status = "okay"; - perst-gpio = <&tlmm 35 GPIO_ACTIVE_LOW>; - vddpe-3v3-supply = <&wlan_en>; - vdda-supply = <&vreg_l28a_0p925>; -}; - -&pcie1 { - status = "okay"; - perst-gpio = <&tlmm 130 GPIO_ACTIVE_LOW>; - vdda-supply = <&vreg_l28a_0p925>; -}; - -&pcie2 { - status = "okay"; - perst-gpio = <&tlmm 114 GPIO_ACTIVE_LOW>; - vdda-supply = <&vreg_l28a_0p925>; -}; - -&pcie_phy { - status = "okay"; - - vdda-phy-supply = <&vreg_l28a_0p925>; - vdda-pll-supply = <&vreg_l12a_1p8>; -}; - -&pm8994_gpios { - gpio-line-names = - "NC", - "KEY_VOLP_N", - "NC", - "BL1_PWM", - "GPIO-F", /* BL0_PWM, LSEC pin 28 */ - "BL1_EN", - "NC", - "WLAN_EN", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "DIVCLK1", - "DIVCLK2", - "DIVCLK3", - "DIVCLK4", - "BT_EN", - "PMIC_SLB", - "PMIC_BUA", - "USB_VBUS_DET"; - - pinctrl-names = "default"; - pinctrl-0 = <&ls_exp_gpio_f &bt_en_gpios>; - - ls_exp_gpio_f: pm8994_gpio5 { - pinconf { - pins = "gpio5"; - output-low; - power-source = <2>; // PM8994_GPIO_S4, 1.8V - }; - }; - - bt_en_gpios: bt_en_gpios { - pinconf { - pins = "gpio19"; - function = PMIC_GPIO_FUNC_NORMAL; - output-low; - power-source = <PM8994_GPIO_S4>; // 1.8V - qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>; - bias-pull-down; - }; - }; - - wlan_en_gpios: wlan_en_gpios { - pinconf { - pins = "gpio8"; - function = PMIC_GPIO_FUNC_NORMAL; - output-low; - power-source = <PM8994_GPIO_S4>; // 1.8V - qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>; - bias-pull-down; - }; - }; - - audio_mclk: clk_div1 { - pinconf { - pins = "gpio15"; - function = "func1"; - power-source = <PM8994_GPIO_S4>; // 1.8V - }; - }; - - volume_up_gpio: pm8996_gpio2 { - pinconf { - pins = "gpio2"; - function = "normal"; - input-enable; - drive-push-pull; - bias-pull-up; - qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>; - power-source = <PM8994_GPIO_S4>; // 1.8V - }; - }; - - divclk4_pin_a: divclk4 { - pinconf { - pins = "gpio18"; - function = PMIC_GPIO_FUNC_FUNC2; - - bias-disable; - power-source = <PM8994_GPIO_S4>; - }; - }; - - usb3_vbus_det_gpio: pm8996_gpio22 { - pinconf { - pins = "gpio22"; - function = PMIC_GPIO_FUNC_NORMAL; - input-enable; - bias-pull-down; - qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>; - power-source = <PM8994_GPIO_S4>; // 1.8V - }; - }; -}; - -&pm8994_mpps { - gpio-line-names = - "VDDPX_BIAS", - "WIFI_LED", - "NC", - "BT_LED", - "PM_MPP05", - "PM_MPP06", - "PM_MPP07", - "NC"; -}; - -&pm8994_spmi_regulators { - qcom,saw-reg = <&saw3>; - s9 { - qcom,saw-slave; - }; - s10 { - qcom,saw-slave; - }; - s11 { - qcom,saw-leader; - regulator-always-on; - regulator-min-microvolt = <980000>; - regulator-max-microvolt = <980000>; - }; -}; - -&pmi8994_gpios { - gpio-line-names = - "NC", - "SPKR_AMP_EN1", - "SPKR_AMP_EN2", - "TP61", - "NC", - "USB2_VBUS_DET", - "NC", - "NC", - "NC", - "NC"; - - usb2_vbus_det_gpio: pmi8996_gpio6 { - pinconf { - pins = "gpio6"; - function = PMIC_GPIO_FUNC_NORMAL; - input-enable; - bias-pull-down; - qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>; - power-source = <PM8994_GPIO_S4>; // 1.8V - }; - }; -}; - -&pmi8994_spmi_regulators { - vdd_gfx: s2@1700 { - reg = <0x1700 0x100>; - regulator-name = "VDD_GFX"; - regulator-min-microvolt = <980000>; - regulator-max-microvolt = <980000>; - }; -}; - -&rpm_requests { - pm8994-regulators { - compatible = "qcom,rpm-pm8994-regulators"; - - vdd_s1-supply = <&vph_pwr>; - vdd_s2-supply = <&vph_pwr>; - vdd_s3-supply = <&vph_pwr>; - vdd_s4-supply = <&vph_pwr>; - vdd_s5-supply = <&vph_pwr>; - vdd_s6-supply = <&vph_pwr>; - vdd_s7-supply = <&vph_pwr>; - vdd_s8-supply = <&vph_pwr>; - vdd_s9-supply = <&vph_pwr>; - vdd_s10-supply = <&vph_pwr>; - vdd_s11-supply = <&vph_pwr>; - vdd_s12-supply = <&vph_pwr>; - vdd_l1-supply = <&vreg_s1b_1p025>; - vdd_l2_l26_l28-supply = <&vreg_s3a_1p3>; - vdd_l3_l11-supply = <&vreg_s3a_1p3>; - vdd_l4_l27_l31-supply = <&vreg_s3a_1p3>; - vdd_l5_l7-supply = <&vreg_s5a_2p15>; - vdd_l6_l12_l32-supply = <&vreg_s5a_2p15>; - vdd_l8_l16_l30-supply = <&vph_pwr>; - vdd_l9_l10_l18_l22-supply = <&vph_pwr_bbyp>; - vdd_l13_l19_l23_l24-supply = <&vph_pwr_bbyp>; - vdd_l14_l15-supply = <&vreg_s5a_2p15>; - vdd_l17_l29-supply = <&vph_pwr_bbyp>; - vdd_l20_l21-supply = <&vph_pwr_bbyp>; - vdd_l25-supply = <&vreg_s3a_1p3>; - vdd_lvs1_lvs2-supply = <&vreg_s4a_1p8>; - - vreg_s3a_1p3: s3 { - regulator-name = "vreg_s3a_1p3"; - regulator-min-microvolt = <1300000>; - regulator-max-microvolt = <1300000>; - }; - - /** - * 1.8v required on LS expansion - * for mezzanine boards - */ - vreg_s4a_1p8: s4 { - regulator-name = "vreg_s4a_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-always-on; - }; - vreg_s5a_2p15: s5 { - regulator-name = "vreg_s5a_2p15"; - regulator-min-microvolt = <2150000>; - regulator-max-microvolt = <2150000>; - }; - vreg_s7a_1p0: s7 { - regulator-name = "vreg_s7a_1p0"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <800000>; - }; - - vreg_l1a_1p0: l1 { - regulator-name = "vreg_l1a_1p0"; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1000000>; - }; - vreg_l2a_1p25: l2 { - regulator-name = "vreg_l2a_1p25"; - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <1250000>; - }; - vreg_l3a_0p875: l3 { - regulator-name = "vreg_l3a_0p875"; - regulator-min-microvolt = <850000>; - regulator-max-microvolt = <850000>; - }; - vreg_l4a_1p225: l4 { - regulator-name = "vreg_l4a_1p225"; - regulator-min-microvolt = <1225000>; - regulator-max-microvolt = <1225000>; - }; - vreg_l6a_1p2: l6 { - regulator-name = "vreg_l6a_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - }; - vreg_l8a_1p8: l8 { - regulator-name = "vreg_l8a_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - vreg_l9a_1p8: l9 { - regulator-name = "vreg_l9a_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - vreg_l10a_1p8: l10 { - regulator-name = "vreg_l10a_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - vreg_l11a_1p15: l11 { - regulator-name = "vreg_l11a_1p15"; - regulator-min-microvolt = <1150000>; - regulator-max-microvolt = <1150000>; - }; - vreg_l12a_1p8: l12 { - regulator-name = "vreg_l12a_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - vreg_l13a_2p95: l13 { - regulator-name = "vreg_l13a_2p95"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <2950000>; - }; - vreg_l14a_1p8: l14 { - regulator-name = "vreg_l14a_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - vreg_l15a_1p8: l15 { - regulator-name = "vreg_l15a_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - vreg_l16a_2p7: l16 { - regulator-name = "vreg_l16a_2p7"; - regulator-min-microvolt = <2700000>; - regulator-max-microvolt = <2700000>; - }; - vreg_l17a_2p8: l17 { - regulator-name = "vreg_l17a_2p8"; - regulator-min-microvolt = <2500000>; - regulator-max-microvolt = <2500000>; - }; - vreg_l18a_2p85: l18 { - regulator-name = "vreg_l18a_2p85"; - regulator-min-microvolt = <2700000>; - regulator-max-microvolt = <2900000>; - }; - vreg_l19a_2p8: l19 { - regulator-name = "vreg_l19a_2p8"; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - }; - vreg_l20a_2p95: l20 { - regulator-name = "vreg_l20a_2p95"; - regulator-min-microvolt = <2950000>; - regulator-max-microvolt = <2950000>; - regulator-allow-set-load; - }; - vreg_l21a_2p95: l21 { - regulator-name = "vreg_l21a_2p95"; - regulator-min-microvolt = <2950000>; - regulator-max-microvolt = <2950000>; - regulator-allow-set-load; - regulator-system-load = <200000>; - }; - vreg_l22a_3p0: l22 { - regulator-name = "vreg_l22a_3p0"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - vreg_l23a_2p8: l23 { - regulator-name = "vreg_l23a_2p8"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - }; - vreg_l24a_3p075: l24 { - regulator-name = "vreg_l24a_3p075"; - regulator-min-microvolt = <3075000>; - regulator-max-microvolt = <3075000>; - }; - vreg_l25a_1p2: l25 { - regulator-name = "vreg_l25a_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-allow-set-load; - }; - vreg_l26a_0p8: l27 { - regulator-name = "vreg_l26a_0p8"; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1000000>; - }; - vreg_l28a_0p925: l28 { - regulator-name = "vreg_l28a_0p925"; - regulator-min-microvolt = <925000>; - regulator-max-microvolt = <925000>; - regulator-allow-set-load; - }; - vreg_l29a_2p8: l29 { - regulator-name = "vreg_l29a_2p8"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - }; - vreg_l30a_1p8: l30 { - regulator-name = "vreg_l30a_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - vreg_l32a_1p8: l32 { - regulator-name = "vreg_l32a_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - - vreg_lvs1a_1p8: lvs1 { - regulator-name = "vreg_lvs1a_1p8"; - }; - - vreg_lvs2a_1p8: lvs2 { - regulator-name = "vreg_lvs2a_1p8"; - }; - }; - - pmi8994-regulators { - compatible = "qcom,rpm-pmi8994-regulators"; - - vdd_s1-supply = <&vph_pwr>; - vdd_s2-supply = <&vph_pwr>; - vdd_s3-supply = <&vph_pwr>; - vdd_bst_byp-supply = <&vph_pwr>; - - vph_pwr_bbyp: boost-bypass { - regulator-name = "vph_pwr_bbyp"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - vreg_s1b_1p025: s1 { - regulator-name = "vreg_s1b_1p025"; - regulator-min-microvolt = <1025000>; - regulator-max-microvolt = <1025000>; - }; - }; -}; - -&sdhc2 { - /* External SD card */ - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc2_state_on &sdc2_cd_on>; - pinctrl-1 = <&sdc2_state_off &sdc2_cd_off>; - cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; - vmmc-supply = <&vreg_l21a_2p95>; - vqmmc-supply = <&vreg_l13a_2p95>; - status = "okay"; -}; - -&q6asmdai { - dai@0 { - reg = <0>; - }; - - dai@1 { - reg = <1>; - }; - - dai@2 { - reg = <2>; - }; -}; - -&sound { - compatible = "qcom,apq8096-sndcard"; - model = "DB820c"; - audio-routing = "RX_BIAS", "MCLK", - "MM_DL1", "MultiMedia1 Playback", - "MM_DL2", "MultiMedia2 Playback", - "MultiMedia3 Capture", "MM_UL3"; - - mm1-dai-link { - link-name = "MultiMedia1"; - cpu { - sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>; - }; - }; - - mm2-dai-link { - link-name = "MultiMedia2"; - cpu { - sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>; - }; - }; - - mm3-dai-link { - link-name = "MultiMedia3"; - cpu { - sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>; - }; - }; - - hdmi-dai-link { - link-name = "HDMI"; - cpu { - sound-dai = <&q6afedai HDMI_RX>; - }; - - platform { - sound-dai = <&q6routing>; - }; - - codec { - sound-dai = <&hdmi 0>; - }; - }; - - slim-dai-link { - link-name = "SLIM Playback"; - cpu { - sound-dai = <&q6afedai SLIMBUS_6_RX>; - }; - - platform { - sound-dai = <&q6routing>; - }; - - codec { - sound-dai = <&wcd9335 6>; - }; - }; - - slimcap-dai-link { - link-name = "SLIM Capture"; - cpu { - sound-dai = <&q6afedai SLIMBUS_0_TX>; - }; - - platform { - sound-dai = <&q6routing>; - }; - - codec { - sound-dai = <&wcd9335 1>; - }; - }; -}; - -&ufsphy { - status = "okay"; - - vdda-phy-supply = <&vreg_l28a_0p925>; - vdda-pll-supply = <&vreg_l12a_1p8>; - vddp-ref-clk-supply = <&vreg_l25a_1p2>; -}; - -&ufshc { - status = "okay"; - - vcc-supply = <&vreg_l20a_2p95>; - vccq-supply = <&vreg_l25a_1p2>; - vccq2-supply = <&vreg_s4a_1p8>; - - vcc-max-microamp = <600000>; - vccq-max-microamp = <450000>; - vccq2-max-microamp = <450000>; -}; - -&usb2 { - status = "okay"; - extcon = <&usb2_id>; - - dwc3@7600000 { - extcon = <&usb2_id>; - dr_mode = "otg"; - maximum-speed = "high-speed"; - }; -}; - -&usb3 { - status = "okay"; - extcon = <&usb3_id>; - - dwc3@6a00000 { - extcon = <&usb3_id>; - dr_mode = "otg"; - }; -}; - -&usb3phy { - status = "okay"; - - vdda-phy-supply = <&vreg_l28a_0p925>; - vdda-pll-supply = <&vreg_l12a_1p8>; - -}; - -&venus { - status = "okay"; -}; - -&wcd9335 { - clock-names = "mclk", "slimbus"; - clocks = <&div1_mclk>, - <&rpmcc RPM_SMD_BB_CLK1>; - - vdd-buck-supply = <&vreg_s4a_1p8>; - vdd-buck-sido-supply = <&vreg_s4a_1p8>; - vdd-tx-supply = <&vreg_s4a_1p8>; - vdd-rx-supply = <&vreg_s4a_1p8>; - vdd-io-supply = <&vreg_s4a_1p8>; -}; diff --git a/arch/arm64/boot/dts/qcom/msm8916-mtp.dts b/arch/arm64/boot/dts/qcom/msm8916-mtp.dts index d66c155387850..7c0ceb3cff45e 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-mtp.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-mtp.dts @@ -5,9 +5,22 @@
/dts-v1/;
-#include "msm8916-mtp.dtsi" +#include "msm8916-pm8916.dtsi"
/ { model = "Qualcomm Technologies, Inc. MSM 8916 MTP"; compatible = "qcom,msm8916-mtp", "qcom,msm8916-mtp/1", "qcom,msm8916"; + + aliases { + serial0 = &blsp1_uart2; + usid0 = &pm8916_0; + }; + + chosen { + stdout-path = "serial0"; + }; +}; + +&blsp1_uart2 { + status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi deleted file mode 100644 index 1bd05046cdeba..0000000000000 --- a/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. - */ - -#include "msm8916-pm8916.dtsi" - -/ { - aliases { - serial0 = &blsp1_uart2; - usid0 = &pm8916_0; - }; - - chosen { - stdout-path = "serial0"; - }; -}; - -&blsp1_uart2 { - status = "okay"; -}; diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dts b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts index 45ed594c1b9c2..7d9fc35bc7a06 100644 --- a/arch/arm64/boot/dts/qcom/msm8996-mtp.dts +++ b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts @@ -5,9 +5,31 @@
/dts-v1/;
-#include "msm8996-mtp.dtsi" +#include "msm8996.dtsi"
/ { model = "Qualcomm Technologies, Inc. MSM 8996 MTP"; compatible = "qcom,msm8996-mtp"; + + aliases { + serial0 = &blsp2_uart2; + }; + + chosen { + stdout-path = "serial0"; + }; + + soc { + serial@75b0000 { + status = "okay"; + }; + }; +}; + +&hdmi { + status = "okay"; +}; + +&hdmi_phy { + status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi deleted file mode 100644 index ac43a91f11048..0000000000000 --- a/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. - */ - -#include "msm8996.dtsi" - -/ { - aliases { - serial0 = &blsp2_uart2; - }; - - chosen { - stdout-path = "serial0"; - }; - - soc { - serial@75b0000 { - status = "okay"; - }; - }; -}; - -&hdmi { - status = "okay"; -}; - -&hdmi_phy { - status = "okay"; -};
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit e27654df20d77ad7549a3cf6739ebaa3aa59a088 ]
For some reason DB410c has completely bogus regulator constraints that actually just correspond to the programmable voltages which are already provided by the regulator driver. Some of them are not just outside the recommended operating conditions of the APQ8016E SoC but even exceed the absolute maximum ratings, potentially risking permanent device damage.
In practice it's not quite as dangerous thanks to the RPM firmware: It turns out that it has its own voltage constraints and silently clamps all regulator requests. For example, requesting 3.3V for L5 (allowed by the current regulator constraints!) still results in 1.8V being programmed in the actual regulator hardware.
Experimentation with various voltages shows that the internal RPM voltage constraints roughly correspond to the safe "specified range" in the PM8916 Device Specification (rather than the "programmable range" used inside apq8016-sbc.dtsi right now).
Combine those together with some fixed voltages used in the old msm-3.10 device tree from Qualcomm to give DB410c some actually valid voltage constraints.
Cc: Srinivas Kandagatla srinivas.kandagatla@linaro.org Fixes: 4c7d53d16d77 ("arm64: dts: apq8016-sbc: add regulators support") Signed-off-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230510-msm8916-regulators-v1-1-54d4960a05fc@gerh... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 64 ++++++++++++------------ 1 file changed, 32 insertions(+), 32 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts index a5320d6d30e7b..528138af24f09 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts @@ -440,21 +440,21 @@ &smd_rpm_regulators { vdd_l7-supply = <&pm8916_s4>;
s3 { - regulator-min-microvolt = <375000>; - regulator-max-microvolt = <1562000>; + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1350000>; };
s4 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1850000>; + regulator-max-microvolt = <2150000>;
regulator-always-on; regulator-boot-on; };
l1 { - regulator-min-microvolt = <375000>; - regulator-max-microvolt = <1525000>; + regulator-min-microvolt = <1225000>; + regulator-max-microvolt = <1225000>; };
l2 { @@ -463,13 +463,13 @@ l2 { };
l4 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <2050000>; + regulator-max-microvolt = <2050000>; };
l5 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; };
l6 { @@ -478,45 +478,45 @@ l6 { };
l7 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; };
l8 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; };
l9 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; };
l10 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; };
l11 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; regulator-allow-set-load; regulator-system-load = <200000>; };
l12 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; };
l13 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3075000>; };
l14 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; };
/** @@ -524,14 +524,14 @@ l14 { * for mezzanine boards */ l15 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; regulator-always-on; };
l16 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; };
l17 { @@ -540,8 +540,8 @@ l17 { };
l18 { - regulator-min-microvolt = <1750000>; - regulator-max-microvolt = <3337000>; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; }; };
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit 5500f823db38db073d30557af159b77fb1f2bf26 ]
The 96Boards specification expects a 1.8V power rail on the low-speed expansion connector that is able to provide at least 0.18W / 100 mA. According to the DB410c hardware user manual this is done by connecting both L15 and L16 in parallel with up to 55mA each (for 110 mA total) [1].
Unfortunately the current regulator setup in the DB410c device tree does not implement the specification correctly and only provides 5 mA:
- Only L15 is marked always-on, so L16 is never enabled. - Without specifying a load the regulator is put into LPM where it can only provide 5 mA.
Fix this by:
- Adding proper voltage constraints for L16. - Making L16 always-on. - Adding regulator-system-load for both L15 and L16. 100 mA should be available in total, so specify 50 mA for each. (The regulator hardware can only be in normal (55 mA) or low-power mode (5 mA) so this will actually result in the expected 110 mA total...)
[1]: https://www.96boards.org/documentation/consumer/dragonboard/dragonboard410c/...
Cc: Srinivas Kandagatla srinivas.kandagatla@linaro.org Fixes: 828dd5d66f0f ("arm64: dts: apq8016-sbc: make 1.8v available on LS expansion") Signed-off-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230510-msm8916-regulators-v1-2-54d4960a05fc@gerh... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts index 528138af24f09..c6e8bf18defc6 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts @@ -519,19 +519,27 @@ l14 { regulator-max-microvolt = <3300000>; };
- /** - * 1.8v required on LS expansion - * for mezzanine boards + /* + * The 96Boards specification expects a 1.8V power rail on the low-speed + * expansion connector that is able to provide at least 0.18W / 100 mA. + * L15/L16 are connected in parallel to provide 55 mA each. A minimum load + * must be specified to ensure the regulators are not put in LPM where they + * would only provide 5 mA. */ l15 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + regulator-system-load = <50000>; + regulator-allow-set-load; regulator-always-on; };
l16 { regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; + regulator-max-microvolt = <1800000>; + regulator-system-load = <50000>; + regulator-allow-set-load; + regulator-always-on; };
l17 {
From: Dario Binacchi dario.binacchi@amarulasolutions.com
[ Upstream commit f24b49550814fdee4a98b9552e35e243ccafd4a8 ]
The previous setting was related to the overall dimension and not to the active display area. In the "PHYSICAL SPECIFICATIONS" section, the datasheet shows the following parameters:
---------------------------------------------------------- | Item | Specifications | unit | ---------------------------------------------------------- | Display area | 98.7 (W) x 57.5 (H) | mm | ---------------------------------------------------------- | Overall dimension | 105.5(W) x 67.2(H) x 4.96(D) | mm | ----------------------------------------------------------
Fixes: 966fea78adf2 ("drm/panel: simple: Add support for Ampire AM-480272H3TMQW-T01H") Signed-off-by: Dario Binacchi dario.binacchi@amarulasolutions.com Reviewed-by: Neil Armstrong neil.armstrong@linaro.org [narmstrong: fixed Fixes commit id length] Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20230516085039.3797303-1-dario... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-simple.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index fb785f5a106ac..2f85266cdb2e3 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -890,8 +890,8 @@ static const struct panel_desc ampire_am_480272h3tmqw_t01h = { .num_modes = 1, .bpc = 8, .size = { - .width = 105, - .height = 67, + .width = 99, + .height = 58, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X24, };
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 419013740ea1e4343d8ade535d999f59fa28e460 ]
ep93xx_clocksource_read() is only called from the file it is declared in, while ep93xx_timer_init() is declared in a header that is not included here.
arch/arm/mach-ep93xx/timer-ep93xx.c:120:13: error: no previous prototype for 'ep93xx_timer_init' arch/arm/mach-ep93xx/timer-ep93xx.c:63:5: error: no previous prototype for 'ep93xx_clocksource_read'
Fixes: 000bc17817bf ("ARM: ep93xx: switch to GENERIC_CLOCKEVENTS") Acked-by: Alexander Sverdlin alexander.sverdlin@gmail.com Link: https://lore.kernel.org/r/20230516153109.514251-3-arnd@kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-ep93xx/timer-ep93xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c index dd4b164d18317..a9efa7bc2fa12 100644 --- a/arch/arm/mach-ep93xx/timer-ep93xx.c +++ b/arch/arm/mach-ep93xx/timer-ep93xx.c @@ -9,6 +9,7 @@ #include <linux/io.h> #include <asm/mach/time.h> #include "soc.h" +#include "platform.h"
/************************************************************************* * Timer handling for EP93xx @@ -60,7 +61,7 @@ static u64 notrace ep93xx_read_sched_clock(void) return ret; }
-u64 ep93xx_clocksource_read(struct clocksource *c) +static u64 ep93xx_clocksource_read(struct clocksource *c) { u64 ret;
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 861bc1d2886d47bd57a2cbf2cda87fdbe3eb9d08 ]
omap2 contains a hack to define tick_broadcast() on non-SMP configurations in place of the normal SMP definition. This one causes a warning because of a missing prototype:
arch/arm/mach-omap2/board-generic.c:44:6: error: no previous prototype for 'tick_broadcast'
Make sure to always include the header with the declaration.
Fixes: d86ad463d670 ("ARM: OMAP2+: Fix regression for using local timer on non-SMP SoCs") Acked-by: Aaro Koskinen aaro.koskinen@iki.fi Link: https://lore.kernel.org/r/20230516153109.514251-9-arnd@kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap2/board-generic.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 1610c567a6a3a..10d2f078e4a8e 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -13,6 +13,7 @@ #include <linux/of_platform.h> #include <linux/irqdomain.h> #include <linux/clocksource.h> +#include <linux/clockchips.h>
#include <asm/setup.h> #include <asm/mach/arch.h>
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit c77612a07d18d4425fd8ddd532a8a9b8e1970c53 ]
Correct the typo in 'regulator-name' property.
apq8096-ifc6640.dtb: v1p05-regulator: 'regulator-name' is a required property apq8096-ifc6640.dtb: v1p05-regulator: Unevaluated properties are not allowed ('reglator-name' was unexpected)
Fixes: 6cbdec2d3ca6 ("arm64: dts: qcom: msm8996: Introduce IFC6640") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230507174516.264936-3-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts index a57c60070cdc2..f0a98ab1616ab 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts +++ b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts @@ -26,7 +26,7 @@ chosen {
v1p05: v1p05-regulator { compatible = "regulator-fixed"; - reglator-name = "v1p05"; + regulator-name = "v1p05"; regulator-always-on; regulator-boot-on;
@@ -38,7 +38,7 @@ v1p05: v1p05-regulator {
v12_poe: v12-poe-regulator { compatible = "regulator-fixed"; - reglator-name = "v12_poe"; + regulator-name = "v12_poe"; regulator-always-on; regulator-boot-on;
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 42127f578ebde652d1373e0233356fbd351675c4 ]
Firmware shipped on mt8183 Chromebooks is affected by the GICR save/restore issue as described by the patch ("dt-bindings: interrupt-controller: arm,gic-v3: Add quirk for Mediatek SoCs w/ broken FW"). Add the quirk property.
Fixes: cd894e274b74 ("arm64: dts: mt8183: Add krane-sku176 board") Reviewed-by: Julius Werner jwerner@chromium.org Signed-off-by: Douglas Anderson dianders@chromium.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20230515131353.v2.3.I525a2ed4260046d43c885ee1275e9... Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi index 8e9cf36a9a41a..6529962edd4e9 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi @@ -281,6 +281,10 @@ dsi_out: endpoint { }; };
+&gic { + mediatek,broken-save-restore-fw; +}; + &gpu { mali-supply = <&mt6358_vgpu_reg>; sram-supply = <&mt6358_vsram_gpu_reg>;
From: Marek Vasut marex@denx.de
[ Upstream commit 0cf765e598712addec34d0208cc1418c151fefb2 ]
Fix the following error in kernel log due to too long sound card name: " asoc-audio-graph-card sound: ASoC: driver name too long 'STM32MP1-AV96-HDMI' -> 'STM32MP1-AV96-H' "
Fixes: e027da342772 ("ARM: dts: stm32: Add bindings for audio on AV96") Signed-off-by: Marek Vasut marex@denx.de Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi index 7fe93cdc82bbb..5f65d96435f6e 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi @@ -88,7 +88,7 @@ sd_switch: regulator-sd_switch {
sound { compatible = "audio-graph-card"; - label = "STM32MP1-AV96-HDMI"; + label = "STM32-AV96-HDMI"; dais = <&sai2a_port>; status = "okay"; };
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 1d9e93fad549bc38f593147479ee063f2872c170 ]
Code should first check for valid value of array offset, then use it as the index. Fixes smatch warning:
drivers/memory/brcmstb_dpfe.c:443 __send_command() error: testing array offset 'cmd' after use.
Fixes: 2f330caff577 ("memory: brcmstb: Add driver for DPFE") Acked-by: Markus Mayer mmayer@broadcom.com Reviewed-by: Florian Fainelli florian.fainelli@broadcom.com Link: https://lore.kernel.org/r/20230513112931.176066-1-krzysztof.kozlowski@linaro... Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memory/brcmstb_dpfe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c index f43ba69fbb3e3..2daae2e0cb19e 100644 --- a/drivers/memory/brcmstb_dpfe.c +++ b/drivers/memory/brcmstb_dpfe.c @@ -434,15 +434,17 @@ static void __finalize_command(struct brcmstb_dpfe_priv *priv) static int __send_command(struct brcmstb_dpfe_priv *priv, unsigned int cmd, u32 result[]) { - const u32 *msg = priv->dpfe_api->command[cmd]; void __iomem *regs = priv->regs; unsigned int i, chksum, chksum_idx; + const u32 *msg; int ret = 0; u32 resp;
if (cmd >= DPFE_CMD_MAX) return -1;
+ msg = priv->dpfe_api->command[cmd]; + mutex_lock(&priv->lock);
/* Wait for DCPU to become ready */
From: Cristian Ciocaltea cristian.ciocaltea@collabora.com
[ Upstream commit 6f073429037cd79d7311cd8236311c53f5ea8f01 ]
The following error occurs when trying to restore a previously saved ALSA mixer state (tested on a Rock 5B board):
$ alsactl --no-ucm -f /tmp/asound.state store hw:Analog $ alsactl --no-ucm -I -f /tmp/asound.state restore hw:Analog alsactl: set_control:1475: Cannot write control '2:0:0:ALC Capture Target Volume:0' : Invalid argument
According to ES8316 datasheet, the register at address 0x2B, which is related to the above mixer control, contains by default the value 0xB0. Considering the corresponding ALC target bits (ALCLVL) are 7:4, the control is initialized with 11, which is one step above the maximum value allowed by the driver:
ALCLVL | dB gain -------+-------- 0000 | -16.5 0001 | -15.0 0010 | -13.5 .... | ..... 0111 | -6.0 1000 | -4.5 1001 | -3.0 1010 | -1.5 .... | ..... 1111 | -1.5
The tests performed using the VU meter feature (--vumeter=TYPE) of arecord/aplay confirm the specs are correct and there is no measured gain if the 1011-1111 range would have been mapped to 0 dB:
dB gain | VU meter % --------+----------- -6.0 | 30-31 -4.5 | 35-36 -3.0 | 42-43 -1.5 | 50-51 0.0 | 50-51
Increment the max value allowed for ALC Capture Target Volume control, so that it matches the hardware default. Additionally, update the related TLV to prevent an artificial extension of the dB gain range.
Fixes: b8b88b70875a ("ASoC: add es8316 codec driver") Signed-off-by: Cristian Ciocaltea cristian.ciocaltea@collabora.com Link: https://lore.kernel.org/r/20230530181140.483936-2-cristian.ciocaltea@collabo... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/es8316.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index afd6d401e3d09..673aac91d717e 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -52,7 +52,12 @@ static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9600, 50, 1); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9600, 50, 1); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0); -static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_target_tlv, -1650, 150, 0); + +static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(alc_target_tlv, + 0, 10, TLV_DB_SCALE_ITEM(-1650, 150, 0), + 11, 11, TLV_DB_SCALE_ITEM(-150, 0, 0), +); + static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpmixer_gain_tlv, 0, 4, TLV_DB_SCALE_ITEM(-1200, 150, 0), 8, 11, TLV_DB_SCALE_ITEM(-450, 150, 0), @@ -115,7 +120,7 @@ static const struct snd_kcontrol_new es8316_snd_controls[] = { alc_max_gain_tlv), SOC_SINGLE_TLV("ALC Capture Min Volume", ES8316_ADC_ALC2, 0, 28, 0, alc_min_gain_tlv), - SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 10, 0, + SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 11, 0, alc_target_tlv), SOC_SINGLE("ALC Capture Hold Time", ES8316_ADC_ALC3, 0, 10, 0), SOC_SINGLE("ALC Capture Decay Time", ES8316_ADC_ALC4, 4, 10, 0),
From: Cristian Ciocaltea cristian.ciocaltea@collabora.com
[ Upstream commit 60413129ee2b38a80347489270af7f6e1c1de4d0 ]
When using the codec through the generic audio graph card, there are at least two calls of es8316_set_dai_sysclk(), with the effect of limiting the allowed sample rates according to the MCLK/LRCK ratios supported by the codec:
1. During audio card setup, to set the initial MCLK - see asoc_simple_init_dai().
2. Before opening a stream, to update MCLK, according to the stream sample rate and the multiplication factor - see asoc_simple_hw_params().
In some cases the initial MCLK might be set to a frequency that doesn't match any of the supported ratios, e.g. 12287999 instead of 12288000, which is only 1 Hz below the supported clock, as that is what the hardware reports. This creates an empty list of rate constraints, which is further passed to snd_pcm_hw_constraint_list() via es8316_pcm_startup(), and causes the following error on the very first access of the sound card:
$ speaker-test -D hw:Analog,0 -F S16_LE -c 2 -t wav Broken configuration for playback: no configurations available: Invalid argument Setting of hwparams failed: Invalid argument
Note that all subsequent retries succeed thanks to the updated MCLK set at point 2 above, which uses a computed frequency value instead of a reading from the hardware registers. Normally this would have mitigated the issue, but es8316_pcm_startup() executes before the 2nd call to es8316_set_dai_sysclk(), hence it cannot make use of the updated constraints.
Since es8316_pcm_hw_params() performs anyway a final validation of MCLK against the stream sample rate and the supported MCLK/LRCK ratios, fix the issue by ensuring that sysclk_constraints list is only set when at least one supported sample rate is autodetected by the codec.
Fixes: b8b88b70875a ("ASoC: add es8316 codec driver") Signed-off-by: Cristian Ciocaltea cristian.ciocaltea@collabora.com Link: https://lore.kernel.org/r/20230530181140.483936-3-cristian.ciocaltea@collabo... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/es8316.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index 673aac91d717e..b36ccfc54cd69 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -369,13 +369,11 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai, int count = 0;
es8316->sysclk = freq; + es8316->sysclk_constraints.list = NULL; + es8316->sysclk_constraints.count = 0;
- if (freq == 0) { - es8316->sysclk_constraints.list = NULL; - es8316->sysclk_constraints.count = 0; - + if (freq == 0) return 0; - }
ret = clk_set_rate(es8316->mclk, freq); if (ret) @@ -391,8 +389,10 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai, es8316->allowed_rates[count++] = freq / ratio; }
- es8316->sysclk_constraints.list = es8316->allowed_rates; - es8316->sysclk_constraints.count = count; + if (count) { + es8316->sysclk_constraints.list = es8316->allowed_rates; + es8316->sysclk_constraints.count = count; + }
return 0; }
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
[ Upstream commit 98b503c7fb13a17a47d8ebf15fa8f7c10118e75c ]
On Meson8 uart_B and uart_C do not work, because they are relying on incorrect clocks. Change the references of pclk to the correct CLKID (UART1 for uart_B and UART2 for uart_C), to allow use of the two uarts.
This was originally reported by Hans-Frieder Vogt for Meson8b [0], but the same bug is also present in meson8.dtsi
[0] https://lore.kernel.org/linux-amlogic/trinity-bf20bcb9-790b-4ab9-99e3-0831ef...
Fixes: 57007bfb5469 ("ARM: dts: meson8: Fix the UART device-tree schema validation") Reported-by: Hans-Frieder Vogt hfdevel@gmx.net # for meson8b.dtsi Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Link: https://lore.kernel.org/r/20230516203029.1031174-1-martin.blumenstingl@googl... Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/meson8.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi index 9997a5d0333a3..72828b9d4281d 100644 --- a/arch/arm/boot/dts/meson8.dtsi +++ b/arch/arm/boot/dts/meson8.dtsi @@ -749,13 +749,13 @@ &uart_A {
&uart_B { compatible = "amlogic,meson8-uart"; - clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; + clocks = <&xtal>, <&clkc CLKID_UART1>, <&clkc CLKID_CLK81>; clock-names = "xtal", "pclk", "baud"; };
&uart_C { compatible = "amlogic,meson8-uart"; - clocks = <&xtal>, <&clkc CLKID_UART0>, <&clkc CLKID_CLK81>; + clocks = <&xtal>, <&clkc CLKID_UART2>, <&clkc CLKID_CLK81>; clock-names = "xtal", "pclk", "baud"; };
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 7b1a78babd0d2cd27aa07255dee0c2d7ac0f31e3 ]
Fix build errors in soc/fsl/qe/usb.c when QUICC_ENGINE is not set. This happens when PPC_EP88XC is set, which selects CPM1 & CPM. When CPM is set, USB_FSL_QE can be set without QUICC_ENGINE being set. When USB_FSL_QE is set, QE_USB deafults to y, which causes build errors when QUICC_ENGINE is not set. Making QE_USB depend on QUICC_ENGINE prevents QE_USB from defaulting to y.
Fixes these build errors:
drivers/soc/fsl/qe/usb.o: in function `qe_usb_clock_set': usb.c:(.text+0x1e): undefined reference to `qe_immr' powerpc-linux-ld: usb.c:(.text+0x2a): undefined reference to `qe_immr' powerpc-linux-ld: usb.c:(.text+0xbc): undefined reference to `qe_setbrg' powerpc-linux-ld: usb.c:(.text+0xca): undefined reference to `cmxgcr_lock' powerpc-linux-ld: usb.c:(.text+0xce): undefined reference to `cmxgcr_lock'
Fixes: 5e41486c408e ("powerpc/QE: add support for QE USB clocks routing") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Link: https://lore.kernel.org/all/202301101500.pillNv6R-lkp@intel.com/ Suggested-by: Michael Ellerman mpe@ellerman.id.au Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Leo Li leoyang.li@nxp.com Cc: Masahiro Yamada masahiroy@kernel.org Cc: Nicolas Schier nicolas@fjasle.eu Cc: Qiang Zhao qiang.zhao@nxp.com Cc: linuxppc-dev linuxppc-dev@lists.ozlabs.org Cc: linux-arm-kernel@lists.infradead.org Cc: Kumar Gala galak@kernel.crashing.org Acked-by: Nicolas Schier nicolas@jasle.eu Signed-off-by: Li Yang leoyang.li@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/fsl/qe/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/soc/fsl/qe/Kconfig b/drivers/soc/fsl/qe/Kconfig index 357c5800b112f..7afa796dbbb89 100644 --- a/drivers/soc/fsl/qe/Kconfig +++ b/drivers/soc/fsl/qe/Kconfig @@ -39,6 +39,7 @@ config QE_TDM
config QE_USB bool + depends on QUICC_ENGINE default y if USB_FSL_QE help QE USB Controller support
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit b002760f877c0d91ecd3c78565b52f4bbac379dd ]
Commit df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3") triggers a warning for fortified memset():
In function 'fortify_memset_chk', inlined from 'irdma_clr_wqes' at drivers/infiniband/hw/irdma/uk.c:103:4: include/linux/fortify-string.h:493:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning] 493 | __write_overflow_field(p_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The problem here isthat the inner array only has four 8-byte elements, so clearing 4096 bytes overflows that. As this structure is part of an outer array, change the code to pass a pointer to the irdma_qp_quanta instead, and change the size argument for readability, matching the comment above it.
Fixes: 551c46edc769 ("RDMA/irdma: Add user/kernel shared libraries") Link: https://lore.kernel.org/r/20230523111859.2197825-1-arnd@kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Shiraz Saleem shiraz.saleem@intel.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/irdma/uk.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c index aecd64a7dbbaf..a348f0c010ab3 100644 --- a/drivers/infiniband/hw/irdma/uk.c +++ b/drivers/infiniband/hw/irdma/uk.c @@ -94,16 +94,18 @@ static enum irdma_status_code irdma_nop_1(struct irdma_qp_uk *qp) */ void irdma_clr_wqes(struct irdma_qp_uk *qp, u32 qp_wqe_idx) { - __le64 *wqe; + struct irdma_qp_quanta *sq; u32 wqe_idx;
if (!(qp_wqe_idx & 0x7F)) { wqe_idx = (qp_wqe_idx + 128) % qp->sq_ring.size; - wqe = qp->sq_base[wqe_idx].elem; + sq = qp->sq_base + wqe_idx; if (wqe_idx) - memset(wqe, qp->swqe_polarity ? 0 : 0xFF, 0x1000); + memset(sq, qp->swqe_polarity ? 0 : 0xFF, + 128 * sizeof(*sq)); else - memset(wqe, qp->swqe_polarity ? 0xFF : 0, 0x1000); + memset(sq, qp->swqe_polarity ? 0xFF : 0, + 128 * sizeof(*sq)); } }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit f86dbc9fc5d83384eae7eda0de17f823e8c81ca0 ]
Use 'bitmap_zalloc()' to simplify code, improve the semantic and avoid some open-coded arithmetic in allocator arguments.
Also change the corresponding 'kfree()' into 'bitmap_free()' to keep consistency.
Link: https://lore.kernel.org/r/d46c6bc1869b8869244fa71943d2cad4104b3668.163786992... Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Jason Gunthorpe jgg@nvidia.com Stable-dep-of: c9358de193ec ("IB/hfi1: Fix wrong mmu_node used for user SDMA packet after invalidate") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/user_sdma.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c index a932ae1e03af5..ae58b48afe074 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.c +++ b/drivers/infiniband/hw/hfi1/user_sdma.c @@ -161,9 +161,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, if (!pq->reqs) goto pq_reqs_nomem;
- pq->req_in_use = kcalloc(BITS_TO_LONGS(hfi1_sdma_comp_ring_size), - sizeof(*pq->req_in_use), - GFP_KERNEL); + pq->req_in_use = bitmap_zalloc(hfi1_sdma_comp_ring_size, GFP_KERNEL); if (!pq->req_in_use) goto pq_reqs_no_in_use;
@@ -210,7 +208,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, cq_nomem: kmem_cache_destroy(pq->txreq_cache); pq_txreq_nomem: - kfree(pq->req_in_use); + bitmap_free(pq->req_in_use); pq_reqs_no_in_use: kfree(pq->reqs); pq_reqs_nomem: @@ -257,7 +255,7 @@ int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd, pq->wait, !atomic_read(&pq->n_reqs)); kfree(pq->reqs); - kfree(pq->req_in_use); + bitmap_free(pq->req_in_use); kmem_cache_destroy(pq->txreq_cache); flush_pq_iowait(pq); kfree(pq);
From: Brendan Cunningham bcunningham@cornelisnetworks.com
[ Upstream commit c9358de193ecfb360c3ce75f27ce839ca0b0bc8c ]
The hfi1 user SDMA pinned-page cache will leave a stale cache entry when the cache-entry's virtual address range is invalidated but that cache entry is in-use by an outstanding SDMA request.
Subsequent user SDMA requests with buffers in or spanning the virtual address range of the stale cache entry will result in packets constructed from the wrong memory, the physical pages pointed to by the stale cache entry.
To fix this, remove mmu_rb_node cache entries from the mmu_rb_handler cache independent of the cache entry's refcount. Add 'struct kref refcount' to struct mmu_rb_node and manage mmu_rb_node lifetime with kref_get() and kref_put().
mmu_rb_node.refcount makes sdma_mmu_node.refcount redundant. Remove 'atomic_t refcount' from struct sdma_mmu_node and change sdma_mmu_node code to use mmu_rb_node.refcount.
Move the mmu_rb_handler destructor call after a wait-for-SDMA-request-completion call so mmu_rb_nodes that need mmu_rb_handler's workqueue to queue themselves up for destruction from an interrupt context may do so.
Fixes: f48ad614c100 ("IB/hfi1: Move driver out of staging") Fixes: 00cbce5cbf88 ("IB/hfi1: Fix bugs with non-PAGE_SIZE-end multi-iovec user SDMA requests") Link: https://lore.kernel.org/r/168451393605.3700681.13493776139032178861.stgit@aw... Reviewed-by: Dean Luick dean.luick@cornelisnetworks.com Signed-off-by: Brendan Cunningham bcunningham@cornelisnetworks.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/ipoib_tx.c | 4 +- drivers/infiniband/hw/hfi1/mmu_rb.c | 101 ++++++++++------- drivers/infiniband/hw/hfi1/mmu_rb.h | 3 + drivers/infiniband/hw/hfi1/sdma.c | 23 +++- drivers/infiniband/hw/hfi1/sdma.h | 47 +++++--- drivers/infiniband/hw/hfi1/sdma_txreq.h | 2 + drivers/infiniband/hw/hfi1/user_sdma.c | 137 ++++++++++-------------- drivers/infiniband/hw/hfi1/user_sdma.h | 1 - drivers/infiniband/hw/hfi1/vnic_sdma.c | 4 +- 9 files changed, 177 insertions(+), 145 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/ipoib_tx.c b/drivers/infiniband/hw/hfi1/ipoib_tx.c index 33ffb00c63823..a89d1bd99a332 100644 --- a/drivers/infiniband/hw/hfi1/ipoib_tx.c +++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c @@ -251,11 +251,11 @@ static int hfi1_ipoib_build_ulp_payload(struct ipoib_txreq *tx, const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
ret = sdma_txadd_page(dd, - NULL, txreq, skb_frag_page(frag), frag->bv_offset, - skb_frag_size(frag)); + skb_frag_size(frag), + NULL, NULL, NULL); if (unlikely(ret)) break; } diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c index 71b9ac0188875..94f1701667301 100644 --- a/drivers/infiniband/hw/hfi1/mmu_rb.c +++ b/drivers/infiniband/hw/hfi1/mmu_rb.c @@ -19,8 +19,7 @@ static int mmu_notifier_range_start(struct mmu_notifier *, const struct mmu_notifier_range *); static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *, unsigned long, unsigned long); -static void do_remove(struct mmu_rb_handler *handler, - struct list_head *del_list); +static void release_immediate(struct kref *refcount); static void handle_remove(struct work_struct *work);
static const struct mmu_notifier_ops mn_opts = { @@ -103,7 +102,11 @@ void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler) } spin_unlock_irqrestore(&handler->lock, flags);
- do_remove(handler, &del_list); + while (!list_empty(&del_list)) { + rbnode = list_first_entry(&del_list, struct mmu_rb_node, list); + list_del(&rbnode->list); + kref_put(&rbnode->refcount, release_immediate); + }
/* Now the mm may be freed. */ mmdrop(handler->mn.mm); @@ -131,12 +134,6 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, } __mmu_int_rb_insert(mnode, &handler->root); list_add_tail(&mnode->list, &handler->lru_list); - - ret = handler->ops->insert(handler->ops_arg, mnode); - if (ret) { - __mmu_int_rb_remove(mnode, &handler->root); - list_del(&mnode->list); /* remove from LRU list */ - } mnode->handler = handler; unlock: spin_unlock_irqrestore(&handler->lock, flags); @@ -180,6 +177,48 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, return node; }
+/* + * Must NOT call while holding mnode->handler->lock. + * mnode->handler->ops->remove() may sleep and mnode->handler->lock is a + * spinlock. + */ +static void release_immediate(struct kref *refcount) +{ + struct mmu_rb_node *mnode = + container_of(refcount, struct mmu_rb_node, refcount); + mnode->handler->ops->remove(mnode->handler->ops_arg, mnode); +} + +/* Caller must hold mnode->handler->lock */ +static void release_nolock(struct kref *refcount) +{ + struct mmu_rb_node *mnode = + container_of(refcount, struct mmu_rb_node, refcount); + list_move(&mnode->list, &mnode->handler->del_list); + queue_work(mnode->handler->wq, &mnode->handler->del_work); +} + +/* + * struct mmu_rb_node->refcount kref_put() callback. + * Adds mmu_rb_node to mmu_rb_node->handler->del_list and queues + * handler->del_work on handler->wq. + * Does not remove mmu_rb_node from handler->lru_list or handler->rb_root. + * Acquires mmu_rb_node->handler->lock; do not call while already holding + * handler->lock. + */ +void hfi1_mmu_rb_release(struct kref *refcount) +{ + struct mmu_rb_node *mnode = + container_of(refcount, struct mmu_rb_node, refcount); + struct mmu_rb_handler *handler = mnode->handler; + unsigned long flags; + + spin_lock_irqsave(&handler->lock, flags); + list_move(&mnode->list, &mnode->handler->del_list); + spin_unlock_irqrestore(&handler->lock, flags); + queue_work(handler->wq, &handler->del_work); +} + void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) { struct mmu_rb_node *rbnode, *ptr; @@ -194,6 +233,10 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
spin_lock_irqsave(&handler->lock, flags); list_for_each_entry_safe(rbnode, ptr, &handler->lru_list, list) { + /* refcount == 1 implies mmu_rb_handler has only rbnode ref */ + if (kref_read(&rbnode->refcount) > 1) + continue; + if (handler->ops->evict(handler->ops_arg, rbnode, evict_arg, &stop)) { __mmu_int_rb_remove(rbnode, &handler->root); @@ -206,7 +249,7 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) spin_unlock_irqrestore(&handler->lock, flags);
list_for_each_entry_safe(rbnode, ptr, &del_list, list) { - handler->ops->remove(handler->ops_arg, rbnode); + kref_put(&rbnode->refcount, release_immediate); } }
@@ -218,7 +261,6 @@ static int mmu_notifier_range_start(struct mmu_notifier *mn, struct rb_root_cached *root = &handler->root; struct mmu_rb_node *node, *ptr = NULL; unsigned long flags; - bool added = false;
spin_lock_irqsave(&handler->lock, flags); for (node = __mmu_int_rb_iter_first(root, range->start, range->end-1); @@ -227,38 +269,16 @@ static int mmu_notifier_range_start(struct mmu_notifier *mn, ptr = __mmu_int_rb_iter_next(node, range->start, range->end - 1); trace_hfi1_mmu_mem_invalidate(node->addr, node->len); - if (handler->ops->invalidate(handler->ops_arg, node)) { - __mmu_int_rb_remove(node, root); - /* move from LRU list to delete list */ - list_move(&node->list, &handler->del_list); - added = true; - } + /* Remove from rb tree and lru_list. */ + __mmu_int_rb_remove(node, root); + list_del_init(&node->list); + kref_put(&node->refcount, release_nolock); } spin_unlock_irqrestore(&handler->lock, flags);
- if (added) - queue_work(handler->wq, &handler->del_work); - return 0; }
-/* - * Call the remove function for the given handler and the list. This - * is expected to be called with a delete list extracted from handler. - * The caller should not be holding the handler lock. - */ -static void do_remove(struct mmu_rb_handler *handler, - struct list_head *del_list) -{ - struct mmu_rb_node *node; - - while (!list_empty(del_list)) { - node = list_first_entry(del_list, struct mmu_rb_node, list); - list_del(&node->list); - handler->ops->remove(handler->ops_arg, node); - } -} - /* * Work queue function to remove all nodes that have been queued up to * be removed. The key feature is that mm->mmap_lock is not being held @@ -271,11 +291,16 @@ static void handle_remove(struct work_struct *work) del_work); struct list_head del_list; unsigned long flags; + struct mmu_rb_node *node;
/* remove anything that is queued to get removed */ spin_lock_irqsave(&handler->lock, flags); list_replace_init(&handler->del_list, &del_list); spin_unlock_irqrestore(&handler->lock, flags);
- do_remove(handler, &del_list); + while (!list_empty(&del_list)) { + node = list_first_entry(&del_list, struct mmu_rb_node, list); + list_del(&node->list); + handler->ops->remove(handler->ops_arg, node); + } } diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.h b/drivers/infiniband/hw/hfi1/mmu_rb.h index ed75acdb7b839..dd2c4a0ae95b1 100644 --- a/drivers/infiniband/hw/hfi1/mmu_rb.h +++ b/drivers/infiniband/hw/hfi1/mmu_rb.h @@ -16,6 +16,7 @@ struct mmu_rb_node { struct rb_node node; struct mmu_rb_handler *handler; struct list_head list; + struct kref refcount; };
/* @@ -51,6 +52,8 @@ int hfi1_mmu_rb_register(void *ops_arg, void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler); int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, struct mmu_rb_node *mnode); +void hfi1_mmu_rb_release(struct kref *refcount); + void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg); struct mmu_rb_node *hfi1_mmu_rb_get_first(struct mmu_rb_handler *handler, unsigned long addr, diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index bb2552dd29c1e..26c62162759ba 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c @@ -1593,7 +1593,20 @@ static inline void sdma_unmap_desc( struct hfi1_devdata *dd, struct sdma_desc *descp) { - system_descriptor_complete(dd, descp); + switch (sdma_mapping_type(descp)) { + case SDMA_MAP_SINGLE: + dma_unmap_single(&dd->pcidev->dev, sdma_mapping_addr(descp), + sdma_mapping_len(descp), DMA_TO_DEVICE); + break; + case SDMA_MAP_PAGE: + dma_unmap_page(&dd->pcidev->dev, sdma_mapping_addr(descp), + sdma_mapping_len(descp), DMA_TO_DEVICE); + break; + } + + if (descp->pinning_ctx && descp->ctx_put) + descp->ctx_put(descp->pinning_ctx); + descp->pinning_ctx = NULL; }
/* @@ -3113,8 +3126,8 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
/* Add descriptor for coalesce buffer */ tx->desc_limit = MAX_DESC; - return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx, - addr, tx->tlen); + return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx, + addr, tx->tlen, NULL, NULL, NULL); }
return 1; @@ -3157,9 +3170,9 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) make_tx_sdma_desc( tx, SDMA_MAP_NONE, - NULL, dd->sdma_pad_phys, - sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1))); + sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1)), + NULL, NULL, NULL); tx->num_desc++; _sdma_close_tx(dd, tx); return rval; diff --git a/drivers/infiniband/hw/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h index 95aaec14c6c28..7fdebab202c4f 100644 --- a/drivers/infiniband/hw/hfi1/sdma.h +++ b/drivers/infiniband/hw/hfi1/sdma.h @@ -594,9 +594,11 @@ static inline dma_addr_t sdma_mapping_addr(struct sdma_desc *d) static inline void make_tx_sdma_desc( struct sdma_txreq *tx, int type, - void *pinning_ctx, dma_addr_t addr, - size_t len) + size_t len, + void *pinning_ctx, + void (*ctx_get)(void *), + void (*ctx_put)(void *)) { struct sdma_desc *desc = &tx->descp[tx->num_desc];
@@ -613,7 +615,11 @@ static inline void make_tx_sdma_desc( << SDMA_DESC0_PHY_ADDR_SHIFT) | (((u64)len & SDMA_DESC0_BYTE_COUNT_MASK) << SDMA_DESC0_BYTE_COUNT_SHIFT); + desc->pinning_ctx = pinning_ctx; + desc->ctx_put = ctx_put; + if (pinning_ctx && ctx_get) + ctx_get(pinning_ctx); }
/* helper to extend txreq */ @@ -645,18 +651,20 @@ static inline void _sdma_close_tx(struct hfi1_devdata *dd, static inline int _sdma_txadd_daddr( struct hfi1_devdata *dd, int type, - void *pinning_ctx, struct sdma_txreq *tx, dma_addr_t addr, - u16 len) + u16 len, + void *pinning_ctx, + void (*ctx_get)(void *), + void (*ctx_put)(void *)) { int rval = 0;
make_tx_sdma_desc( tx, type, - pinning_ctx, - addr, len); + addr, len, + pinning_ctx, ctx_get, ctx_put); WARN_ON(len > tx->tlen); tx->num_desc++; tx->tlen -= len; @@ -676,11 +684,18 @@ static inline int _sdma_txadd_daddr( /** * sdma_txadd_page() - add a page to the sdma_txreq * @dd: the device to use for mapping - * @pinning_ctx: context to be released at descriptor retirement * @tx: tx request to which the page is added * @page: page to map * @offset: offset within the page * @len: length in bytes + * @pinning_ctx: context to be stored on struct sdma_desc .pinning_ctx. Not + * added if coalesce buffer is used. E.g. pointer to pinned-page + * cache entry for the sdma_desc. + * @ctx_get: optional function to take reference to @pinning_ctx. Not called if + * @pinning_ctx is NULL. + * @ctx_put: optional function to release reference to @pinning_ctx after + * sdma_desc completes. May be called in interrupt context so must + * not sleep. Not called if @pinning_ctx is NULL. * * This is used to add a page/offset/length descriptor. * @@ -692,11 +707,13 @@ static inline int _sdma_txadd_daddr( */ static inline int sdma_txadd_page( struct hfi1_devdata *dd, - void *pinning_ctx, struct sdma_txreq *tx, struct page *page, unsigned long offset, - u16 len) + u16 len, + void *pinning_ctx, + void (*ctx_get)(void *), + void (*ctx_put)(void *)) { dma_addr_t addr; int rval; @@ -720,7 +737,8 @@ static inline int sdma_txadd_page( return -ENOSPC; }
- return _sdma_txadd_daddr(dd, SDMA_MAP_PAGE, pinning_ctx, tx, addr, len); + return _sdma_txadd_daddr(dd, SDMA_MAP_PAGE, tx, addr, len, + pinning_ctx, ctx_get, ctx_put); }
/** @@ -754,8 +772,8 @@ static inline int sdma_txadd_daddr( return rval; }
- return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, NULL, tx, - addr, len); + return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, tx, addr, len, + NULL, NULL, NULL); }
/** @@ -801,7 +819,8 @@ static inline int sdma_txadd_kvaddr( return -ENOSPC; }
- return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx, addr, len); + return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx, addr, len, + NULL, NULL, NULL); }
struct iowait_work; @@ -1034,6 +1053,4 @@ u16 sdma_get_descq_cnt(void); extern uint mod_num_sdma;
void sdma_update_lmc(struct hfi1_devdata *dd, u64 mask, u32 lid); - -void system_descriptor_complete(struct hfi1_devdata *dd, struct sdma_desc *descp); #endif diff --git a/drivers/infiniband/hw/hfi1/sdma_txreq.h b/drivers/infiniband/hw/hfi1/sdma_txreq.h index fad946cb5e0d8..85ae7293c2741 100644 --- a/drivers/infiniband/hw/hfi1/sdma_txreq.h +++ b/drivers/infiniband/hw/hfi1/sdma_txreq.h @@ -20,6 +20,8 @@ struct sdma_desc { /* private: don't use directly */ u64 qw[2]; void *pinning_ctx; + /* Release reference to @pinning_ctx. May be called in interrupt context. Must not sleep. */ + void (*ctx_put)(void *ctx); };
/** diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c index ae58b48afe074..02bd62b857b75 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.c +++ b/drivers/infiniband/hw/hfi1/user_sdma.c @@ -62,18 +62,14 @@ static int defer_packet_queue( static void activate_packet_queue(struct iowait *wait, int reason); static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr, unsigned long len); -static int sdma_rb_insert(void *arg, struct mmu_rb_node *mnode); static int sdma_rb_evict(void *arg, struct mmu_rb_node *mnode, void *arg2, bool *stop); static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode); -static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode);
static struct mmu_rb_ops sdma_rb_ops = { .filter = sdma_rb_filter, - .insert = sdma_rb_insert, .evict = sdma_rb_evict, .remove = sdma_rb_remove, - .invalidate = sdma_rb_invalidate };
static int add_system_pages_to_sdma_packet(struct user_sdma_request *req, @@ -247,14 +243,14 @@ int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd, spin_unlock(&fd->pq_rcu_lock); synchronize_srcu(&fd->pq_srcu); /* at this point there can be no more new requests */ - if (pq->handler) - hfi1_mmu_rb_unregister(pq->handler); iowait_sdma_drain(&pq->busy); /* Wait until all requests have been freed. */ wait_event_interruptible( pq->wait, !atomic_read(&pq->n_reqs)); kfree(pq->reqs); + if (pq->handler) + hfi1_mmu_rb_unregister(pq->handler); bitmap_free(pq->req_in_use); kmem_cache_destroy(pq->txreq_cache); flush_pq_iowait(pq); @@ -1275,25 +1271,17 @@ static void free_system_node(struct sdma_mmu_node *node) kfree(node); }
-static inline void acquire_node(struct sdma_mmu_node *node) -{ - atomic_inc(&node->refcount); - WARN_ON(atomic_read(&node->refcount) < 0); -} - -static inline void release_node(struct mmu_rb_handler *handler, - struct sdma_mmu_node *node) -{ - atomic_dec(&node->refcount); - WARN_ON(atomic_read(&node->refcount) < 0); -} - +/* + * kref_get()'s an additional kref on the returned rb_node to prevent rb_node + * from being released until after rb_node is assigned to an SDMA descriptor + * (struct sdma_desc) under add_system_iovec_to_sdma_packet(), even if the + * virtual address range for rb_node is invalidated between now and then. + */ static struct sdma_mmu_node *find_system_node(struct mmu_rb_handler *handler, unsigned long start, unsigned long end) { struct mmu_rb_node *rb_node; - struct sdma_mmu_node *node; unsigned long flags;
spin_lock_irqsave(&handler->lock, flags); @@ -1302,11 +1290,12 @@ static struct sdma_mmu_node *find_system_node(struct mmu_rb_handler *handler, spin_unlock_irqrestore(&handler->lock, flags); return NULL; } - node = container_of(rb_node, struct sdma_mmu_node, rb); - acquire_node(node); + + /* "safety" kref to prevent release before add_system_iovec_to_sdma_packet() */ + kref_get(&rb_node->refcount); spin_unlock_irqrestore(&handler->lock, flags);
- return node; + return container_of(rb_node, struct sdma_mmu_node, rb); }
static int pin_system_pages(struct user_sdma_request *req, @@ -1355,6 +1344,13 @@ static int pin_system_pages(struct user_sdma_request *req, return 0; }
+/* + * kref refcount on *node_p will be 2 on successful addition: one kref from + * kref_init() for mmu_rb_handler and one kref to prevent *node_p from being + * released until after *node_p is assigned to an SDMA descriptor (struct + * sdma_desc) under add_system_iovec_to_sdma_packet(), even if the virtual + * address range for *node_p is invalidated between now and then. + */ static int add_system_pinning(struct user_sdma_request *req, struct sdma_mmu_node **node_p, unsigned long start, unsigned long len) @@ -1368,6 +1364,12 @@ static int add_system_pinning(struct user_sdma_request *req, if (!node) return -ENOMEM;
+ /* First kref "moves" to mmu_rb_handler */ + kref_init(&node->rb.refcount); + + /* "safety" kref to prevent release before add_system_iovec_to_sdma_packet() */ + kref_get(&node->rb.refcount); + node->pq = pq; ret = pin_system_pages(req, start, len, node, PFN_DOWN(len)); if (ret == 0) { @@ -1431,15 +1433,15 @@ static int get_system_cache_entry(struct user_sdma_request *req, return 0; }
- SDMA_DBG(req, "prepend: node->rb.addr %lx, node->refcount %d", - node->rb.addr, atomic_read(&node->refcount)); + SDMA_DBG(req, "prepend: node->rb.addr %lx, node->rb.refcount %d", + node->rb.addr, kref_read(&node->rb.refcount)); prepend_len = node->rb.addr - start;
/* * This node will not be returned, instead a new node * will be. So release the reference. */ - release_node(handler, node); + kref_put(&node->rb.refcount, hfi1_mmu_rb_release);
/* Prepend a node to cover the beginning of the allocation */ ret = add_system_pinning(req, node_p, start, prepend_len); @@ -1451,6 +1453,20 @@ static int get_system_cache_entry(struct user_sdma_request *req, } }
+static void sdma_mmu_rb_node_get(void *ctx) +{ + struct mmu_rb_node *node = ctx; + + kref_get(&node->refcount); +} + +static void sdma_mmu_rb_node_put(void *ctx) +{ + struct sdma_mmu_node *node = ctx; + + kref_put(&node->rb.refcount, hfi1_mmu_rb_release); +} + static int add_mapping_to_sdma_packet(struct user_sdma_request *req, struct user_sdma_txreq *tx, struct sdma_mmu_node *cache_entry, @@ -1494,9 +1510,12 @@ static int add_mapping_to_sdma_packet(struct user_sdma_request *req, ctx = cache_entry; }
- ret = sdma_txadd_page(pq->dd, ctx, &tx->txreq, + ret = sdma_txadd_page(pq->dd, &tx->txreq, cache_entry->pages[page_index], - page_offset, from_this_page); + page_offset, from_this_page, + ctx, + sdma_mmu_rb_node_get, + sdma_mmu_rb_node_put); if (ret) { /* * When there's a failure, the entire request is freed by @@ -1518,8 +1537,6 @@ static int add_system_iovec_to_sdma_packet(struct user_sdma_request *req, struct user_sdma_iovec *iovec, size_t from_this_iovec) { - struct mmu_rb_handler *handler = req->pq->handler; - while (from_this_iovec > 0) { struct sdma_mmu_node *cache_entry; size_t from_this_cache_entry; @@ -1540,15 +1557,15 @@ static int add_system_iovec_to_sdma_packet(struct user_sdma_request *req,
ret = add_mapping_to_sdma_packet(req, tx, cache_entry, start, from_this_cache_entry); + + /* + * Done adding cache_entry to zero or more sdma_desc. Can + * kref_put() the "safety" kref taken under + * get_system_cache_entry(). + */ + kref_put(&cache_entry->rb.refcount, hfi1_mmu_rb_release); + if (ret) { - /* - * We're guaranteed that there will be no descriptor - * completion callback that releases this node - * because only the last descriptor referencing it - * has a context attached, and a failure means the - * last descriptor was never added. - */ - release_node(handler, cache_entry); SDMA_DBG(req, "add system segment failed %d", ret); return ret; } @@ -1599,42 +1616,12 @@ static int add_system_pages_to_sdma_packet(struct user_sdma_request *req, return 0; }
-void system_descriptor_complete(struct hfi1_devdata *dd, - struct sdma_desc *descp) -{ - switch (sdma_mapping_type(descp)) { - case SDMA_MAP_SINGLE: - dma_unmap_single(&dd->pcidev->dev, sdma_mapping_addr(descp), - sdma_mapping_len(descp), DMA_TO_DEVICE); - break; - case SDMA_MAP_PAGE: - dma_unmap_page(&dd->pcidev->dev, sdma_mapping_addr(descp), - sdma_mapping_len(descp), DMA_TO_DEVICE); - break; - } - - if (descp->pinning_ctx) { - struct sdma_mmu_node *node = descp->pinning_ctx; - - release_node(node->rb.handler, node); - } -} - static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr, unsigned long len) { return (bool)(node->addr == addr); }
-static int sdma_rb_insert(void *arg, struct mmu_rb_node *mnode) -{ - struct sdma_mmu_node *node = - container_of(mnode, struct sdma_mmu_node, rb); - - atomic_inc(&node->refcount); - return 0; -} - /* * Return 1 to remove the node from the rb tree and call the remove op. * @@ -1647,10 +1634,6 @@ static int sdma_rb_evict(void *arg, struct mmu_rb_node *mnode, container_of(mnode, struct sdma_mmu_node, rb); struct evict_data *evict_data = evict_arg;
- /* is this node still being used? */ - if (atomic_read(&node->refcount)) - return 0; /* keep this node */ - /* this node will be evicted, add its pages to our count */ evict_data->cleared += node->npages;
@@ -1668,13 +1651,3 @@ static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode)
free_system_node(node); } - -static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode) -{ - struct sdma_mmu_node *node = - container_of(mnode, struct sdma_mmu_node, rb); - - if (!atomic_read(&node->refcount)) - return 1; - return 0; -} diff --git a/drivers/infiniband/hw/hfi1/user_sdma.h b/drivers/infiniband/hw/hfi1/user_sdma.h index a241836371dc1..548347d4c5bc2 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.h +++ b/drivers/infiniband/hw/hfi1/user_sdma.h @@ -104,7 +104,6 @@ struct hfi1_user_sdma_comp_q { struct sdma_mmu_node { struct mmu_rb_node rb; struct hfi1_user_sdma_pkt_q *pq; - atomic_t refcount; struct page **pages; unsigned int npages; }; diff --git a/drivers/infiniband/hw/hfi1/vnic_sdma.c b/drivers/infiniband/hw/hfi1/vnic_sdma.c index 727eedfba332a..cc6324d2d1ddc 100644 --- a/drivers/infiniband/hw/hfi1/vnic_sdma.c +++ b/drivers/infiniband/hw/hfi1/vnic_sdma.c @@ -64,11 +64,11 @@ static noinline int build_vnic_ulp_payload(struct sdma_engine *sde,
/* combine physically continuous fragments later? */ ret = sdma_txadd_page(sde->dd, - NULL, &tx->txreq, skb_frag_page(frag), skb_frag_off(frag), - skb_frag_size(frag)); + skb_frag_size(frag), + NULL, NULL, NULL); if (unlikely(ret)) goto bail_txadd; }
From: Chengchang Tang tangchengchang@huawei.com
[ Upstream commit cf5b608fb0e369c473a8303cad6ddb386505e5b8 ]
The return value of set_hem has been fixed to ENODEV, which will lead a diagnostic information missing.
Fixes: 9a4435375cd1 ("IB/hns: Add driver files for hns RoCE driver") Link: https://lore.kernel.org/r/20230523121641.3132102-3-huangjunxian6@hisilicon.c... Signed-off-by: Chengchang Tang tangchengchang@huawei.com Signed-off-by: Junxian Huang huangjunxian6@hisilicon.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hns/hns_roce_hem.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c index fa15d79eabb36..267474070f271 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hem.c +++ b/drivers/infiniband/hw/hns/hns_roce_hem.c @@ -597,11 +597,12 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev, }
/* Set HEM base address(128K/page, pa) to Hardware */ - if (hr_dev->hw->set_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT)) { + ret = hr_dev->hw->set_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT); + if (ret) { hns_roce_free_hem(hr_dev, table->hem[i]); table->hem[i] = NULL; - ret = -ENODEV; - dev_err(dev, "set HEM base address to HW failed.\n"); + dev_err(dev, "set HEM base address to HW failed, ret = %d.\n", + ret); goto out; }
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 0501fdec106a291c43b3c1b525cf22ab4c24b2d8 ]
make dtbs_check:
arch/arm/boot/dts/renesas/r8a7743-iwg20d-q7.dtb: backlight: pwms: [[58, 0, 5000000], [0]] is too long From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml arch/arm/boot/dts/renesas/r8a7743-iwg20d-q7-dbcm-ca.dtb: backlight: pwms: [[67, 0, 5000000], [0]] is too long From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml arch/arm/boot/dts/renesas/r8a7744-iwg20d-q7-dbcm-ca.dtb: backlight: pwms: [[67, 0, 5000000], [0]] is too long From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml arch/arm/boot/dts/renesas/r8a7744-iwg20d-q7.dtb: backlight: pwms: [[58, 0, 5000000], [0]] is too long From schema: Documentation/devicetree/bindings/leds/backlight/pwm-backlight.yaml
PWM specifiers referring to R-Car PWM Timer Controllers should contain only two cells.
Fix this by dropping the bogus third cell.
Fixes: 6f89dd9e9325d05b ("ARM: dts: iwg20d-q7-common: Add LCD support") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/6e5c3167424a43faf8c1fa68d9667b3d87dc86d8.168485591... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/iwg20d-q7-common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/iwg20d-q7-common.dtsi b/arch/arm/boot/dts/iwg20d-q7-common.dtsi index bc857676d1910..c13d2f6e1a38f 100644 --- a/arch/arm/boot/dts/iwg20d-q7-common.dtsi +++ b/arch/arm/boot/dts/iwg20d-q7-common.dtsi @@ -49,7 +49,7 @@ audio_clock: audio_clock { lcd_backlight: backlight { compatible = "pwm-backlight";
- pwms = <&pwm3 0 5000000 0>; + pwms = <&pwm3 0 5000000>; brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <7>; enable-gpios = <&gpio5 14 GPIO_ACTIVE_HIGH>;
From: Wolfram Sang wsa+renesas@sang-engineering.com
[ Upstream commit 1a2c4e5635177939a088d22fa35c6a7032725663 ]
The schematics are misleading, the flow control is for HSCIF1. We need SCIF1 for GNSS/GPS which does not use flow control.
Fixes: c6c816e22bc8 ("arm64: dts: ulcb-kf: enable SCIF1") Signed-off-by: Wolfram Sang wsa+renesas@sang-engineering.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/20230525084823.4195-2-wsa+renesas@sang-engineering... Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi index 61bd4df09df0d..26cb5f14f9c7a 100644 --- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi +++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi @@ -270,7 +270,7 @@ hscif0_pins: hscif0 { };
scif1_pins: scif1 { - groups = "scif1_data_b", "scif1_ctrl"; + groups = "scif1_data_b"; function = "scif1"; };
@@ -330,7 +330,6 @@ rsnd_for_pcm3168a_capture: endpoint { &scif1 { pinctrl-0 = <&scif1_pins>; pinctrl-names = "default"; - uart-has-rtscts;
status = "okay"; };
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 79a3908d1ea6c35157a6d907b1a9d8ec06015e7a ]
If 'mipid_detect()' fails, we must free 'md' to avoid a memory leak.
Fixes: 66d2f99d0bb5 ("omapfb: add support for MIPI-DCS compatible LCDs") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/omap/lcd_mipid.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c index a75ae0c9b14c7..d1cd8785d011d 100644 --- a/drivers/video/fbdev/omap/lcd_mipid.c +++ b/drivers/video/fbdev/omap/lcd_mipid.c @@ -563,11 +563,15 @@ static int mipid_spi_probe(struct spi_device *spi)
r = mipid_detect(md); if (r < 0) - return r; + goto free_md;
omapfb_register_panel(&md->panel);
return 0; + +free_md: + kfree(md); + return r; }
static int mipid_spi_remove(struct spi_device *spi)
From: Keerthy j-keerthy@ti.com
[ Upstream commit 3d011933000ed9054c649952d83162d24f020a93 ]
wkup_pmx splits into multiple regions. Like
wkup_pmx0 -> 13 pins (WKUP_PADCONFIG 0 - 12) wkup_pmx1 -> 2 pins (WKUP_PADCONFIG 14 - 15) wkup_pmx2 -> 59 pins (WKUP_PADCONFIG 26 - 84) wkup_pmx3 -> 8 pins (WKUP_PADCONFIG 93 - 100)
With this split, pin offset needs to be adjusted to match with new pmx for all pins above wkup_pmx0.
Example a pin under wkup_pmx1 should start from 0 instead of old offset(0x38 WKUP_PADCONFIG 14 offset)
J7200 Datasheet (Table 6-106, Section 6.4 Pin Multiplexing) : https://www.ti.com/lit/ds/symlink/dra821u.pdf
Fixes: 9ae21ac445e9 ("arm64: dts: ti: k3-j7200: Fix wakeup pinmux range")
Signed-off-by: Keerthy j-keerthy@ti.com Signed-off-by: Udit Kumar u-kumar1@ti.com Link: https://lore.kernel.org/r/20230419040007.3022780-2-u-kumar1@ti.com Signed-off-by: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../dts/ti/k3-j7200-common-proc-board.dts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts index 4417fe81afd7f..ee244df75eaea 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts @@ -80,25 +80,25 @@ vdd_sd_dv: gpio-regulator-TLV71033 { &wkup_pmx2 { mcu_cpsw_pins_default: mcu-cpsw-pins-default { pinctrl-single,pins = < - J721E_WKUP_IOPAD(0x0068, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */ - J721E_WKUP_IOPAD(0x006c, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */ - J721E_WKUP_IOPAD(0x0070, PIN_OUTPUT, 0) /* MCU_RGMII1_TD3 */ - J721E_WKUP_IOPAD(0x0074, PIN_OUTPUT, 0) /* MCU_RGMII1_TD2 */ - J721E_WKUP_IOPAD(0x0078, PIN_OUTPUT, 0) /* MCU_RGMII1_TD1 */ - J721E_WKUP_IOPAD(0x007c, PIN_OUTPUT, 0) /* MCU_RGMII1_TD0 */ - J721E_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* MCU_RGMII1_RD3 */ - J721E_WKUP_IOPAD(0x008c, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */ - J721E_WKUP_IOPAD(0x0090, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */ - J721E_WKUP_IOPAD(0x0094, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */ - J721E_WKUP_IOPAD(0x0080, PIN_OUTPUT, 0) /* MCU_RGMII1_TXC */ - J721E_WKUP_IOPAD(0x0084, PIN_INPUT, 0) /* MCU_RGMII1_RXC */ + J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */ + J721E_WKUP_IOPAD(0x0004, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */ + J721E_WKUP_IOPAD(0x0008, PIN_OUTPUT, 0) /* MCU_RGMII1_TD3 */ + J721E_WKUP_IOPAD(0x000c, PIN_OUTPUT, 0) /* MCU_RGMII1_TD2 */ + J721E_WKUP_IOPAD(0x0010, PIN_OUTPUT, 0) /* MCU_RGMII1_TD1 */ + J721E_WKUP_IOPAD(0x0014, PIN_OUTPUT, 0) /* MCU_RGMII1_TD0 */ + J721E_WKUP_IOPAD(0x0020, PIN_INPUT, 0) /* MCU_RGMII1_RD3 */ + J721E_WKUP_IOPAD(0x0024, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */ + J721E_WKUP_IOPAD(0x0028, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */ + J721E_WKUP_IOPAD(0x002c, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */ + J721E_WKUP_IOPAD(0x0018, PIN_OUTPUT, 0) /* MCU_RGMII1_TXC */ + J721E_WKUP_IOPAD(0x001c, PIN_INPUT, 0) /* MCU_RGMII1_RXC */ >; };
mcu_mdio_pins_default: mcu-mdio1-pins-default { pinctrl-single,pins = < - J721E_WKUP_IOPAD(0x009c, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */ - J721E_WKUP_IOPAD(0x0098, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */ + J721E_WKUP_IOPAD(0x0034, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */ + J721E_WKUP_IOPAD(0x0030, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */ >; }; };
From: Marek Vasut marex@denx.de
[ Upstream commit e3f2778b1b6ced649bffdc7cbb05b80bb92f2108 ]
The audio routing flow is not correct, the flow should be from source (second element in the pair) to sink (first element in the pair). The flow now is from "HP_OUT" to "Playback", where "Playback" is source and "HP_OUT" is sink, i.e. the direction is swapped and there is no direct link between the two either.
Fill in the correct routing, where "HP_OUT" supplies the "Headphone Jack", "Line In Jack" supplies "LINE_IN" input, "Microphone Jack" supplies "MIC_IN" input and "Mic Bias" supplies "Microphone Jack".
Fixes: 34e0c7847dcf ("ARM: dts: stm32: Add DH Electronics DHCOM STM32MP1 SoM and PDK2 board") Signed-off-by: Marek Vasut marex@denx.de Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi index fbf3826933e4d..7c0aa59accc55 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi @@ -137,10 +137,13 @@ reg_panel_supply: regulator-panel-supply {
sound { compatible = "audio-graph-card"; - routing = - "MIC_IN", "Capture", - "Capture", "Mic Bias", - "Playback", "HP_OUT"; + widgets = "Headphone", "Headphone Jack", + "Line", "Line In Jack", + "Microphone", "Microphone Jack"; + routing = "Headphone Jack", "HP_OUT", + "LINE_IN", "Line In Jack", + "MIC_IN", "Microphone Jack", + "Microphone Jack", "Mic Bias"; dais = <&sai2a_port &sai2b_port>; status = "okay"; };
From: Olivier Moysan olivier.moysan@foss.st.com
[ Upstream commit 076c74c592cabe4a47537fe5205b5b678bed010d ]
Use "dai-format" to configure DAI audio format as specified in audio-graph-port.yaml bindings.
Fixes: 144d1ba70548 ("ARM: dts: stm32: Adapt STM32MP157 DK boards to stm32 DT diversity") Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dkx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi index 48beed0f1f30a..a76173e8a2a17 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi @@ -438,7 +438,7 @@ &i2s2 { i2s2_port: port { i2s2_endpoint: endpoint { remote-endpoint = <&sii9022_tx_endpoint>; - format = "i2s"; + dai-format = "i2s"; mclk-fs = <256>; }; };
From: Tim Harvey tharvey@gateworks.com
[ Upstream commit a6d80df47ee2c69db99e4f2f8871aa4db154620b ]
The GSC fan pwm temperature register is in centidegrees celcius but the Linux hwmon convention is to use milidegrees celcius. Fix the scaling.
Fixes: 3bce5377ef66 ("hwmon: Add Gateworks System Controller support") Signed-off-by: Tim Harvey tharvey@gateworks.com Link: https://lore.kernel.org/r/20230606153004.1448086-1-tharvey@gateworks.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/gsc-hwmon.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/gsc-hwmon.c b/drivers/hwmon/gsc-hwmon.c index f29ce49294daf..89d036bf88df7 100644 --- a/drivers/hwmon/gsc-hwmon.c +++ b/drivers/hwmon/gsc-hwmon.c @@ -82,8 +82,8 @@ static ssize_t pwm_auto_point_temp_store(struct device *dev, if (kstrtol(buf, 10, &temp)) return -EINVAL;
- temp = clamp_val(temp, 0, 10000); - temp = DIV_ROUND_CLOSEST(temp, 10); + temp = clamp_val(temp, 0, 100000); + temp = DIV_ROUND_CLOSEST(temp, 100);
regs[0] = temp & 0xff; regs[1] = (temp >> 8) & 0xff; @@ -100,7 +100,7 @@ static ssize_t pwm_auto_point_pwm_show(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)) / 100); + return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10))); }
static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point1_pwm, pwm_auto_point_pwm, 0);
From: Potin Lai potin.lai@quantatw.com
[ Upstream commit a3cd66d7cbadcc0c29884f25b754fd22699c719c ]
Current driver assume PWR_AVG and VI_AVG as 1 by default, and user needs to set sample averaging via sysfs manually.
This patch parses the properties "adi,power-sample-average" and "adi,volt-curr-sample-average" from device tree, and setting sample averaging during probe. Input value must be one of value in the list [1, 2, 4, 8, 16, 32, 64, 128].
Signed-off-by: Potin Lai potin.lai@quantatw.com Link: https://lore.kernel.org/r/20220302123817.27025-2-potin.lai@quantatw.com Signed-off-by: Guenter Roeck linux@roeck-us.net Stable-dep-of: b153a0bb4199 ("hwmon: (pmbus/adm1275) Fix problems with temperature monitoring on ADM1272") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/pmbus/adm1275.c | 40 ++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index d311e0557401c..3b07bfb43e937 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c @@ -475,6 +475,7 @@ static int adm1275_probe(struct i2c_client *client) int vindex = -1, voindex = -1, cindex = -1, pindex = -1; int tindex = -1; u32 shunt; + u32 avg;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA @@ -687,7 +688,7 @@ static int adm1275_probe(struct i2c_client *client) if ((config & (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) != (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) { config |= ADM1278_VOUT_EN | ADM1278_TEMP1_EN; - ret = i2c_smbus_write_byte_data(client, + ret = i2c_smbus_write_word_data(client, ADM1275_PMON_CONFIG, config); if (ret < 0) { @@ -756,6 +757,43 @@ static int adm1275_probe(struct i2c_client *client) return -ENODEV; }
+ if (data->have_power_sampling && + of_property_read_u32(client->dev.of_node, + "adi,power-sample-average", &avg) == 0) { + if (!avg || avg > ADM1275_SAMPLES_AVG_MAX || + BIT(__fls(avg)) != avg) { + dev_err(&client->dev, + "Invalid number of power samples"); + return -EINVAL; + } + ret = adm1275_write_pmon_config(data, client, true, + ilog2(avg)); + if (ret < 0) { + dev_err(&client->dev, + "Setting power sample averaging failed with error %d", + ret); + return ret; + } + } + + if (of_property_read_u32(client->dev.of_node, + "adi,volt-curr-sample-average", &avg) == 0) { + if (!avg || avg > ADM1275_SAMPLES_AVG_MAX || + BIT(__fls(avg)) != avg) { + dev_err(&client->dev, + "Invalid number of voltage/current samples"); + return -EINVAL; + } + ret = adm1275_write_pmon_config(data, client, false, + ilog2(avg)); + if (ret < 0) { + dev_err(&client->dev, + "Setting voltage and current sample averaging failed with error %d", + ret); + return ret; + } + } + if (voindex < 0) voindex = vindex; if (vindex >= 0) {
From: Guenter Roeck linux@roeck-us.net
[ Upstream commit b153a0bb4199566abd337119207f82b59a8cd1ca ]
The PMON_CONFIG register on ADM1272 is a 16 bit register. Writing a 8 bit value into it clears the upper 8 bits of the register, resulting in unexpected side effects. Fix by writing the 16 bit register value.
Also, it has been reported that temperature readings are sometimes widely inaccurate, to the point where readings may result in device shutdown due to errant overtemperature faults. Improve by enabling temperature sampling.
While at it, move the common code for ADM1272 and ADM1278 into a separate function, and clarify in the error message that an attempt was made to enable both VOUT and temperature monitoring.
Last but not least, return the error code reported by the underlying I2C controller and not -ENODEV if updating the PMON_CONFIG register fails. After all, this does not indicate that the chip is not present, but an error in the communication with the chip.
Fixes: 4ff0ce227a1e ("hwmon: (pmbus/adm1275) Add support for ADM1272") Fixes: 9da9c2dc57b2 ("hwmon: (adm1275) enable adm1272 temperature reporting") Signed-off-by: Guenter Roeck linux@roeck-us.net Link: https://lore.kernel.org/r/20230602213447.3557346-1-linux@roeck-us.net Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/pmbus/adm1275.c | 52 +++++++++++++++++------------------ 1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index 3b07bfb43e937..b8543c06d022a 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c @@ -37,10 +37,13 @@ enum chips { adm1075, adm1272, adm1275, adm1276, adm1278, adm1293, adm1294 };
#define ADM1272_IRANGE BIT(0)
+#define ADM1278_TSFILT BIT(15) #define ADM1278_TEMP1_EN BIT(3) #define ADM1278_VIN_EN BIT(2) #define ADM1278_VOUT_EN BIT(1)
+#define ADM1278_PMON_DEFCONFIG (ADM1278_VOUT_EN | ADM1278_TEMP1_EN | ADM1278_TSFILT) + #define ADM1293_IRANGE_25 0 #define ADM1293_IRANGE_50 BIT(6) #define ADM1293_IRANGE_100 BIT(7) @@ -462,6 +465,22 @@ static const struct i2c_device_id adm1275_id[] = { }; MODULE_DEVICE_TABLE(i2c, adm1275_id);
+/* Enable VOUT & TEMP1 if not enabled (disabled by default) */ +static int adm1275_enable_vout_temp(struct i2c_client *client, int config) +{ + int ret; + + if ((config & ADM1278_PMON_DEFCONFIG) != ADM1278_PMON_DEFCONFIG) { + config |= ADM1278_PMON_DEFCONFIG; + ret = i2c_smbus_write_word_data(client, ADM1275_PMON_CONFIG, config); + if (ret < 0) { + dev_err(&client->dev, "Failed to enable VOUT/TEMP1 monitoring\n"); + return ret; + } + } + return 0; +} + static int adm1275_probe(struct i2c_client *client) { s32 (*config_read_fn)(const struct i2c_client *client, u8 reg); @@ -615,19 +634,10 @@ static int adm1275_probe(struct i2c_client *client) PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
- /* Enable VOUT & TEMP1 if not enabled (disabled by default) */ - if ((config & (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) != - (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) { - config |= ADM1278_VOUT_EN | ADM1278_TEMP1_EN; - ret = i2c_smbus_write_byte_data(client, - ADM1275_PMON_CONFIG, - config); - if (ret < 0) { - dev_err(&client->dev, - "Failed to enable VOUT monitoring\n"); - return -ENODEV; - } - } + ret = adm1275_enable_vout_temp(client, config); + if (ret) + return ret; + if (config & ADM1278_VIN_EN) info->func[0] |= PMBUS_HAVE_VIN; break; @@ -684,19 +694,9 @@ static int adm1275_probe(struct i2c_client *client) PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
- /* Enable VOUT & TEMP1 if not enabled (disabled by default) */ - if ((config & (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) != - (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)) { - config |= ADM1278_VOUT_EN | ADM1278_TEMP1_EN; - ret = i2c_smbus_write_word_data(client, - ADM1275_PMON_CONFIG, - config); - if (ret < 0) { - dev_err(&client->dev, - "Failed to enable VOUT monitoring\n"); - return -ENODEV; - } - } + ret = adm1275_enable_vout_temp(client, config); + if (ret) + return ret;
if (config & ADM1278_VIN_EN) info->func[0] |= PMBUS_HAVE_VIN;
From: Christian Lamparter chunkeey@gmail.com
[ Upstream commit fd274b733bfdde3ca72f0fa2a37f032f3a8c402c ]
this typo was found by the dtbs_check | ports:port@5:fixed-link: 'oneOf' conditional failed, | {'speed': [[1000]], 'duplex-full': True} is not of type 'array' | 'duplex-full' does not match any of the regexes: 'pinctrl-[0-]..."
this should have been full-duplex;
Fixes: 935327a73553 ("ARM: dts: BCM5301X: Add DT for Meraki MR26") Fixes: ec88a9c344d9 ("ARM: BCM5301X: Add DT for Meraki MR32") Signed-off-by: Christian Lamparter chunkeey@gmail.com Link: https://lore.kernel.org/r/50522f45566951a9eabd22820647924cc6b4a264.168623855... Signed-off-by: Florian Fainelli florian.fainelli@broadcom.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 +- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts index 14f58033efeb9..ca2266b936ee2 100644 --- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts +++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts @@ -128,7 +128,7 @@ port@5 {
fixed-link { speed = <1000>; - duplex-full; + full-duplex; }; }; }; diff --git a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts index 577a4dc604d93..edf9910100b02 100644 --- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts +++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts @@ -212,7 +212,7 @@ port@5 {
fixed-link { speed = <1000>; - duplex-full; + full-duplex; }; }; };
From: Daniil Dulov d.dulov@aladdin.ru
[ Upstream commit cabbdea1f1861098991768d7bbf5a49ed1608213 ]
Pointer mqd_mem_obj can be deallocated in kfd_gtt_sa_allocate(). The function then returns non-zero value, which causes the second deallocation.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: d1f8f0d17d40 ("drm/amdkfd: Move non-sdma mqd allocation out of init_mqd") Signed-off-by: Daniil Dulov d.dulov@aladdin.ru Signed-off-by: Felix Kuehling Felix.Kuehling@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c index 7f4e102ff4bd3..ddaafcd7b8256 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c @@ -113,18 +113,19 @@ static struct kfd_mem_obj *allocate_mqd(struct kfd_dev *kfd, &(mqd_mem_obj->gtt_mem), &(mqd_mem_obj->gpu_addr), (void *)&(mqd_mem_obj->cpu_ptr), true); + + if (retval) { + kfree(mqd_mem_obj); + return NULL; + } } else { retval = kfd_gtt_sa_allocate(kfd, sizeof(struct v9_mqd), &mqd_mem_obj); - } - - if (retval) { - kfree(mqd_mem_obj); - return NULL; + if (retval) + return NULL; }
return mqd_mem_obj; - }
static void init_mqd(struct mqd_manager *mm, void **mqd,
From: Aurabindo Pillai aurabindo.pillai@amd.com
[ Upstream commit b18f05a0666aecd5cb19c26a8305bcfa4e9d6502 ]
[Why] When freesync video mode is enabled, switching resolution from native mode to one of the freesync video compatible modes can trigger continous artifacts on some eDP panels when running under KDE. The articating can be seen in the attached bug report.
[How] Fix this by restricting updates that require full commit by using the same checks for stream and scaling changes in the the enable pass of dm_update_crtc_state() along with the check for compatible timings for freesync vide mode.
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2162 Fixes: da5e14909776 ("drm/amd/display: Fix hang when skipping modeset") Signed-off-by: Aurabindo Pillai aurabindo.pillai@amd.com Reviewed-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++ 1 file changed, 2 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 be863af956bb0..79ac19948e7af 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -10209,6 +10209,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
/* Now check if we should set freesync video mode */ if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream && + dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) && + dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream) && is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state)) { new_crtc_state->mode_changed = false;
From: Nikita Zhandarovich n.zhandarovich@fintech.ru
[ Upstream commit 1becc57cd1a905e2aa0e1eca60d2a37744525c4a ]
Function rv740_get_decoded_reference_divider() may return 0 due to unpredictable reference divider value calculated in radeon_atom_get_clock_dividers(). This will lead to division-by-zero error once that value is used as a divider in calculating 'clk_s'. While unlikely, this issue should nonetheless be prevented so add a sanity check for such cases by testing 'decoded_ref' value against 0.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
v2: minor coding style fixes (Alex) In practice this should actually happen as the vbios should be properly populated.
Fixes: 66229b200598 ("drm/radeon/kms: add dpm support for rv7xx (v4)") Signed-off-by: Nikita Zhandarovich n.zhandarovich@fintech.ru Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/radeon/cypress_dpm.c | 8 ++++++-- drivers/gpu/drm/radeon/ni_dpm.c | 8 ++++++-- drivers/gpu/drm/radeon/rv740_dpm.c | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c index fdddbbaecbb74..72a0768df00f7 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.c +++ b/drivers/gpu/drm/radeon/cypress_dpm.c @@ -557,8 +557,12 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev, ASIC_INTERNAL_MEMORY_SS, vco_freq)) { u32 reference_clock = rdev->clock.mpll.reference_freq; u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); - u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); - u32 clk_v = ss.percentage * + u32 clk_s, clk_v; + + if (!decoded_ref) + return -EINVAL; + clk_s = reference_clock * 5 / (decoded_ref * ss.rate); + clk_v = ss.percentage * (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
mpll_ss1 &= ~CLKV_MASK; diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 672d2239293e0..3e1c1a392fb7b 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -2241,8 +2241,12 @@ static int ni_populate_mclk_value(struct radeon_device *rdev, ASIC_INTERNAL_MEMORY_SS, vco_freq)) { u32 reference_clock = rdev->clock.mpll.reference_freq; u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); - u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); - u32 clk_v = ss.percentage * + u32 clk_s, clk_v; + + if (!decoded_ref) + return -EINVAL; + clk_s = reference_clock * 5 / (decoded_ref * ss.rate); + clk_v = ss.percentage * (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
mpll_ss1 &= ~CLKV_MASK; diff --git a/drivers/gpu/drm/radeon/rv740_dpm.c b/drivers/gpu/drm/radeon/rv740_dpm.c index d57a3e1df8d63..4464fd21a3029 100644 --- a/drivers/gpu/drm/radeon/rv740_dpm.c +++ b/drivers/gpu/drm/radeon/rv740_dpm.c @@ -249,8 +249,12 @@ int rv740_populate_mclk_value(struct radeon_device *rdev, ASIC_INTERNAL_MEMORY_SS, vco_freq)) { u32 reference_clock = rdev->clock.mpll.reference_freq; u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); - u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); - u32 clk_v = 0x40000 * ss.percentage * + u32 clk_s, clk_v; + + if (!decoded_ref) + return -EINVAL; + clk_s = reference_clock * 5 / (decoded_ref * ss.rate); + clk_v = 0x40000 * ss.percentage * (dividers.whole_fb_div + (dividers.frac_fb_div / 8)) / (clk_s * 10000);
mpll_ss1 &= ~CLKV_MASK;
From: Chia-I Wu olvaffe@gmail.com
[ Upstream commit 9f0bcf49e9895cb005d78b33a5eebfa11711b425 ]
This is motivated by OOB access in amdgpu_vm_update_range when offset_in_bo+map_size overflows.
v2: keep the validations in amdgpu_vm_bo_map v3: add the validations to amdgpu_vm_bo_map/amdgpu_vm_bo_replace_map rather than to amdgpu_gem_va_ioctl
Fixes: 9f7eb5367d00 ("drm/amdgpu: actually use the VM map parameters") Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Chia-I Wu olvaffe@gmail.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 8da5cc8fcc6c0..86914bd3e09e1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2334,14 +2334,14 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, uint64_t eaddr;
/* validate the parameters */ - if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || - size == 0 || size & ~PAGE_MASK) + if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK) + return -EINVAL; + if (saddr + size <= saddr || offset + size <= offset) return -EINVAL;
/* make sure object fit at this offset */ eaddr = saddr + size - 1; - if (saddr >= eaddr || - (bo && offset + size > amdgpu_bo_size(bo)) || + if ((bo && offset + size > amdgpu_bo_size(bo)) || (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT)) return -EINVAL;
@@ -2400,14 +2400,14 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, int r;
/* validate the parameters */ - if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || - size == 0 || size & ~PAGE_MASK) + if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK) + return -EINVAL; + if (saddr + size <= saddr || offset + size <= offset) return -EINVAL;
/* make sure object fit at this offset */ eaddr = saddr + size - 1; - if (saddr >= eaddr || - (bo && offset + size > amdgpu_bo_size(bo)) || + if ((bo && offset + size > amdgpu_bo_size(bo)) || (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT)) return -EINVAL;
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 736a9327365644b460e4498b1ce172ca411efcbc ]
The commit 010c8bbad2cb ("drm: msm: adreno: Disable preemption on Adreno 510") added special handling for a510 (this SKU doesn't seem to support preemption, so the driver should clamp nr_rings to 1). However the gpu->revn is not yet set (it is set later, in adreno_gpu_init()) and thus the condition is always false. Check config->rev instead.
Fixes: 010c8bbad2cb ("drm: msm: adreno: Disable preemption on Adreno 510") Reported-by: Adam Skladowski a39.skl@gmail.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Tested-by: Adam Skladowski a39.skl@gmail.com Patchwork: https://patchwork.freedesktop.org/patch/531511/ Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index d92416d526286..ef62900b06128 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1746,6 +1746,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; + struct adreno_platform_config *config = pdev->dev.platform_data; struct a5xx_gpu *a5xx_gpu = NULL; struct adreno_gpu *adreno_gpu; struct msm_gpu *gpu; @@ -1772,7 +1773,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
nr_rings = 4;
- if (adreno_is_a510(adreno_gpu)) + if (adreno_cmp_rev(ADRENO_REV(5, 1, 0, ANY_ID), config->rev)) nr_rings = 1;
ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, nr_rings);
From: Kashyap Desai kashyap.desai@broadcom.com
[ Upstream commit 0af91306e17ef3d18e5f100aa58aa787869118af ]
Driver is not handling the wraparound of the mbox producer index correctly. Currently the wraparound happens once u32 max is reached.
Bit 31 of the producer index register is special and should be set only once for the first command. Because the producer index overflow setting bit31 after a long time, FW goes to initialization sequence and this causes FW hang.
Fix is to wraparound the mbox producer index once it reaches u16 max.
Fixes: cee0c7bba486 ("RDMA/bnxt_re: Refactor command queue management code") Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Signed-off-by: Kashyap Desai kashyap.desai@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Link: https://lore.kernel.org/r/1686308514-11996-2-git-send-email-selvin.xavier@br... Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index d72f36d2bd496..abeee7cc7dc6d 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -181,7 +181,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, struct cmdq_base *req, } while (size > 0); cmdq->seq_num++;
- cmdq_prod = hwq->prod; + cmdq_prod = hwq->prod & 0xFFFF; if (test_bit(FIRMWARE_FIRST_FLAG, &cmdq->flags)) { /* The very first doorbell write * is required to set this flag @@ -599,7 +599,7 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res, rcfw->cmdq_depth = BNXT_QPLIB_CMDQE_MAX_CNT_8192;
sginfo.pgsize = bnxt_qplib_cmdqe_page_size(rcfw->cmdq_depth); - hwq_attr.depth = rcfw->cmdq_depth; + hwq_attr.depth = rcfw->cmdq_depth & 0x7FFFFFFF; hwq_attr.stride = BNXT_QPLIB_CMDQE_UNITS; hwq_attr.type = HWQ_TYPE_CTX; if (bnxt_qplib_alloc_init_hwq(&cmdq->hwq, &hwq_attr)) {
From: Kashyap Desai kashyap.desai@broadcom.com
[ Upstream commit 3099bcdc19b701f732f638ee45679858c08559bb ]
bnxt_qplib_service_creq can be called from interrupt or tasklet or process context. So the function take irq variant of spin_lock. But when wake_up is invoked with the lock held, it is putting the calling context to sleep.
[exception RIP: __wake_up_common+190] RIP: ffffffffb7539d7e RSP: ffffa73300207ad8 RFLAGS: 00000083 RAX: 0000000000000001 RBX: ffff91fa295f69b8 RCX: dead000000000200 RDX: ffffa733344af940 RSI: ffffa73336527940 RDI: ffffa73336527940 RBP: 000000000000001c R8: 0000000000000002 R9: 00000000000299c0 R10: 0000017230de82c5 R11: 0000000000000002 R12: ffffa73300207b28 R13: 0000000000000000 R14: ffffa733341bf928 R15: 0000000000000000 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
Call the wakeup after releasing the lock.
Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Signed-off-by: Kashyap Desai kashyap.desai@broadcom.com Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Link: https://lore.kernel.org/r/1686308514-11996-3-git-send-email-selvin.xavier@br... Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index abeee7cc7dc6d..3b8cb46551bf2 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -299,7 +299,8 @@ static int bnxt_qplib_process_func_event(struct bnxt_qplib_rcfw *rcfw, }
static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, - struct creq_qp_event *qp_event) + struct creq_qp_event *qp_event, + u32 *num_wait) { struct creq_qp_error_notification *err_event; struct bnxt_qplib_hwq *hwq = &rcfw->cmdq.hwq; @@ -308,6 +309,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, u16 cbit, blocked = 0; struct pci_dev *pdev; unsigned long flags; + u32 wait_cmds = 0; __le16 mcookie; u16 cookie; int rc = 0; @@ -367,9 +369,10 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, crsqe->req_size = 0;
if (!blocked) - wake_up(&rcfw->cmdq.waitq); + wait_cmds++; spin_unlock_irqrestore(&hwq->lock, flags); } + *num_wait += wait_cmds; return rc; }
@@ -383,6 +386,7 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t) struct creq_base *creqe; u32 sw_cons, raw_cons; unsigned long flags; + u32 num_wakeup = 0;
/* Service the CREQ until budget is over */ spin_lock_irqsave(&hwq->lock, flags); @@ -401,7 +405,8 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t) switch (type) { case CREQ_BASE_TYPE_QP_EVENT: bnxt_qplib_process_qp_event - (rcfw, (struct creq_qp_event *)creqe); + (rcfw, (struct creq_qp_event *)creqe, + &num_wakeup); creq->stats.creq_qp_event_processed++; break; case CREQ_BASE_TYPE_FUNC_EVENT: @@ -429,6 +434,8 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t) rcfw->res->cctx, true); } spin_unlock_irqrestore(&hwq->lock, flags); + if (num_wakeup) + wake_up_nr(&rcfw->cmdq.waitq, num_wakeup); }
static irqreturn_t bnxt_qplib_creq_irq(int irq, void *dev_instance)
From: Hao Luo m202171776@hust.edu.cn
[ Upstream commit 188d070de9132667956f5aadd98d2bd87d3eac89 ]
Use devm_of_iomap() instead of of_iomap() to automatically handle the unused ioremap region.
If any error occurs, regions allocated by kzalloc() will leak, but using devm_kzalloc() instead will automatically free the memory using devm_kfree().
Fixes: daeb14545514 ("clk: imx: imx8mn: Switch to clk_hw based API") Fixes: 96d6392b54db ("clk: imx: Add support for i.MX8MN clock driver") Signed-off-by: Hao Luo m202171776@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Reviewed-by: Peng Fan peng.fan@nxp.com Link: https://lore.kernel.org/r/20230411015107.2645-1-m202171776@hust.edu.cn Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-imx8mn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 52903146fdbaf..4499da4154f06 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -299,7 +299,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) void __iomem *base; int ret;
- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MN_CLK_END), GFP_KERNEL); if (WARN_ON(!clk_hw_data)) return -ENOMEM; @@ -316,10 +316,10 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4");
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop"); - base = of_iomap(np, 0); + base = devm_of_iomap(dev, np, 0, NULL); of_node_put(np); - if (WARN_ON(!base)) { - ret = -ENOMEM; + if (WARN_ON(IS_ERR(base))) { + ret = PTR_ERR(base); goto unregister_hws; }
From: Yuxing Liu lyx2022@hust.edu.cn
[ Upstream commit 878b02d5f3b56cb090dbe2c70c89273be144087f ]
Replace of_iomap() and kzalloc() with devm_of_iomap() and devm_kzalloc() which can automatically release the related memory when the device or driver is removed or unloaded to avoid potential memory leak.
In this case, iounmap(anatop_base) in line 427,433 are removed as manual release is not required.
Besides, referring to clk-imx8mq.c, check the return code of of_clk_add_hw_provider, if it returns negtive, print error info and unregister hws, which makes the program more robust.
Fixes: 9c140d992676 ("clk: imx: Add support for i.MX8MP clock driver") Signed-off-by: Yuxing Liu lyx2022@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/20230503070607.2462-1-lyx2022@hust.edu.cn Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-imx8mp.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index b173c30093946..0191457fb3cfc 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -407,25 +407,22 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np; void __iomem *anatop_base, *ccm_base; + int err;
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop"); - anatop_base = of_iomap(np, 0); + anatop_base = devm_of_iomap(dev, np, 0, NULL); of_node_put(np); - if (WARN_ON(!anatop_base)) - return -ENOMEM; + if (WARN_ON(IS_ERR(anatop_base))) + return PTR_ERR(anatop_base);
np = dev->of_node; ccm_base = devm_platform_ioremap_resource(pdev, 0); - if (WARN_ON(IS_ERR(ccm_base))) { - iounmap(anatop_base); + if (WARN_ON(IS_ERR(ccm_base))) return PTR_ERR(ccm_base); - }
- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL); - if (WARN_ON(!clk_hw_data)) { - iounmap(anatop_base); + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL); + if (WARN_ON(!clk_hw_data)) return -ENOMEM; - }
clk_hw_data->num = IMX8MP_CLK_END; hws = clk_hw_data->hws; @@ -710,7 +707,12 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
imx_check_clk_hws(hws, IMX8MP_CLK_END);
- of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); + err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); + if (err < 0) { + dev_err(dev, "failed to register hws for i.MX8MP\n"); + imx_unregister_hw_clocks(hws, IMX8MP_CLK_END); + return err; + }
imx_register_uart_clocks(4);
From: Marijn Suijten marijn.suijten@somainline.org
[ Upstream commit 223ce29c8b7e5b00f01a68387aabeefd77d97f06 ]
The framebuffer configuration for edo pdx203, written in edo dtsi (which is overwritten in pdx206 dts for its smaller panel) has to use a 1096x2560 configuration as this is what the panel (and framebuffer area) has been initialized to. Downstream userspace also has access to (and uses) this 2.5k mode by default, and only switches the panel to 4k when requested.
This is similar to commit be8de06dc397 ("arm64: dts: qcom: sm8150-kumano: Panel framebuffer is 2.5k instead of 4k") which fixed the same for the previous generation Sony platform.
Fixes: 69cdb97ef652 ("arm64: dts: qcom: sm8250: Add support for SONY Xperia 1 II / 5 II (Edo platform)") Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230606211418.587676-1-marijn.suijten@somainline.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi index effbd6a9c9891..b093f2a02a9cb 100644 --- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi @@ -26,9 +26,10 @@ chosen { framebuffer: framebuffer@9c000000 { compatible = "simple-framebuffer"; reg = <0 0x9c000000 0 0x2300000>; - width = <1644>; - height = <3840>; - stride = <(1644 * 4)>; + /* pdx203 BL initializes in 2.5k mode, not 4k */ + width = <1096>; + height = <2560>; + stride = <(1096 * 4)>; format = "a8r8g8b8"; /* * That's a lot of clocks, but it's necessary due
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit 9c632a6396505a019ea6d12b5ab45e659a542a93 ]
Smatch detected this potential error pointer dereference clk_wzrd_register_divider(). If devm_clk_hw_register() fails then it sets "hw" to an error pointer and then dereferences it on the next line. Return the error directly instead.
Fixes: 5a853722eb32 ("staging: clocking-wizard: Add support for dynamic reconfiguration") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Link: https://lore.kernel.org/r/f0e39b5c-4554-41e0-80d9-54ca3fabd060@kili.mountain Reviewed-by: Michal Simek michal.simek@amd.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c index 39367712ef540..8c1934df70dea 100644 --- a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c +++ b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c @@ -347,7 +347,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev, hw = &div->hw; ret = devm_clk_hw_register(dev, hw); if (ret) - hw = ERR_PTR(ret); + return ERR_PTR(ret);
return hw->clk; }
From: Yuan Can yuancan@huawei.com
[ Upstream commit 53a06e5924c0d43c11379a08c5a78529c3e61595 ]
The tegra and tegra needs to be freed in the error handling path, otherwise it will be leaked.
Fixes: 2db04f16b589 ("clk: tegra: Add EMC clock driver") Signed-off-by: Yuan Can yuancan@huawei.com Link: https://lore.kernel.org/r/20221209094124.71043-1-yuancan@huawei.com Acked-by: Thierry Reding treding@nvidia.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/tegra/clk-tegra124-emc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c index 219c80653dbdb..2a6db04342815 100644 --- a/drivers/clk/tegra/clk-tegra124-emc.c +++ b/drivers/clk/tegra/clk-tegra124-emc.c @@ -464,6 +464,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra, err = load_one_timing_from_dt(tegra, timing, child); if (err) { of_node_put(child); + kfree(tegra->timings); return err; }
@@ -515,6 +516,7 @@ struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np err = load_timings_from_dt(tegra, node, node_ram_code); if (err) { of_node_put(node); + kfree(tegra); return ERR_PTR(err); } }
From: Su Hui suhui@nfschina.com
[ Upstream commit 79597c8bf64ca99eab385115743131d260339da5 ]
smatch error: sound/pci/ac97/ac97_codec.c:2354 snd_ac97_mixer() error: we previously assumed 'rac97' could be null (see line 2072)
remove redundant assignment, return error if rac97 is NULL.
Fixes: da3cec35dd3c ("ALSA: Kill snd_assert() in sound/pci/*") Signed-off-by: Su Hui suhui@nfschina.com Link: https://lore.kernel.org/r/20230615021732.1972194-1-suhui@nfschina.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/ac97/ac97_codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index ceead55f13ab1..58ae0c3ce1e49 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -2070,8 +2070,8 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, .dev_disconnect = snd_ac97_dev_disconnect, };
- if (rac97) - *rac97 = NULL; + if (!rac97) + return -EINVAL; if (snd_BUG_ON(!bus || !template)) return -EINVAL; if (snd_BUG_ON(template->num >= 4))
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 3bcfc7b90465efd337d39b91b43972162f0d1908 ]
We can not support color management without DSPP blocks being provided in the HW catalog. Do not enable color management for CRTCs if num_dspps is 0.
Fixes: 4259ff7ae509 ("drm/msm/dpu: add support for pcc color block in dpu driver") Reported-by: Yongqin Liu yongqin.liu@linaro.org Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-by: Sumit Semwal sumit.semwal@linaro.org Tested-by: Yongqin Liu yongqin.liu@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/542141/ Link: https://lore.kernel.org/r/20230612182534.3345805-1-dmitry.baryshkov@linaro.o... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 4194689b6b35d..8be941c9b6a94 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1380,6 +1380,8 @@ static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = { struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, struct drm_plane *cursor) { + struct msm_drm_private *priv = dev->dev_private; + struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); struct drm_crtc *crtc = NULL; struct dpu_crtc *dpu_crtc = NULL; int i; @@ -1411,7 +1413,8 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs);
- drm_crtc_enable_color_mgmt(crtc, 0, true, 0); + if (dpu_kms->catalog->dspp_count) + drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
/* save user friendly CRTC name for later */ snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
From: Bjorn Andersson quic_bjorande@quicinc.com
[ Upstream commit fa0048a4b1fa7a50c8b0e514f5b428abdf69a6f8 ]
The DP component's unbind operation walks through the submodules to unregister and clean things up. But if the unbind happens because the DP controller itself is being removed, all the memory for those submodules has just been freed.
Change the order of these operations to avoid the many use-after-free that otherwise happens in this code path.
Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support") Signed-off-by: Bjorn Andersson quic_bjorande@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/542166/ Link: https://lore.kernel.org/r/20230612220259.1884381-1-quic_bjorande@quicinc.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 38d37345c216b..bbe350fab797c 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1295,9 +1295,9 @@ static int dp_display_remove(struct platform_device *pdev) dp = container_of(g_dp_display, struct dp_display_private, dp_display);
+ component_del(&pdev->dev, &dp_display_comp_ops); dp_display_deinit_sub_modules(dp);
- component_del(&pdev->dev, &dp_display_comp_ops); platform_set_drvdata(pdev, NULL);
return 0;
From: Allen-KH Cheng allen-kh.cheng@mediatek.com
[ Upstream commit 9d498cce9298a71e3896e2d1aee24a1a4c531d81 ]
Add the cpufreq nodes for MT8192 SoC.
Signed-off-by: Allen-KH Cheng allen-kh.cheng@mediatek.com Tested-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: Nícolas F. R. A. Prado nfraprado@collabora.com Tested-by: Nícolas F. R. A. Prado nfraprado@collabora.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Tested-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20230317061944.15434-1-allen-kh.cheng@mediatek.com Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Stable-dep-of: a4366b5695c9 ("arm64: dts: mediatek: mt8192: Fix CPUs capacity-dmips-mhz") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/mediatek/mt8192.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi index 9ed1a72295747..19ba781729722 100644 --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi @@ -41,6 +41,7 @@ cpu0: cpu@0 { clock-frequency = <1701000000>; cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; + performance-domains = <&performance 0>; capacity-dmips-mhz = <530>; };
@@ -52,6 +53,7 @@ cpu1: cpu@100 { clock-frequency = <1701000000>; cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; + performance-domains = <&performance 0>; capacity-dmips-mhz = <530>; };
@@ -63,6 +65,7 @@ cpu2: cpu@200 { clock-frequency = <1701000000>; cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; + performance-domains = <&performance 0>; capacity-dmips-mhz = <530>; };
@@ -74,6 +77,7 @@ cpu3: cpu@300 { clock-frequency = <1701000000>; cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; + performance-domains = <&performance 0>; capacity-dmips-mhz = <530>; };
@@ -85,6 +89,7 @@ cpu4: cpu@400 { clock-frequency = <2171000000>; cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>; next-level-cache = <&l2_1>; + performance-domains = <&performance 1>; capacity-dmips-mhz = <1024>; };
@@ -96,6 +101,7 @@ cpu5: cpu@500 { clock-frequency = <2171000000>; cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>; next-level-cache = <&l2_1>; + performance-domains = <&performance 1>; capacity-dmips-mhz = <1024>; };
@@ -107,6 +113,7 @@ cpu6: cpu@600 { clock-frequency = <2171000000>; cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>; next-level-cache = <&l2_1>; + performance-domains = <&performance 1>; capacity-dmips-mhz = <1024>; };
@@ -118,6 +125,7 @@ cpu7: cpu@700 { clock-frequency = <2171000000>; cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>; next-level-cache = <&l2_1>; + performance-domains = <&performance 1>; capacity-dmips-mhz = <1024>; };
@@ -234,6 +242,12 @@ soc { compatible = "simple-bus"; ranges;
+ performance: performance-controller@11bc10 { + compatible = "mediatek,cpufreq-hw"; + reg = <0 0x0011bc10 0 0x120>, <0 0x0011bd30 0 0x120>; + #performance-domain-cells = <1>; + }; + gic: interrupt-controller@c000000 { compatible = "arm,gic-v3"; #interrupt-cells = <4>;
From: Nícolas F. R. A. Prado nfraprado@collabora.com
[ Upstream commit a4366b5695c984b8a3fc8b31de9e758c8f6d1aed ]
The capacity-dmips-mhz parameter was miscalculated: this SoC runs the first (Cortex-A55) cluster at a maximum of 2000MHz and the second (Cortex-A76) cluster at a maximum of 2200MHz.
In order to calculate the right capacity-dmips-mhz, the following test was performed: 1. CPUFREQ governor was set to 'performance' on both clusters 2. Ran dhrystone with 500000000 iterations for 10 times on each cluster 3. Calculated the mean result for each cluster 4. Calculated DMIPS/MHz: dmips_mhz = dmips_per_second / cpu_mhz 5. Scaled results to 1024: result_c0 = dmips_mhz_c0 / dmips_mhz_c1 * 1024
The mean results for this SoC are: Cluster 0 (LITTLE): 12016411 Dhry/s Cluster 1 (BIG): 31702034 Dhry/s
The calculated scaled results are: Cluster 0: 426.953226899238 (rounded to 427) Cluster 1: 1024
Fixes: 48489980e27e ("arm64: dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile") Signed-off-by: Nícolas F. R. A. Prado nfraprado@collabora.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20230602183515.3778780-1-nfraprado@collabora.com Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/mediatek/mt8192.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi index 19ba781729722..72f444405ebfe 100644 --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi @@ -42,7 +42,7 @@ cpu0: cpu@0 { cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; performance-domains = <&performance 0>; - capacity-dmips-mhz = <530>; + capacity-dmips-mhz = <427>; };
cpu1: cpu@100 { @@ -54,7 +54,7 @@ cpu1: cpu@100 { cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; performance-domains = <&performance 0>; - capacity-dmips-mhz = <530>; + capacity-dmips-mhz = <427>; };
cpu2: cpu@200 { @@ -66,7 +66,7 @@ cpu2: cpu@200 { cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; performance-domains = <&performance 0>; - capacity-dmips-mhz = <530>; + capacity-dmips-mhz = <427>; };
cpu3: cpu@300 { @@ -78,7 +78,7 @@ cpu3: cpu@300 { cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; performance-domains = <&performance 0>; - capacity-dmips-mhz = <530>; + capacity-dmips-mhz = <427>; };
cpu4: cpu@400 {
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 9a6c13b847d61b0c3796820ca6e976789df59cd8 ]
Each MERGE_3D block has just two registers. Correct the block length accordingly.
Fixes: 4369c93cf36b ("drm/msm/dpu: initial support for merge3D hardware block") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Patchwork: https://patchwork.freedesktop.org/patch/542177/ Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Link: https://lore.kernel.org/r/20230613001004.3426676-3-dmitry.baryshkov@linaro.o... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 951aa1aafa96a..272a3d7e1aef2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -808,7 +808,7 @@ static const struct dpu_pingpong_cfg sm8150_pp[] = { #define MERGE_3D_BLK(_name, _id, _base) \ {\ .name = _name, .id = _id, \ - .base = _base, .len = 0x100, \ + .base = _base, .len = 0x8, \ .features = MERGE_3D_SM8150_MASK, \ .sblk = NULL \ }
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 144601f6228de5598f03e693822b60a95c367a17 ]
kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: f491276a5168 ("clk: vc5: Allow Versaclock driver to support multiple instances") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-2-claudiu.beznea@microchip.... Reviewed-by: Luca Ceresoli luca.ceresoli@bootlin.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-versaclock5.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index 5f8bd49b0810c..c52f02471bb4f 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -992,6 +992,11 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) }
init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } + init.ops = &vc5_mux_ops; init.flags = 0; init.parent_names = parent_names; @@ -1006,6 +1011,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_dbl_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1021,6 +1030,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Register PFD */ memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_pfd_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1038,6 +1051,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Register PLL */ memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_pll_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1057,6 +1074,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d", client->dev.of_node, idx); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_fod_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1075,6 +1096,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb", client->dev.of_node); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_clk_out_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names; @@ -1101,6 +1126,10 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) memset(&init, 0, sizeof(init)); init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d", client->dev.of_node, idx + 1); + if (!init.name) { + ret = -ENOMEM; + goto err_clk; + } init.ops = &vc5_clk_out_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = parent_names;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit bb7d09ddbf361d51eae46f38e7c8a2b85914ea2a ]
kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: 19fbbbbcd3a3 ("Add TI CDCE925 I2C controlled clock synthesizer driver") Depends-on: e665f029a283 ("clk: Convert to using %pOFn instead of device_node.name") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-3-claudiu.beznea@microchip.... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-cdce925.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c index 308b353815e17..470d91d7314db 100644 --- a/drivers/clk/clk-cdce925.c +++ b/drivers/clk/clk-cdce925.c @@ -705,6 +705,10 @@ static int cdce925_probe(struct i2c_client *client, for (i = 0; i < data->chip_info->num_plls; ++i) { pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d", client->dev.of_node, i); + if (!pll_clk_name[i]) { + err = -ENOMEM; + goto error; + } init.name = pll_clk_name[i]; data->pll[i].chip = data; data->pll[i].hw.init = &init; @@ -746,6 +750,10 @@ static int cdce925_probe(struct i2c_client *client, init.num_parents = 1; init.parent_names = &parent_name; /* Mux Y1 to input */ init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node); + if (!init.name) { + err = -ENOMEM; + goto error; + } data->clk[0].chip = data; data->clk[0].hw.init = &init; data->clk[0].index = 0; @@ -764,6 +772,10 @@ static int cdce925_probe(struct i2c_client *client, for (i = 1; i < data->chip_info->num_outputs; ++i) { init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d", client->dev.of_node, i+1); + if (!init.name) { + err = -ENOMEM; + goto error; + } data->clk[i].chip = data; data->clk[i].hw.init = &init; data->clk[i].index = i;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 2560114c06d7a752b3f4639f28cece58fed11267 ]
In case devm_clk_hw_register() fails for one of synth clocks the probe continues. Later on, when registering output clocks which have as parents all the synth clocks, in case there is registration failure for at least one synth clock the information passed to clk core for registering output clock is not right: init.num_parents is fixed but init.parents may contain an array with less parents.
Fixes: 3044a860fd09 ("clk: Add Si5341/Si5340 driver") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-4-claudiu.beznea@microchip.... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-si5341.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 4de098b6b0d4e..883a49a0805c9 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -1554,7 +1554,7 @@ static int si5341_probe(struct i2c_client *client, struct clk_init_data init; struct clk *input; const char *root_clock_name; - const char *synth_clock_names[SI5341_NUM_SYNTH]; + const char *synth_clock_names[SI5341_NUM_SYNTH] = { NULL }; int err; unsigned int i; struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS]; @@ -1706,6 +1706,7 @@ static int si5341_probe(struct i2c_client *client, if (err) { dev_err(&client->dev, "synth N%u registration failed\n", i); + goto free_clk_names; } }
@@ -1783,16 +1784,17 @@ static int si5341_probe(struct i2c_client *client, goto cleanup; }
+free_clk_names: /* Free the names, clk framework makes copies */ for (i = 0; i < data->num_synth; ++i) devm_kfree(&client->dev, (void *)synth_clock_names[i]);
- return 0; - cleanup: - for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { - if (data->clk[i].vddo_reg) - regulator_disable(data->clk[i].vddo_reg); + if (err) { + for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { + if (data->clk[i].vddo_reg) + regulator_disable(data->clk[i].vddo_reg); + } } return err; }
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 36e4ef82016a2b785cf2317eade77e76699b7bff ]
{devm_}kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: 3044a860fd09 ("clk: Add Si5341/Si5340 driver") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-5-claudiu.beznea@microchip.... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-si5341.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 883a49a0805c9..4bcfb38cfbebe 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -1698,6 +1698,10 @@ static int si5341_probe(struct i2c_client *client, for (i = 0; i < data->num_synth; ++i) { synth_clock_names[i] = devm_kasprintf(&client->dev, GFP_KERNEL, "%s.N%u", client->dev.of_node->name, i); + if (!synth_clock_names[i]) { + err = -ENOMEM; + goto free_clk_names; + } init.name = synth_clock_names[i]; data->synth[i].index = i; data->synth[i].data = data; @@ -1716,6 +1720,10 @@ static int si5341_probe(struct i2c_client *client, for (i = 0; i < data->num_outputs; ++i) { init.name = kasprintf(GFP_KERNEL, "%s.%d", client->dev.of_node->name, i); + if (!init.name) { + err = -ENOMEM; + goto free_clk_names; + } init.flags = config[i].synth_master ? CLK_SET_RATE_PARENT : 0; data->clk[i].index = i; data->clk[i].data = data;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 267ad94b13c53d8c99a336f0841b1fa1595b1d0f ]
Pointers from synth_clock_names[] should be freed at the end of probe either on probe success or failure path.
Fixes: b7bbf6ec4940 ("clk: si5341: Allow different output VDD_SEL values") Fixes: 9b13ff4340df ("clk: si5341: Add sysfs properties to allow checking/resetting device faults") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-6-claudiu.beznea@microchip.... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-si5341.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 4bcfb38cfbebe..91a6bc74ebd5a 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -1745,7 +1745,7 @@ static int si5341_probe(struct i2c_client *client, if (err) { dev_err(&client->dev, "output %u registration failed\n", i); - goto cleanup; + goto free_clk_names; } if (config[i].always_on) clk_prepare(data->clk[i].hw.clk); @@ -1755,7 +1755,7 @@ static int si5341_probe(struct i2c_client *client, data); if (err) { dev_err(&client->dev, "unable to add clk provider\n"); - goto cleanup; + goto free_clk_names; }
if (initialization_required) { @@ -1763,11 +1763,11 @@ static int si5341_probe(struct i2c_client *client, regcache_cache_only(data->regmap, false); err = regcache_sync(data->regmap); if (err < 0) - goto cleanup; + goto free_clk_names;
err = si5341_finalize_defaults(data); if (err < 0) - goto cleanup; + goto free_clk_names; }
/* wait for device to report input clock present and PLL lock */ @@ -1776,21 +1776,19 @@ static int si5341_probe(struct i2c_client *client, 10000, 250000); if (err) { dev_err(&client->dev, "Error waiting for input clock or PLL lock\n"); - goto cleanup; + goto free_clk_names; }
/* clear sticky alarm bits from initialization */ err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0); if (err) { dev_err(&client->dev, "unable to clear sticky status\n"); - goto cleanup; + goto free_clk_names; }
err = sysfs_create_files(&client->dev.kobj, si5341_attributes); - if (err) { + if (err) dev_err(&client->dev, "unable to create sysfs files\n"); - goto cleanup; - }
free_clk_names: /* Free the names, clk framework makes copies */
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit b73ed981da6d25c921aaefa7ca3df85bbd85b7fc ]
kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: b745c0794e2f ("clk: keystone: Add sci-clk driver support") Depends-on: 96488c09b0f4 ("clk: keystone: sci-clk: cut down the clock name length") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-7-claudiu.beznea@microchip.... Reviewed-by: Tony Lindgren tony@atomide.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/keystone/sci-clk.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c index 7e1b136e71ae0..8af2a9faa805a 100644 --- a/drivers/clk/keystone/sci-clk.c +++ b/drivers/clk/keystone/sci-clk.c @@ -302,6 +302,8 @@ static int _sci_clk_build(struct sci_clk_provider *provider,
name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id, sci_clk->clk_id); + if (!name) + return -ENOMEM;
init.name = name;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit bd46cd0b802d9c9576ca78007aa084ae3e74907b ]
kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: 852049594b9a ("clk: ti: clkctrl: convert subclocks to use proper names also") Fixes: 6c3090520554 ("clk: ti: clkctrl: Fix hidden dependency to node name") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230530093913.1656095-8-claudiu.beznea@microchip.... Reviewed-by: Tony Lindgren tony@atomide.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/ti/clkctrl.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 864c484bde1b4..157abc46dcf44 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -267,6 +267,9 @@ static const char * __init clkctrl_get_clock_name(struct device_node *np, if (clkctrl_name && !legacy_naming) { clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d", clkctrl_name, offset, index); + if (!clock_name) + return NULL; + strreplace(clock_name, '_', '-');
return clock_name; @@ -598,6 +601,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) if (clkctrl_name) { provider->clkdm_name = kasprintf(GFP_KERNEL, "%s_clkdm", clkctrl_name); + if (!provider->clkdm_name) { + kfree(provider); + return; + } goto clkdm_found; }
From: Alexey Romanov avromanov@sberdevices.ru
[ Upstream commit 0bb4644d583789c97e74d3e3047189f0c59c4742 ]
Starting from commit e45f243409db ("firmware: meson_sm: populate platform devices from sm device tree data") pwrc is probed successfully and disables unused pwr domains. By A1 SoC family design, any TEE requires DMA pwr domain always enabled.
Fixes: b3dde5013e13 ("soc: amlogic: Add support for Secure power domains controller") Signed-off-by: Alexey Romanov avromanov@sberdevices.ru Acked-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20230610090414.90529-1-avromanov@sberdevices.ru [narmstrong: added fixes tag] Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/amlogic/meson-secure-pwrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/amlogic/meson-secure-pwrc.c b/drivers/soc/amlogic/meson-secure-pwrc.c index 2eeea5e1b3b7f..2f3ca5531fa96 100644 --- a/drivers/soc/amlogic/meson-secure-pwrc.c +++ b/drivers/soc/amlogic/meson-secure-pwrc.c @@ -104,7 +104,7 @@ static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = { SEC_PD(ACODEC, 0), SEC_PD(AUDIO, 0), SEC_PD(OTP, 0), - SEC_PD(DMA, 0), + SEC_PD(DMA, GENPD_FLAG_ALWAYS_ON | GENPD_FLAG_IRQ_SAFE), SEC_PD(SD_EMMC, 0), SEC_PD(RAMA, 0), /* SRAMB is used as ATF runtime memory, and should be always on */
From: Amir Goldstein amir73il@gmail.com
[ Upstream commit b07d5cc93e1b28df47a72c519d09d0a836043613 ]
After copy up, we may need to update d_flags if upper dentry is on a remote fs and lower dentries are not.
Add helpers to allow incremental update of the revalidate flags.
Fixes: bccece1ead36 ("ovl: allow remote upper") Reviewed-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/overlayfs/copy_up.c | 2 ++ fs/overlayfs/dir.c | 3 +-- fs/overlayfs/export.c | 3 +-- fs/overlayfs/namei.c | 3 +-- fs/overlayfs/overlayfs.h | 6 ++++-- fs/overlayfs/super.c | 2 +- fs/overlayfs/util.c | 24 ++++++++++++++++++++---- 7 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index ef0bf98b620d7..46cc429c44f7e 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -542,6 +542,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c) /* Restore timestamps on parent (best effort) */ ovl_set_timestamps(upperdir, &c->pstat); ovl_dentry_set_upper_alias(c->dentry); + ovl_dentry_update_reval(c->dentry, upper); } } inode_unlock(udir); @@ -840,6 +841,7 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) inode_unlock(udir);
ovl_dentry_set_upper_alias(c->dentry); + ovl_dentry_update_reval(c->dentry, ovl_dentry_upper(c->dentry)); }
out: diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index eca984d6484d1..519193ce7d575 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -267,8 +267,7 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,
ovl_dir_modified(dentry->d_parent, false); ovl_dentry_set_upper_alias(dentry); - ovl_dentry_update_reval(dentry, newdentry, - DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE); + ovl_dentry_init_reval(dentry, newdentry);
if (!hardlink) { /* diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c index 0cc14ce8c7e83..baa50ece0bc53 100644 --- a/fs/overlayfs/export.c +++ b/fs/overlayfs/export.c @@ -326,8 +326,7 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb, if (upper_alias) ovl_dentry_set_upper_alias(dentry);
- ovl_dentry_update_reval(dentry, upper, - DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE); + ovl_dentry_init_reval(dentry, upper);
return d_instantiate_anon(dentry, inode);
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index 1a9b515fc45d4..9c055d11a95de 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -1103,8 +1103,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ovl_set_flag(OVL_UPPERDATA, inode); }
- ovl_dentry_update_reval(dentry, upperdentry, - DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE); + ovl_dentry_init_reval(dentry, upperdentry);
revert_creds(old_cred); if (origin_path) { diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index ae4876da2ced2..a96b67586f817 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -286,8 +286,10 @@ bool ovl_index_all(struct super_block *sb); bool ovl_verify_lower(struct super_block *sb); struct ovl_entry *ovl_alloc_entry(unsigned int numlower); bool ovl_dentry_remote(struct dentry *dentry); -void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry, - unsigned int mask); +void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *realdentry); +void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry); +void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry, + unsigned int mask); bool ovl_dentry_weird(struct dentry *dentry); enum ovl_path_type ovl_path_type(struct dentry *dentry); void ovl_path_upper(struct dentry *dentry, struct path *path); diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index b3675d13c1ac2..5310271cf2e38 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -1965,7 +1965,7 @@ static struct dentry *ovl_get_root(struct super_block *sb, ovl_dentry_set_flag(OVL_E_CONNECTED, root); ovl_set_upperdata(d_inode(root)); ovl_inode_init(d_inode(root), &oip, ino, fsid); - ovl_dentry_update_reval(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE); + ovl_dentry_init_flags(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE);
return root; } diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 9d33ce385bef0..d62d5ede60dfd 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -94,14 +94,30 @@ struct ovl_entry *ovl_alloc_entry(unsigned int numlower) return oe; }
+#define OVL_D_REVALIDATE (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE) + bool ovl_dentry_remote(struct dentry *dentry) { - return dentry->d_flags & - (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE); + return dentry->d_flags & OVL_D_REVALIDATE; +} + +void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *realdentry) +{ + if (!ovl_dentry_remote(realdentry)) + return; + + spin_lock(&dentry->d_lock); + dentry->d_flags |= realdentry->d_flags & OVL_D_REVALIDATE; + spin_unlock(&dentry->d_lock); +} + +void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry) +{ + return ovl_dentry_init_flags(dentry, upperdentry, OVL_D_REVALIDATE); }
-void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry, - unsigned int mask) +void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry, + unsigned int mask) { struct ovl_entry *oe = OVL_E(dentry); unsigned int i, flags = 0;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 2f76e1d6ca524a888d29aafe29f2ad2003857971 ]
devm_kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: b86ef5367761 ("ASoC: fsl: Add Audio Mixer machine driver") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230614121509.443926-1-claudiu.beznea@microchip.c... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/imx-audmix.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c index a364e2415de02..d991e457060c7 100644 --- a/sound/soc/fsl/imx-audmix.c +++ b/sound/soc/fsl/imx-audmix.c @@ -228,6 +228,8 @@ static int imx_audmix_probe(struct platform_device *pdev)
dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%s", fe_name_pref, args.np->full_name + 1); + if (!dai_name) + return -ENOMEM;
dev_info(pdev->dev.parent, "DAI FE name:%s\n", dai_name);
@@ -236,6 +238,8 @@ static int imx_audmix_probe(struct platform_device *pdev) capture_dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s", dai_name, "CPU-Capture"); + if (!capture_dai_name) + return -ENOMEM; }
priv->dai[i].cpus = &dlc[0]; @@ -266,6 +270,8 @@ static int imx_audmix_probe(struct platform_device *pdev) "AUDMIX-Playback-%d", i); be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL, "AUDMIX-Capture-%d", i); + if (!be_name || !be_pb || !be_cp) + return -ENOMEM;
priv->dai[num_dai + i].cpus = &dlc[3]; priv->dai[num_dai + i].codecs = &dlc[4]; @@ -293,6 +299,9 @@ static int imx_audmix_probe(struct platform_device *pdev) priv->dapm_routes[i].source = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s", dai_name, "CPU-Playback"); + if (!priv->dapm_routes[i].source) + return -ENOMEM; + priv->dapm_routes[i].sink = be_pb; priv->dapm_routes[num_dai + i].source = be_pb; priv->dapm_routes[num_dai + i].sink = be_cp;
From: Fei Shao fshao@chromium.org
[ Upstream commit 7fb933e56f77a57ef7cfc59fc34cbbf1b1fa31ff ]
devm_clk_notifier_register() allocates a devres resource for clk notifier but didn't register that to the device, so the notifier didn't get unregistered on device detach and the allocated resource was leaked.
Fix the issue by registering the resource through devres_add().
This issue was found with kmemleak on a Chromebook.
Fixes: 6d30d50d037d ("clk: add devm variant of clk_notifier_register") Signed-off-by: Fei Shao fshao@chromium.org Link: https://lore.kernel.org/r/20230619112253.v2.1.I13f060c10549ef181603e921291bd... Reviewed-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 0674dbc62eb55..5eba83745d8de 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -4504,6 +4504,7 @@ int devm_clk_notifier_register(struct device *dev, struct clk *clk, if (!ret) { devres->clk = clk; devres->nb = nb; + devres_add(dev, devres); } else { devres_free(devres); }
From: Siddharth Vadapalli s-vadapalli@ti.com
[ Upstream commit 0e12f830236928b6fadf40d917a7527f0a048d2f ]
The Link Retraining process is initiated to account for the Gen2 defect in the Cadence PCIe controller in J721E SoC. The errata corresponding to this is i2085, documented at: https://www.ti.com/lit/er/sprz455c/sprz455c.pdf
The existing workaround implemented for the errata waits for the Data Link initialization to complete and assumes that the link retraining process at the Physical Layer has completed. However, it is possible that the Physical Layer training might be ongoing as indicated by the PCI_EXP_LNKSTA_LT bit in the PCI_EXP_LNKSTA register.
Fix the existing workaround, to ensure that the Physical Layer training has also completed, in addition to the Data Link initialization.
Link: https://lore.kernel.org/r/20230315070800.1615527-1-s-vadapalli@ti.com Fixes: 4740b969aaf5 ("PCI: cadence: Retrain Link to work around Gen2 training defect") Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../controller/cadence/pcie-cadence-host.c | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c index fb96d37a135c1..4d8d15ac51ef4 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-host.c +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c @@ -12,6 +12,8 @@
#include "pcie-cadence.h"
+#define LINK_RETRAIN_TIMEOUT HZ + static u64 bar_max_size[] = { [RP_BAR0] = _ULL(128 * SZ_2G), [RP_BAR1] = SZ_2G, @@ -77,6 +79,27 @@ static struct pci_ops cdns_pcie_host_ops = { .write = pci_generic_config_write, };
+static int cdns_pcie_host_training_complete(struct cdns_pcie *pcie) +{ + u32 pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET; + unsigned long end_jiffies; + u16 lnk_stat; + + /* Wait for link training to complete. Exit after timeout. */ + end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT; + do { + lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA); + if (!(lnk_stat & PCI_EXP_LNKSTA_LT)) + break; + usleep_range(0, 1000); + } while (time_before(jiffies, end_jiffies)); + + if (!(lnk_stat & PCI_EXP_LNKSTA_LT)) + return 0; + + return -ETIMEDOUT; +} + static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie) { struct device *dev = pcie->dev; @@ -118,6 +141,10 @@ static int cdns_pcie_retrain(struct cdns_pcie *pcie) cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL, lnk_ctl);
+ ret = cdns_pcie_host_training_complete(pcie); + if (ret) + return ret; + ret = cdns_pcie_host_wait_for_link(pcie); } return ret;
From: Nirmal Patel nirmal.patel@linux.intel.com
[ Upstream commit b61cf04c49c3dfa70a0d6725d3eb40bf9b35cf71 ]
VMD driver can disable or enable MSI remapping by changing VMCONFIG_MSI_REMAP register. This register needs to be set to the default value during soft reboots. Drives failed to enumerate when Windows boots after performing a soft reboot from Linux. Windows doesn't support MSI remapping disable feature and stale register value hinders Windows VMD driver initialization process. Adding vmd_shutdown function to make sure to set the VMCONFIG register to the default value.
Link: https://lore.kernel.org/r/20230224202811.644370-1-nirmal.patel@linux.intel.c... Fixes: ee81ee84f873 ("PCI: vmd: Disable MSI-X remapping when possible") Signed-off-by: Nirmal Patel nirmal.patel@linux.intel.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Jon Derrick jonathan.derrick@linux.dev Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/vmd.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index 8dce71142e10f..f49001ba96c75 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@ -881,6 +881,13 @@ static void vmd_remove(struct pci_dev *dev) vmd_remove_irq_domain(vmd); }
+static void vmd_shutdown(struct pci_dev *dev) +{ + struct vmd_dev *vmd = pci_get_drvdata(dev); + + vmd_remove_irq_domain(vmd); +} + #ifdef CONFIG_PM_SLEEP static int vmd_suspend(struct device *dev) { @@ -946,6 +953,7 @@ static struct pci_driver vmd_drv = { .id_table = vmd_ids, .probe = vmd_probe, .remove = vmd_remove, + .shutdown = vmd_shutdown, .driver = { .pm = &vmd_dev_pm_ops, },
From: Jinhong Zhu jinhongzhu@hust.edu.cn
[ Upstream commit f025312b089474a54e4859f3453771314d9e3d4f ]
Smatch reported:
drivers/scsi/qedf/qedf_main.c:3056 qedf_alloc_global_queues() warn: missing unwind goto?
At this point in the function, nothing has been allocated so we can return directly. In particular the "qedf->global_queues" have not been allocated so calling qedf_free_global_queues() will lead to a NULL dereference when we check if (!gl[i]) and "gl" is NULL.
Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.") Signed-off-by: Jinhong Zhu jinhongzhu@hust.edu.cn Link: https://lore.kernel.org/r/20230502140022.2852-1-jinhongzhu@hust.edu.cn Reviewed-by: Dan Carpenter error27@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qedf/qedf_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index fa49a3e52a9b5..cf10c1a60399e 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -3046,9 +3046,8 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf) * addresses of our queues */ if (!qedf->p_cpuq) { - status = -EINVAL; QEDF_ERR(&qedf->dbg_ctx, "p_cpuq is NULL.\n"); - goto mem_alloc_failure; + return -EINVAL; }
qedf->global_queues = kzalloc((sizeof(struct global_queue *)
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit cdf7e616120065007687fe1df0412154f259daec ]
gpiochip_add_pin_range() can fail, so better return its error code than a hard coded '0'.
Fixes: d2b67744fd99 ("pinctrl: bcm2835: implement hook for missing gpio-ranges") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/98c3b5890bb72415145c9fe4e1d974711edae376.168168140... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 2c10086fd155b..7904ae5406da1 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -359,10 +359,8 @@ static int bcm2835_of_gpio_ranges_fallback(struct gpio_chip *gc, if (!pctldev) return 0;
- gpiochip_add_pin_range(gc, pinctrl_dev_get_devname(pctldev), 0, 0, - gc->ngpio); - - return 0; + return gpiochip_add_pin_range(gc, pinctrl_dev_get_devname(pctldev), 0, 0, + gc->ngpio); }
static const struct gpio_chip bcm2835_gpio_chip = {
From: Ding Hui dinghui@sangfor.com.cn
[ Upstream commit 456d8aa37d0f56fc9e985e812496e861dcd6f2f2 ]
Struct pcie_link_state->downstream is a pointer to the pci_dev of function 0. Previously we retained that pointer when removing function 0, and subsequent ASPM policy changes dereferenced it, resulting in a use-after-free warning from KASAN, e.g.:
# echo 1 > /sys/bus/pci/devices/0000:03:00.0/remove # echo powersave > /sys/module/pcie_aspm/parameters/policy
BUG: KASAN: slab-use-after-free in pcie_config_aspm_link+0x42d/0x500 Call Trace: kasan_report+0xae/0xe0 pcie_config_aspm_link+0x42d/0x500 pcie_aspm_set_policy+0x8e/0x1a0 param_attr_store+0x162/0x2c0 module_attr_store+0x3e/0x80
PCIe spec r6.0, sec 7.5.3.7, recommends that software program the same ASPM Control value in all functions of multi-function devices.
Disable ASPM and free the pcie_link_state when any child function is removed so we can discard the dangling pcie_link_state->downstream pointer and maintain the same ASPM Control configuration for all functions.
[bhelgaas: commit log and comment] Debugged-by: Zongquan Qin qinzongquan@sangfor.com.cn Suggested-by: Bjorn Helgaas bhelgaas@google.com Fixes: b5a0a9b59c81 ("PCI/ASPM: Read and set up L1 substate capabilities") Link: https://lore.kernel.org/r/20230507034057.20970-1-dinghui@sangfor.com.cn Signed-off-by: Ding Hui dinghui@sangfor.com.cn Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pcie/aspm.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index b3ad316418f1c..c58294f53fcd1 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -993,21 +993,24 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
down_read(&pci_bus_sem); mutex_lock(&aspm_lock); - /* - * All PCIe functions are in one slot, remove one function will remove - * the whole slot, so just wait until we are the last function left. - */ - if (!list_empty(&parent->subordinate->devices)) - goto out;
link = parent->link_state; root = link->root; parent_link = link->parent;
- /* All functions are removed, so just disable ASPM for the link */ + /* + * link->downstream is a pointer to the pci_dev of function 0. If + * we remove that function, the pci_dev is about to be deallocated, + * so we can't use link->downstream again. Free the link state to + * avoid this. + * + * If we're removing a non-0 function, it's possible we could + * retain the link state, but PCIe r6.0, sec 7.5.3.7, recommends + * programming the same ASPM Control value for all functions of + * multi-function devices, so disable ASPM for all of them. + */ pcie_config_aspm_link(link, 0); list_del(&link->sibling); - /* Clock PM is for endpoint device */ free_link_state(link);
/* Recheck latencies and configure upstream links */ @@ -1015,7 +1018,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) pcie_update_aspm_capable(root); pcie_config_aspm_path(parent_link); } -out: + mutex_unlock(&aspm_lock); up_read(&pci_bus_sem); }
From: Yuchen Yang u202114568@hust.edu.cn
[ Upstream commit 2e2fe5ac695a00ab03cab4db1f4d6be07168ed9d ]
Smatch complains that:
tw_probe() warn: missing error code 'retval'
This patch adds error checking to tw_probe() to handle initialization failure. If tw_reset_sequence() function returns a non-zero value, the function will return -EINVAL to indicate initialization failure.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Yuchen Yang u202114568@hust.edu.cn Link: https://lore.kernel.org/r/20230505141259.7730-1-u202114568@hust.edu.cn Reviewed-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/3w-xxxx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 4ee485ab27148..678c8ca4f699c 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -2305,8 +2305,10 @@ static int tw_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id) TW_DISABLE_INTERRUPTS(tw_dev);
/* Initialize the card */ - if (tw_reset_sequence(tw_dev)) + if (tw_reset_sequence(tw_dev)) { + retval = -EINVAL; goto out_release_mem_region; + }
/* Set host specific parameters */ host->max_id = TW_MAX_UNITS;
From: Rongguang Wei weirongguang@kylinos.cn
[ Upstream commit e8afd0d9fccc27c8ad263db5cf5952cfcf72d6fe ]
If a PCIe hotplug slot has an Attention Button, the normal hot-add flow is:
- Slot is empty and slot power is off - User inserts card in slot and presses Attention Button - OS blinks Power Indicator for 5 seconds - After 5 seconds, OS turns on Power Indicator, turns on slot power, and enumerates the device
Previously, if a user pressed the Attention Button on an *empty* slot, pciehp logged the following messages and blinked the Power Indicator until a second button press:
[0.000] pciehp: Button press: will power on in 5 sec [0.001] # Power Indicator starts blinking [5.001] # 5 second timeout; slot is empty, so we should cancel the request to power on and turn off Power Indicator
[7.000] # Power Indicator still blinking [8.000] # possible card insertion [9.000] pciehp: Button press: canceling request to power on
The first button press incorrectly left the slot in BLINKINGON_STATE, so the second was interpreted as a "cancel power on" event regardless of whether a card was present.
If the slot is empty, turn off the Power Indicator and return from BLINKINGON_STATE to OFF_STATE after 5 seconds, effectively canceling the request to power on. Putting the slot in OFF_STATE also means the second button press will correctly request a slot power on if the slot is occupied.
[bhelgaas: commit log] Link: https://lore.kernel.org/r/20230512021518.336460-1-clementwei90@163.com Fixes: d331710ea78f ("PCI: pciehp: Become resilient to missed events") Suggested-by: Lukas Wunner lukas@wunner.de Signed-off-by: Rongguang Wei weirongguang@kylinos.cn Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Lukas Wunner lukas@wunner.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/hotplug/pciehp_ctrl.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 529c348084401..32baba1b7f131 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -256,6 +256,14 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events) present = pciehp_card_present(ctrl); link_active = pciehp_check_link_active(ctrl); if (present <= 0 && link_active <= 0) { + if (ctrl->state == BLINKINGON_STATE) { + ctrl->state = OFF_STATE; + cancel_delayed_work(&ctrl->button_work); + pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, + INDICATOR_NOOP); + ctrl_info(ctrl, "Slot(%s): Card not present\n", + slot_name(ctrl)); + } mutex_unlock(&ctrl->state_lock); return; }
From: Junyan Ye yejunyan@hust.edu.cn
[ Upstream commit c60738de85f40b0b9f5cb23c21f9246e5a47908c ]
Smatch reported: 1. drivers/pci/controller/pci-ftpci100.c:526 faraday_pci_probe() warn: 'clk' from clk_prepare_enable() not released on lines: 442,451,462,478,512,517. 2. drivers/pci/controller/pci-ftpci100.c:526 faraday_pci_probe() warn: 'p->bus_clk' from clk_prepare_enable() not released on lines: 451,462,478,512,517.
The clock resource is obtained by devm_clk_get(), and then clk_prepare_enable() makes the clock resource ready for use. After that, clk_disable_unprepare() should be called to release the clock resource when it is no longer needed. However, while doing some error handling in faraday_pci_probe(), clk_disable_unprepare() is not called to release clk and p->bus_clk before returning. These return lines are exactly 442, 451, 462, 478, 512, 517.
Fix this warning by replacing devm_clk_get() with devm_clk_get_enabled(), which is equivalent to devm_clk_get() + clk_prepare_enable(). And with devm_clk_get_enabled(), the clock will automatically be disabled, unprepared and freed when the device is unbound from the bus.
Link: https://lore.kernel.org/r/20230508043641.23807-1-yejunyan@hust.edu.cn Fixes: b3c433efb8a3 ("PCI: faraday: Fix wrong pointer passed to PTR_ERR()") Fixes: 2eeb02b28579 ("PCI: faraday: Add clock handling") Fixes: 783a862563f7 ("PCI: faraday: Use pci_parse_request_of_pci_ranges()") Fixes: d3c68e0a7e34 ("PCI: faraday: Add Faraday Technology FTPCI100 PCI Host Bridge driver") Fixes: f1e8bd21e39e ("PCI: faraday: Convert IRQ masking to raw PCI config accessors") Signed-off-by: Junyan Ye yejunyan@hust.edu.cn Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pci-ftpci100.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/drivers/pci/controller/pci-ftpci100.c b/drivers/pci/controller/pci-ftpci100.c index 88980a44461df..ca8de44045bbe 100644 --- a/drivers/pci/controller/pci-ftpci100.c +++ b/drivers/pci/controller/pci-ftpci100.c @@ -442,22 +442,12 @@ static int faraday_pci_probe(struct platform_device *pdev) p->dev = dev;
/* Retrieve and enable optional clocks */ - clk = devm_clk_get(dev, "PCLK"); + clk = devm_clk_get_enabled(dev, "PCLK"); if (IS_ERR(clk)) return PTR_ERR(clk); - ret = clk_prepare_enable(clk); - if (ret) { - dev_err(dev, "could not prepare PCLK\n"); - return ret; - } - p->bus_clk = devm_clk_get(dev, "PCICLK"); + p->bus_clk = devm_clk_get_enabled(dev, "PCICLK"); if (IS_ERR(p->bus_clk)) return PTR_ERR(p->bus_clk); - ret = clk_prepare_enable(p->bus_clk); - if (ret) { - dev_err(dev, "could not prepare PCICLK\n"); - return ret; - }
p->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(p->base))
From: Sui Jingfeng suijingfeng@loongson.cn
[ Upstream commit 2aa5ac633259843f656eb6ecff4cf01e8e810c5e ]
Add a pci_clear_master() stub when CONFIG_PCI is not set so drivers that support both PCI and platform devices don't need #ifdefs or extra Kconfig symbols for the PCI parts.
[bhelgaas: commit log] Fixes: 6a479079c072 ("PCI: Add pci_clear_master() as opposite of pci_set_master()") Link: https://lore.kernel.org/r/20230531102744.2354313-1-suijingfeng@loongson.cn Signed-off-by: Sui Jingfeng suijingfeng@loongson.cn Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/linux/pci.h b/include/linux/pci.h index 7e471432a998c..99dfb8c1993a6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1787,6 +1787,7 @@ static inline struct pci_dev *pci_get_class(unsigned int class, #define pci_dev_put(dev) do { } while (0)
static inline void pci_set_master(struct pci_dev *dev) { } +static inline void pci_clear_master(struct pci_dev *dev) { } static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; } static inline void pci_disable_device(struct pci_dev *dev) { } static inline int pcim_enable_device(struct pci_dev *pdev) { return -EIO; }
From: Sohaib Mohamed sohaib.amhmd@gmail.com
[ Upstream commit f0a29c9647ff8bbb424641f79bc1894e83dec218 ]
The output of 'perf bench' gets buffered when I pipe it to a file or to tee, in such a way that I can see it only at the end.
E.g.
$ perf bench internals synthesize -t < output comes out fine after each test run >
$ perf bench internals synthesize -t | tee file.txt < output comes out only at the end of all tests >
This patch resolves this issue for 'bench' and 'test' subcommands.
See, also:
$ perf bench mem all | tee file.txt $ perf bench sched all | tee file.txt $ perf bench internals all -t | tee file.txt $ perf bench internals all | tee file.txt
Committer testing:
It really gets staggered, i.e. outputs in bursts, when the buffer fills up and has to be drained to make up space for more output.
Suggested-by: Riccardo Mancini rickyman7@gmail.com Signed-off-by: Sohaib Mohamed sohaib.amhmd@gmail.com Tested-by: Arnaldo Carvalho de Melo acme@redhat.com Acked-by: Jiri Olsa jolsa@redhat.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Fabian Hemmer copy@copy.sh Cc: Ian Rogers irogers@google.com Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Link: http://lore.kernel.org/lkml/20211119061409.78004-1-sohaib.amhmd@gmail.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Stable-dep-of: 16203e9cd018 ("perf bench: Add missing setlocale() call to allow usage of %'d style formatting") Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-bench.c | 5 +++-- tools/perf/tests/builtin-test.c | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index d0895162c2ba6..d291f3a8af5f2 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c @@ -226,7 +226,6 @@ static void run_collection(struct collection *coll) if (!bench->fn) break; printf("# Running %s/%s benchmark...\n", coll->name, bench->name); - fflush(stdout);
argv[1] = bench->name; run_bench(coll->name, bench->name, bench->fn, 1, argv); @@ -247,6 +246,9 @@ int cmd_bench(int argc, const char **argv) struct collection *coll; int ret = 0;
+ /* Unbuffered output */ + setvbuf(stdout, NULL, _IONBF, 0); + if (argc < 2) { /* No collection specified. */ print_usage(); @@ -300,7 +302,6 @@ int cmd_bench(int argc, const char **argv)
if (bench_format == BENCH_FORMAT_DEFAULT) printf("# Running '%s/%s' benchmark:\n", coll->name, bench->name); - fflush(stdout); ret = run_bench(coll->name, bench->name, bench->fn, argc-1, argv+1); goto end; } diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index da7dc5e45d0cf..4d6d3e3142008 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -828,6 +828,9 @@ int cmd_test(int argc, const char **argv) if (ret < 0) return ret;
+ /* Unbuffered output */ + setvbuf(stdout, NULL, _IONBF, 0); + argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0); if (argc >= 1 && !strcmp(argv[0], "list")) return perf_test__list(argc - 1, argv + 1);
From: Arnaldo Carvalho de Melo acme@redhat.com
[ Upstream commit 16203e9cd01896b4244100a8e3fb9f6e612ab2b1 ]
Without this we were not getting the thousands separator for big numbers.
Noticed while developing 'perf bench uprobe', but the use of %' predates that, for instance 'perf bench syscall' uses it.
Before:
# perf bench uprobe all # Running uprobe/baseline benchmark... # Executed 1000 usleep(1000) calls Total time: 1054082243ns
1054082.243000 nsecs/op
#
After:
# perf bench uprobe all # Running uprobe/baseline benchmark... # Executed 1,000 usleep(1000) calls Total time: 1,053,715,144ns
1,053,715.144000 nsecs/op
#
Fixes: c2a08203052f8975 ("perf bench: Add basic syscall benchmark") Cc: Adrian Hunter adrian.hunter@intel.com Cc: Andre Fredette anfredet@redhat.com Cc: Clark Williams williams@redhat.com Cc: Dave Tucker datucker@redhat.com Cc: Davidlohr Bueso dave@stgolabs.net Cc: Derek Barbosa debarbos@redhat.com Cc: Ian Rogers irogers@google.com Cc: Jiri Olsa jolsa@kernel.org Cc: Namhyung Kim namhyung@kernel.org Cc: Tiezhu Yang yangtiezhu@loongson.cn Link: https://lore.kernel.org/lkml/ZH3lcepZ4tBYr1jv@kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-bench.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index d291f3a8af5f2..ac72bcccc353b 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c @@ -21,6 +21,7 @@ #include "builtin.h" #include "bench/bench.h"
+#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -248,6 +249,7 @@ int cmd_bench(int argc, const char **argv)
/* Unbuffered output */ setvbuf(stdout, NULL, _IONBF, 0); + setlocale(LC_ALL, "");
if (argc < 2) { /* No collection specified. */
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 5835196a17be5cfdcad0b617f90cf4abe16951a4 ]
Currently the getter returns ENOTSUPP on pin configured in the push-pull mode. Fix this by adding the missed switch case.
Fixes: ccdf81d08dbe ("pinctrl: cherryview: add option to set open-drain pin config") Fixes: 6e08d6bbebeb ("pinctrl: Add Intel Cherryview/Braswell pin controller support") Acked-by: Mika Westerberg mika.westerberg@linux.intel.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/intel/pinctrl-cherryview.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 980099028cf8a..34f0ec784dbe2 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -945,11 +945,6 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
break;
- case PIN_CONFIG_DRIVE_OPEN_DRAIN: - if (!(ctrl1 & CHV_PADCTRL1_ODEN)) - return -EINVAL; - break; - case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: { u32 cfg;
@@ -959,6 +954,16 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin, return -EINVAL;
break; + + case PIN_CONFIG_DRIVE_PUSH_PULL: + if (ctrl1 & CHV_PADCTRL1_ODEN) + return -EINVAL; + break; + + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (!(ctrl1 & CHV_PADCTRL1_ODEN)) + return -EINVAL; + break; }
default:
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit 353e7300a1db928e427462f2745f9a2cd1625b3d ]
Activating KCSAN on a 32 bits architecture leads to the following link-time failure:
LD .tmp_vmlinux.kallsyms1 powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_load': kernel/kcsan/core.c:1273: undefined reference to `__atomic_load_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_store': kernel/kcsan/core.c:1273: undefined reference to `__atomic_store_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_exchange': kernel/kcsan/core.c:1273: undefined reference to `__atomic_exchange_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_add': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_add_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_sub': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_sub_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_and': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_and_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_or': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_or_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_xor': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_xor_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_fetch_nand': kernel/kcsan/core.c:1273: undefined reference to `__atomic_fetch_nand_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_compare_exchange_strong': kernel/kcsan/core.c:1273: undefined reference to `__atomic_compare_exchange_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_compare_exchange_weak': kernel/kcsan/core.c:1273: undefined reference to `__atomic_compare_exchange_8' powerpc64-linux-ld: kernel/kcsan/core.o: in function `__tsan_atomic64_compare_exchange_val': kernel/kcsan/core.c:1273: undefined reference to `__atomic_compare_exchange_8'
32 bits architectures don't have 64 bits atomic builtins. Only include DEFINE_TSAN_ATOMIC_OPS(64) on 64 bits architectures.
Fixes: 0f8ad5f2e934 ("kcsan: Add support for atomic builtins") Suggested-by: Marco Elver elver@google.com Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Reviewed-by: Marco Elver elver@google.com Acked-by: Marco Elver elver@google.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/d9c6afc28d0855240171a4e0ad9ffcdb9d07fceb.1683892665.git.c... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/kcsan/core.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c index 526510b3791ed..3f3b5e3ca9eb3 100644 --- a/kernel/kcsan/core.c +++ b/kernel/kcsan/core.c @@ -1050,7 +1050,9 @@ EXPORT_SYMBOL(__tsan_init); DEFINE_TSAN_ATOMIC_OPS(8); DEFINE_TSAN_ATOMIC_OPS(16); DEFINE_TSAN_ATOMIC_OPS(32); +#ifdef CONFIG_64BIT DEFINE_TSAN_ATOMIC_OPS(64); +#endif
void __tsan_atomic_thread_fence(int memorder); void __tsan_atomic_thread_fence(int memorder)
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit 0eb089a72fda3f7969e6277804bde75dc1474a14 ]
A disassembly of interrupt_exit_kernel_prepare() shows a useless read of MSR register. This is shown by r9 being re-used immediately without doing anything with the value read.
c000e0e0: 60 00 00 00 nop c000e0e4: 7d 3a c2 a6 mfmd_ap r9 c000e0e8: 7d 20 00 a6 mfmsr r9 c000e0ec: 7c 51 13 a6 mtspr 81,r2 c000e0f0: 81 3f 00 84 lwz r9,132(r31) c000e0f4: 71 29 80 00 andi. r9,r9,32768
This is due to the use of local_irq_save(). The flags read by local_irq_save() are never used, use local_irq_disable() instead.
Fixes: 13799748b957 ("powerpc/64: use interrupt restart table to speed up return from interrupt") Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Reviewed-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/df36c6205ab64326fb1b991993c82057e92ace2f.1685955214.git.c... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/interrupt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c index 8703df709cce8..e93f67c3af76b 100644 --- a/arch/powerpc/kernel/interrupt.c +++ b/arch/powerpc/kernel/interrupt.c @@ -531,7 +531,6 @@ void preempt_schedule_irq(void);
notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs) { - unsigned long flags; unsigned long ret = 0; unsigned long kuap; bool stack_store = current_thread_info()->flags & @@ -548,7 +547,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
kuap = kuap_get_and_assert_locked();
- local_irq_save(flags); + local_irq_disable();
if (!arch_irq_disabled_regs(regs)) { /* Returning to a kernel context with local irqs enabled. */
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit a03b1a0b19398a47489fdcef02ec19c2ba05a15d ]
Looking at generated code for handle_signal32() shows calls to a function called __unsafe_save_user_regs.constprop.0 while user access is open.
And that __unsafe_save_user_regs.constprop.0 function has two nops at the begining, allowing it to be traced, which is unexpected during user access open window.
The solution could be to mark __unsafe_save_user_regs() no trace, but to be on the safe side the most efficient is to flag it __always_inline as already done for function __unsafe_restore_general_regs(). The function is relatively small and only called twice, so the size increase will remain in the noise.
Do the same with save_tm_user_regs_unsafe() as it may suffer the same issue.
Fixes: ef75e7318294 ("powerpc/signal32: Transform save_user_regs() and save_tm_user_regs() in 'unsafe' version") Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/7e469c8f01860a69c1ada3ca6a5e2aa65f0f74b2.1685955220.git.c... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/signal_32.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 3e053e2fd6b69..68ed8ecf64fcc 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -258,8 +258,9 @@ static void prepare_save_user_regs(int ctx_has_vsx_region) #endif }
-static int __unsafe_save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, - struct mcontext __user *tm_frame, int ctx_has_vsx_region) +static __always_inline int +__unsafe_save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, + struct mcontext __user *tm_frame, int ctx_has_vsx_region) { unsigned long msr = regs->msr;
@@ -358,8 +359,9 @@ static void prepare_save_tm_user_regs(void) current->thread.ckvrsave = mfspr(SPRN_VRSAVE); }
-static int save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame, - struct mcontext __user *tm_frame, unsigned long msr) +static __always_inline int +save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame, + struct mcontext __user *tm_frame, unsigned long msr) { /* Save both sets of general registers */ unsafe_save_general_regs(¤t->thread.ckpt_regs, frame, failed); @@ -438,8 +440,9 @@ static int save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user #else static void prepare_save_tm_user_regs(void) { }
-static int save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame, - struct mcontext __user *tm_frame, unsigned long msr) +static __always_inline int +save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame, + struct mcontext __user *tm_frame, unsigned long msr) { return 0; }
From: Arnaldo Carvalho de Melo acme@redhat.com
[ Upstream commit 36d3e4138e1b6cc9ab179f3f397b5548f8b1eaae ]
When printing output we may want to generate per event files, where the --per-event-dump option should be used, creating perf.data.EVENT.dump files instead of printing to stdout.
The callback thar processes event thus expects that evsel->priv->fp should point to either the per-event FILE descriptor or to stdout.
The a3af66f51bd0bca7 ("perf script: Fix crash because of missing evsel->priv") changeset fixed a case where evsel->priv wasn't setup, thus set to NULL, causing a segfault when trying to access evsel->priv->fp.
But it did it for the non --per-event-dump case by allocating a 'struct perf_evsel_script' just to set its ->fp to stdout.
Since evsel->priv is only freed when --per-event-dump is used, we ended up with a memory leak, detected using ASAN.
Fix it by using the same method as perf_script__setup_per_event_dump(), and reuse that static 'struct perf_evsel_script'.
Also check if evsel_script__new() failed.
Fixes: a3af66f51bd0bca7 ("perf script: Fix crash because of missing evsel->priv") Reported-by: Ian Rogers irogers@google.com Tested-by: Ian Rogers irogers@google.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Jiri Olsa jolsa@kernel.org Cc: Namhyung Kim namhyung@kernel.org Cc: Ravi Bangoria ravi.bangoria@linux.ibm.com Link: https://lore.kernel.org/lkml/ZH+F0wGAWV14zvMP@kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-script.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index c6c40191933d4..34e809c934d72 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2260,6 +2260,9 @@ static int process_sample_event(struct perf_tool *tool, return ret; }
+// Used when scr->per_event_dump is not set +static struct evsel_script es_stdout; + static int process_attr(struct perf_tool *tool, union perf_event *event, struct evlist **pevlist) { @@ -2268,7 +2271,6 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, struct evsel *evsel, *pos; u64 sample_type; int err; - static struct evsel_script *es;
err = perf_event__process_attr(tool, event, pevlist); if (err) @@ -2278,14 +2280,13 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, evsel = evlist__last(*pevlist);
if (!evsel->priv) { - if (scr->per_event_dump) { + if (scr->per_event_dump) { evsel->priv = evsel_script__new(evsel, scr->session->data); - } else { - es = zalloc(sizeof(*es)); - if (!es) + if (!evsel->priv) return -ENOMEM; - es->fp = stdout; - evsel->priv = es; + } else { // Replicate what is done in perf_script__setup_per_event_dump() + es_stdout.fp = stdout; + evsel->priv = &es_stdout; } }
@@ -2591,7 +2592,6 @@ static int perf_script__fopen_per_event_dump(struct perf_script *script) static int perf_script__setup_per_event_dump(struct perf_script *script) { struct evsel *evsel; - static struct evsel_script es_stdout;
if (script->per_event_dump) return perf_script__fopen_per_event_dump(script);
From: Namhyung Kim namhyung@kernel.org
[ Upstream commit 3abfcfd847717d232e36963f31a361747c388fe7 ]
The die_get_varname() returns "(unknown_type)" string if it failed to find a type for the variable. But it had a space before the opening parenthesis and it made the closing parenthesis cut off due to the off-by-one in the string length (14).
Signed-off-by: Namhyung Kim namhyung@kernel.org Fixes: 88fd633cdfa19060 ("perf probe: No need to use formatting strbuf method") Cc: Adrian Hunter adrian.hunter@intel.com Cc: Ian Rogers irogers@google.com Cc: Ingo Molnar mingo@kernel.org Cc: Jiri Olsa jolsa@kernel.org Cc: Masami Hiramatsu mhiramat@kernel.org Cc: Peter Zijlstra peterz@infradead.org Link: https://lore.kernel.org/r/20230612234102.3909116-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/dwarf-aux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 623527edeac1e..b125eaadcec4d 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1081,7 +1081,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf) ret = die_get_typename(vr_die, buf); if (ret < 0) { pr_debug("Failed to get type, make it unknown.\n"); - ret = strbuf_add(buf, " (unknown_type)", 14); + ret = strbuf_add(buf, "(unknown_type)", 14); }
return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
From: Nicholas Piggin npiggin@gmail.com
[ Upstream commit b4bda59b47879cce38a6ec5a01cd3cac702b5331 ]
The refcount on mm is dropped before the coprocessor is detached.
Reported-by: Sachin Sant sachinp@linux.ibm.com Fixes: 7bc6f71bdff5f ("powerpc/vas: Define and use common vas_window struct") Fixes: b22f2d88e435c ("powerpc/pseries/vas: Integrate API with open/close windows") Signed-off-by: Nicholas Piggin npiggin@gmail.com Tested-by: Sachin Sant sachinp@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230607101024.14559-1-npiggin@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/powernv/vas-window.c | 2 +- arch/powerpc/platforms/pseries/vas.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 0072682531d80..b664838008c12 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -1310,8 +1310,8 @@ int vas_win_close(struct vas_window *vwin) /* if send window, drop reference to matching receive window */ if (window->tx_win) { if (window->user_win) { - put_vas_user_win_ref(&vwin->task_ref); mm_context_remove_vas_window(vwin->task_ref.mm); + put_vas_user_win_ref(&vwin->task_ref); } put_rx_win(window->rxwin); } diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c index 15046d80f0427..b54f6fc27896f 100644 --- a/arch/powerpc/platforms/pseries/vas.c +++ b/arch/powerpc/platforms/pseries/vas.c @@ -441,8 +441,8 @@ static int vas_deallocate_window(struct vas_window *vwin) atomic_dec(&caps->used_lpar_creds); mutex_unlock(&vas_pseries_mutex);
- put_vas_user_win_ref(&vwin->task_ref); mm_context_remove_vas_window(vwin->task_ref.mm); + put_vas_user_win_ref(&vwin->task_ref);
kfree(win); return 0;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 310cd4c206cd04696ccbfd1927b5ab6973e8cc8e ]
devm_kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: 7e5ea974e61c ("pinctrl: pinctrl-microchip-sgpio: Add pinctrl driver for Microsemi Serial GPIO") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20230615105333.585304-3-claudiu.beznea@microchip.c... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-microchip-sgpio.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c index dfa374195694d..aceadc9ec0244 100644 --- a/drivers/pinctrl/pinctrl-microchip-sgpio.c +++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c @@ -729,6 +729,9 @@ static int microchip_sgpio_register_bank(struct device *dev, pctl_desc->name = devm_kasprintf(dev, GFP_KERNEL, "%s-%sput", dev_name(dev), bank->is_input ? "in" : "out"); + if (!pctl_desc->name) + return -ENOMEM; + pctl_desc->pctlops = &sgpio_pctl_ops; pctl_desc->pmxops = &sgpio_pmx_ops; pctl_desc->confops = &sgpio_confops;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit f6fd5d4ff8ca0b24cee1af4130bcb1fa96b61aa0 ]
devm_kasprintf() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: 776180848b57 ("pinctrl: introduce driver for Atmel PIO4 controller") Depends-on: 1c4e5c470a56 ("pinctrl: at91: use devm_kasprintf() to avoid potential leaks") Depends-on: 5a8f9cf269e8 ("pinctrl: at91-pio4: use proper format specifier for unsigned int") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20230615105333.585304-4-claudiu.beznea@microchip.c... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-at91-pio4.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index e31f5d9febe9e..62b9a94c10baa 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -1128,6 +1128,8 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) /* Pin naming convention: P(bank_name)(bank_pin_number). */ pin_desc[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "P%c%d", bank + 'A', line); + if (!pin_desc[i].name) + return -ENOMEM;
group->name = group_names[i] = pin_desc[i].name; group->pin = pin_desc[i].number;
From: Colin Ian King colin.i.king@gmail.com
[ Upstream commit f4f913c980bc6abe0ccfe88fe3909c125afe4a2d ]
Currently pointer iov is being dereferenced before the null check of iov which can lead to null pointer dereference errors. Fix this by moving the iov null check before the dereferencing.
Detected using cppcheck static analysis: linux/arch/powerpc/platforms/powernv/pci-sriov.c:597:12: warning: Either the condition '!iov' is redundant or there is possible null pointer dereference: iov. [nullPointerRedundantCheck] num_vfs = iov->num_vfs; ^
Fixes: 052da31d45fc ("powerpc/powernv/sriov: De-indent setup and teardown") Signed-off-by: Colin Ian King colin.i.king@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230608095849.1147969-1-colin.i.king@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/powernv/pci-sriov.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/pci-sriov.c b/arch/powerpc/platforms/powernv/pci-sriov.c index 28aac933a4391..e3e52ff2cbf58 100644 --- a/arch/powerpc/platforms/powernv/pci-sriov.c +++ b/arch/powerpc/platforms/powernv/pci-sriov.c @@ -600,12 +600,12 @@ static void pnv_pci_sriov_disable(struct pci_dev *pdev) struct pnv_iov_data *iov;
iov = pnv_iov_get(pdev); - num_vfs = iov->num_vfs; - base_pe = iov->vf_pe_arr[0].pe_number; - if (WARN_ON(!iov)) return;
+ num_vfs = iov->num_vfs; + base_pe = iov->vf_pe_arr[0].pe_number; + /* Release VF PEs */ pnv_ioda_release_vf_PE(pdev);
From: Nicholas Piggin npiggin@gmail.com
[ Upstream commit 37195b820d32c23bdefce3f460ed7de48a57e5e4 ]
Adjust the pt_regs pointer so the interrupt frame offsets can be used to save registers.
Signed-off-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20221127124942.1665522-7-npiggin@gmail.com Stable-dep-of: b684c09f09e7 ("powerpc: update ppc_save_regs to save current r1 in pt_regs") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/ppc_save_regs.S | 57 ++++++++--------------------- 1 file changed, 15 insertions(+), 42 deletions(-)
diff --git a/arch/powerpc/kernel/ppc_save_regs.S b/arch/powerpc/kernel/ppc_save_regs.S index 2d4d21bb46a97..6e86f3bf46735 100644 --- a/arch/powerpc/kernel/ppc_save_regs.S +++ b/arch/powerpc/kernel/ppc_save_regs.S @@ -21,60 +21,33 @@ * different ABIs, though). */ _GLOBAL(ppc_save_regs) - PPC_STL r0,0*SZL(r3) + /* This allows stack frame accessor macros and offsets to be used */ + subi r3,r3,STACK_FRAME_OVERHEAD + PPC_STL r0,GPR0(r3) #ifdef CONFIG_PPC32 - stmw r2, 2*SZL(r3) + stmw r2,GPR2(r3) #else - PPC_STL r2,2*SZL(r3) - PPC_STL r3,3*SZL(r3) - PPC_STL r4,4*SZL(r3) - PPC_STL r5,5*SZL(r3) - PPC_STL r6,6*SZL(r3) - PPC_STL r7,7*SZL(r3) - PPC_STL r8,8*SZL(r3) - PPC_STL r9,9*SZL(r3) - PPC_STL r10,10*SZL(r3) - PPC_STL r11,11*SZL(r3) - PPC_STL r12,12*SZL(r3) - PPC_STL r13,13*SZL(r3) - PPC_STL r14,14*SZL(r3) - PPC_STL r15,15*SZL(r3) - PPC_STL r16,16*SZL(r3) - PPC_STL r17,17*SZL(r3) - PPC_STL r18,18*SZL(r3) - PPC_STL r19,19*SZL(r3) - PPC_STL r20,20*SZL(r3) - PPC_STL r21,21*SZL(r3) - PPC_STL r22,22*SZL(r3) - PPC_STL r23,23*SZL(r3) - PPC_STL r24,24*SZL(r3) - PPC_STL r25,25*SZL(r3) - PPC_STL r26,26*SZL(r3) - PPC_STL r27,27*SZL(r3) - PPC_STL r28,28*SZL(r3) - PPC_STL r29,29*SZL(r3) - PPC_STL r30,30*SZL(r3) - PPC_STL r31,31*SZL(r3) + SAVE_GPRS(2, 31, r3) lbz r0,PACAIRQSOFTMASK(r13) - PPC_STL r0,SOFTE-STACK_FRAME_OVERHEAD(r3) + PPC_STL r0,SOFTE(r3) #endif /* go up one stack frame for SP */ PPC_LL r4,0(r1) - PPC_STL r4,1*SZL(r3) + PPC_STL r4,GPR1(r3) /* get caller's LR */ PPC_LL r0,LRSAVE(r4) - PPC_STL r0,_LINK-STACK_FRAME_OVERHEAD(r3) + PPC_STL r0,_LINK(r3) mflr r0 - PPC_STL r0,_NIP-STACK_FRAME_OVERHEAD(r3) + PPC_STL r0,_NIP(r3) mfmsr r0 - PPC_STL r0,_MSR-STACK_FRAME_OVERHEAD(r3) + PPC_STL r0,_MSR(r3) mfctr r0 - PPC_STL r0,_CTR-STACK_FRAME_OVERHEAD(r3) + PPC_STL r0,_CTR(r3) mfxer r0 - PPC_STL r0,_XER-STACK_FRAME_OVERHEAD(r3) + PPC_STL r0,_XER(r3) mfcr r0 - PPC_STL r0,_CCR-STACK_FRAME_OVERHEAD(r3) + PPC_STL r0,_CCR(r3) li r0,0 - PPC_STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3) - PPC_STL r0,ORIG_GPR3-STACK_FRAME_OVERHEAD(r3) + PPC_STL r0,_TRAP(r3) + PPC_STL r0,ORIG_GPR3(r3) blr
From: Aditya Gupta adityag@linux.ibm.com
[ Upstream commit b684c09f09e7a6af3794d4233ef785819e72db79 ]
ppc_save_regs() skips one stack frame while saving the CPU register states. Instead of saving current R1, it pulls the previous stack frame pointer.
When vmcores caused by direct panic call (such as `echo c > /proc/sysrq-trigger`), are debugged with gdb, gdb fails to show the backtrace correctly. On further analysis, it was found that it was because of mismatch between r1 and NIP.
GDB uses NIP to get current function symbol and uses corresponding debug info of that function to unwind previous frames, but due to the mismatching r1 and NIP, the unwinding does not work, and it fails to unwind to the 2nd frame and hence does not show the backtrace.
GDB backtrace with vmcore of kernel without this patch:
--------- (gdb) bt #0 0xc0000000002a53e8 in crash_setup_regs (oldregs=<optimized out>, newregs=0xc000000004f8f8d8) at ./arch/powerpc/include/asm/kexec.h:69 #1 __crash_kexec (regs=<optimized out>) at kernel/kexec_core.c:974 #2 0x0000000000000063 in ?? () #3 0xc000000003579320 in ?? () ---------
Further analysis revealed that the mismatch occurred because "ppc_save_regs" was saving the previous stack's SP instead of the current r1. This patch fixes this by storing current r1 in the saved pt_regs.
GDB backtrace with vmcore of patched kernel:
-------- (gdb) bt #0 0xc0000000002a53e8 in crash_setup_regs (oldregs=0x0, newregs=0xc00000000670b8d8) at ./arch/powerpc/include/asm/kexec.h:69 #1 __crash_kexec (regs=regs@entry=0x0) at kernel/kexec_core.c:974 #2 0xc000000000168918 in panic (fmt=fmt@entry=0xc000000001654a60 "sysrq triggered crash\n") at kernel/panic.c:358 #3 0xc000000000b735f8 in sysrq_handle_crash (key=<optimized out>) at drivers/tty/sysrq.c:155 #4 0xc000000000b742cc in __handle_sysrq (key=key@entry=99, check_mask=check_mask@entry=false) at drivers/tty/sysrq.c:602 #5 0xc000000000b7506c in write_sysrq_trigger (file=<optimized out>, buf=<optimized out>, count=2, ppos=<optimized out>) at drivers/tty/sysrq.c:1163 #6 0xc00000000069a7bc in pde_write (ppos=<optimized out>, count=<optimized out>, buf=<optimized out>, file=<optimized out>, pde=0xc00000000362cb40) at fs/proc/inode.c:340 #7 proc_reg_write (file=<optimized out>, buf=<optimized out>, count=<optimized out>, ppos=<optimized out>) at fs/proc/inode.c:352 #8 0xc0000000005b3bbc in vfs_write (file=file@entry=0xc000000006aa6b00, buf=buf@entry=0x61f498b4f60 <error: Cannot access memory at address 0x61f498b4f60>, count=count@entry=2, pos=pos@entry=0xc00000000670bda0) at fs/read_write.c:582 #9 0xc0000000005b4264 in ksys_write (fd=<optimized out>, buf=0x61f498b4f60 <error: Cannot access memory at address 0x61f498b4f60>, count=2) at fs/read_write.c:637 #10 0xc00000000002ea2c in system_call_exception (regs=0xc00000000670be80, r0=<optimized out>) at arch/powerpc/kernel/syscall.c:171 #11 0xc00000000000c270 in system_call_vectored_common () at arch/powerpc/kernel/interrupt_64.S:192 --------
Nick adds: So this now saves regs as though it was an interrupt taken in the caller, at the instruction after the call to ppc_save_regs, whereas previously the NIP was there, but R1 came from the caller's caller and that mismatch is what causes gdb's dwarf unwinder to go haywire.
Signed-off-by: Aditya Gupta adityag@linux.ibm.com Fixes: d16a58f8854b1 ("powerpc: Improve ppc_save_regs()") Reivewed-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230615091047.90433-1-adityag@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/ppc_save_regs.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/ppc_save_regs.S b/arch/powerpc/kernel/ppc_save_regs.S index 6e86f3bf46735..235ae24284519 100644 --- a/arch/powerpc/kernel/ppc_save_regs.S +++ b/arch/powerpc/kernel/ppc_save_regs.S @@ -31,10 +31,10 @@ _GLOBAL(ppc_save_regs) lbz r0,PACAIRQSOFTMASK(r13) PPC_STL r0,SOFTE(r3) #endif - /* go up one stack frame for SP */ - PPC_LL r4,0(r1) - PPC_STL r4,GPR1(r3) + /* store current SP */ + PPC_STL r1,GPR1(r3) /* get caller's LR */ + PPC_LL r4,0(r1) PPC_LL r0,LRSAVE(r4) PPC_STL r0,_LINK(r3) mflr r0
From: Tiezhu Yang yangtiezhu@loongson.cn
[ Upstream commit 58b1294dd1d65bb62f08dddbf418f954210c2057 ]
thread.bad_cause is saved in arch_uprobe_pre_xol(), it should be restored in arch_uprobe_{post,abort}_xol() accordingly, otherwise the save operation is meaningless, this change is similar with x86 and powerpc.
Signed-off-by: Tiezhu Yang yangtiezhu@loongson.cn Acked-by: Oleg Nesterov oleg@redhat.com Reviewed-by: Guo Ren guoren@kernel.org Fixes: 74784081aac8 ("riscv: Add uprobes supported") Link: https://lore.kernel.org/r/1682214146-3756-1-git-send-email-yangtiezhu@loongs... Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/kernel/probes/uprobes.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/riscv/kernel/probes/uprobes.c b/arch/riscv/kernel/probes/uprobes.c index c976a21cd4bd5..194f166b2cc40 100644 --- a/arch/riscv/kernel/probes/uprobes.c +++ b/arch/riscv/kernel/probes/uprobes.c @@ -67,6 +67,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) struct uprobe_task *utask = current->utask;
WARN_ON_ONCE(current->thread.bad_cause != UPROBE_TRAP_NR); + current->thread.bad_cause = utask->autask.saved_cause;
instruction_pointer_set(regs, utask->vaddr + auprobe->insn_size);
@@ -102,6 +103,7 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) { struct uprobe_task *utask = current->utask;
+ current->thread.bad_cause = utask->autask.saved_cause; /* * Task has received a fatal signal, so reset back to probbed * address.
From: Laurent Vivier lvivier@redhat.com
[ Upstream commit bf3175bc50a3754dc427e2f5046e17a9fafc8be7 ]
hwrng core uses two buffers that can be mixed in the virtio-rng queue.
If the buffer is provided with wait=0 it is enqueued in the virtio-rng queue but unused by the caller. On the next call, core provides another buffer but the first one is filled instead and the new one queued. And the caller reads the data from the new one that is not updated, and the data in the first one are lost.
To avoid this mix, virtio-rng needs to use its own unique internal buffer at a cost of a data copy to the caller buffer.
Signed-off-by: Laurent Vivier lvivier@redhat.com Link: https://lore.kernel.org/r/20211028101111.128049-2-lvivier@redhat.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Stable-dep-of: ac52578d6e8d ("hwrng: virtio - Fix race on data_avail and actual data") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/virtio-rng.c | 43 ++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 10 deletions(-)
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index a90001e02bf7a..208c547dcac16 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -18,13 +18,20 @@ static DEFINE_IDA(rng_index_ida); struct virtrng_info { struct hwrng hwrng; struct virtqueue *vq; - struct completion have_data; char name[25]; - unsigned int data_avail; int index; bool busy; bool hwrng_register_done; bool hwrng_removed; + /* data transfer */ + struct completion have_data; + unsigned int data_avail; + /* minimal size returned by rng_buffer_size() */ +#if SMP_CACHE_BYTES < 32 + u8 data[32]; +#else + u8 data[SMP_CACHE_BYTES]; +#endif };
static void random_recv_done(struct virtqueue *vq) @@ -39,14 +46,14 @@ static void random_recv_done(struct virtqueue *vq) }
/* The host will fill any buffer we give it with sweet, sweet randomness. */ -static void register_buffer(struct virtrng_info *vi, u8 *buf, size_t size) +static void register_buffer(struct virtrng_info *vi) { struct scatterlist sg;
- sg_init_one(&sg, buf, size); + sg_init_one(&sg, vi->data, sizeof(vi->data));
/* There should always be room for one buffer. */ - virtqueue_add_inbuf(vi->vq, &sg, 1, buf, GFP_KERNEL); + virtqueue_add_inbuf(vi->vq, &sg, 1, vi->data, GFP_KERNEL);
virtqueue_kick(vi->vq); } @@ -55,6 +62,8 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) { int ret; struct virtrng_info *vi = (struct virtrng_info *)rng->priv; + unsigned int chunk; + size_t read;
if (vi->hwrng_removed) return -ENODEV; @@ -62,19 +71,33 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) if (!vi->busy) { vi->busy = true; reinit_completion(&vi->have_data); - register_buffer(vi, buf, size); + register_buffer(vi); }
if (!wait) return 0;
- ret = wait_for_completion_killable(&vi->have_data); - if (ret < 0) - return ret; + read = 0; + while (size != 0) { + ret = wait_for_completion_killable(&vi->have_data); + if (ret < 0) + return ret; + + chunk = min_t(unsigned int, size, vi->data_avail); + memcpy(buf + read, vi->data, chunk); + read += chunk; + size -= chunk; + vi->data_avail = 0; + + if (size != 0) { + reinit_completion(&vi->have_data); + register_buffer(vi); + } + }
vi->busy = false;
- return vi->data_avail; + return read; }
static void virtio_cleanup(struct hwrng *rng)
From: Laurent Vivier lvivier@redhat.com
[ Upstream commit 2bb31abdbe55742c89f4dc0cc26fcbc8467364f6 ]
When virtio-rng device was dropped by the hwrng core we were forced to wait the buffer to come back from the device to not have remaining ongoing operation that could spoil the buffer.
But now, as the buffer is internal to the virtio-rng we can release the waiting loop immediately, the buffer will be retrieve and use when the virtio-rng driver will be selected again.
This avoids to hang on an rng_current write command if the virtio-rng device is blocked by a lack of entropy. This allows to select another entropy source if the current one is empty.
Signed-off-by: Laurent Vivier lvivier@redhat.com Link: https://lore.kernel.org/r/20211028101111.128049-3-lvivier@redhat.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Stable-dep-of: ac52578d6e8d ("hwrng: virtio - Fix race on data_avail and actual data") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/virtio-rng.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 208c547dcac16..173aeea835bb6 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -82,6 +82,11 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) ret = wait_for_completion_killable(&vi->have_data); if (ret < 0) return ret; + /* if vi->data_avail is 0, we have been interrupted + * by a cleanup, but buffer stays in the queue + */ + if (vi->data_avail == 0) + return read;
chunk = min_t(unsigned int, size, vi->data_avail); memcpy(buf + read, vi->data, chunk); @@ -105,7 +110,7 @@ static void virtio_cleanup(struct hwrng *rng) struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
if (vi->busy) - wait_for_completion(&vi->have_data); + complete(&vi->have_data); }
static int probe_common(struct virtio_device *vdev)
From: Laurent Vivier lvivier@redhat.com
[ Upstream commit 5c8e933050044d6dd2a000f9a5756ae73cbe7c44 ]
if we don't use all the entropy available in the buffer, keep it and use it later.
Signed-off-by: Laurent Vivier lvivier@redhat.com Link: https://lore.kernel.org/r/20211028101111.128049-4-lvivier@redhat.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Stable-dep-of: ac52578d6e8d ("hwrng: virtio - Fix race on data_avail and actual data") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/virtio-rng.c | 52 +++++++++++++++++++---------- 1 file changed, 35 insertions(+), 17 deletions(-)
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 173aeea835bb6..8ba97cf4ca8fb 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -26,6 +26,7 @@ struct virtrng_info { /* data transfer */ struct completion have_data; unsigned int data_avail; + unsigned int data_idx; /* minimal size returned by rng_buffer_size() */ #if SMP_CACHE_BYTES < 32 u8 data[32]; @@ -42,6 +43,9 @@ static void random_recv_done(struct virtqueue *vq) if (!virtqueue_get_buf(vi->vq, &vi->data_avail)) return;
+ vi->data_idx = 0; + vi->busy = false; + complete(&vi->have_data); }
@@ -58,6 +62,16 @@ static void register_buffer(struct virtrng_info *vi) virtqueue_kick(vi->vq); }
+static unsigned int copy_data(struct virtrng_info *vi, void *buf, + unsigned int size) +{ + size = min_t(unsigned int, size, vi->data_avail); + memcpy(buf, vi->data + vi->data_idx, size); + vi->data_idx += size; + vi->data_avail -= size; + return size; +} + static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) { int ret; @@ -68,17 +82,29 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) if (vi->hwrng_removed) return -ENODEV;
- if (!vi->busy) { - vi->busy = true; - reinit_completion(&vi->have_data); - register_buffer(vi); + read = 0; + + /* copy available data */ + if (vi->data_avail) { + chunk = copy_data(vi, buf, size); + size -= chunk; + read += chunk; }
if (!wait) - return 0; + return read;
- read = 0; + /* We have already copied available entropy, + * so either size is 0 or data_avail is 0 + */ while (size != 0) { + /* data_avail is 0 */ + if (!vi->busy) { + /* no pending request, ask for more */ + vi->busy = true; + reinit_completion(&vi->have_data); + register_buffer(vi); + } ret = wait_for_completion_killable(&vi->have_data); if (ret < 0) return ret; @@ -88,20 +114,11 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) if (vi->data_avail == 0) return read;
- chunk = min_t(unsigned int, size, vi->data_avail); - memcpy(buf + read, vi->data, chunk); - read += chunk; + chunk = copy_data(vi, buf + read, size); size -= chunk; - vi->data_avail = 0; - - if (size != 0) { - reinit_completion(&vi->have_data); - register_buffer(vi); - } + read += chunk; }
- vi->busy = false; - return read; }
@@ -161,6 +178,7 @@ static void remove_common(struct virtio_device *vdev)
vi->hwrng_removed = true; vi->data_avail = 0; + vi->data_idx = 0; complete(&vi->have_data); vdev->config->reset(vdev); vi->busy = false;
From: Laurent Vivier lvivier@redhat.com
[ Upstream commit 9a4b612d675b03f7fc9fa1957ca399c8223f3954 ]
If we ensure we have already some data available by enqueuing again the buffer once data are exhausted, we can return what we have without waiting for the device answer.
Signed-off-by: Laurent Vivier lvivier@redhat.com Link: https://lore.kernel.org/r/20211028101111.128049-5-lvivier@redhat.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Stable-dep-of: ac52578d6e8d ("hwrng: virtio - Fix race on data_avail and actual data") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/virtio-rng.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 8ba97cf4ca8fb..0a7dde135db19 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -20,7 +20,6 @@ struct virtrng_info { struct virtqueue *vq; char name[25]; int index; - bool busy; bool hwrng_register_done; bool hwrng_removed; /* data transfer */ @@ -44,16 +43,18 @@ static void random_recv_done(struct virtqueue *vq) return;
vi->data_idx = 0; - vi->busy = false;
complete(&vi->have_data); }
-/* The host will fill any buffer we give it with sweet, sweet randomness. */ -static void register_buffer(struct virtrng_info *vi) +static void request_entropy(struct virtrng_info *vi) { struct scatterlist sg;
+ reinit_completion(&vi->have_data); + vi->data_avail = 0; + vi->data_idx = 0; + sg_init_one(&sg, vi->data, sizeof(vi->data));
/* There should always be room for one buffer. */ @@ -69,6 +70,8 @@ static unsigned int copy_data(struct virtrng_info *vi, void *buf, memcpy(buf, vi->data + vi->data_idx, size); vi->data_idx += size; vi->data_avail -= size; + if (vi->data_avail == 0) + request_entropy(vi); return size; }
@@ -98,13 +101,7 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) * so either size is 0 or data_avail is 0 */ while (size != 0) { - /* data_avail is 0 */ - if (!vi->busy) { - /* no pending request, ask for more */ - vi->busy = true; - reinit_completion(&vi->have_data); - register_buffer(vi); - } + /* data_avail is 0 but a request is pending */ ret = wait_for_completion_killable(&vi->have_data); if (ret < 0) return ret; @@ -126,8 +123,7 @@ static void virtio_cleanup(struct hwrng *rng) { struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
- if (vi->busy) - complete(&vi->have_data); + complete(&vi->have_data); }
static int probe_common(struct virtio_device *vdev) @@ -163,6 +159,9 @@ static int probe_common(struct virtio_device *vdev) goto err_find; }
+ /* we always have a pending entropy request */ + request_entropy(vi); + return 0;
err_find: @@ -181,7 +180,6 @@ static void remove_common(struct virtio_device *vdev) vi->data_idx = 0; complete(&vi->have_data); vdev->config->reset(vdev); - vi->busy = false; if (vi->hwrng_register_done) hwrng_unregister(&vi->hwrng); vdev->config->del_vqs(vdev);
From: Herbert Xu herbert@gondor.apana.org.au
[ Upstream commit ac52578d6e8d300dd50f790f29a24169b1edd26c ]
The virtio rng device kicks off a new entropy request whenever the data available reaches zero. When a new request occurs at the end of a read operation, that is, when the result of that request is only needed by the next reader, then there is a race between the writing of the new data and the next reader.
This is because there is no synchronisation whatsoever between the writer and the reader.
Fix this by writing data_avail with smp_store_release and reading it with smp_load_acquire when we first enter read. The subsequent reads are safe because they're either protected by the first load acquire, or by the completion mechanism.
Also remove the redundant zeroing of data_idx in random_recv_done (data_idx must already be zero at this point) and data_avail in request_entropy (ditto).
Reported-by: syzbot+726dc8c62c3536431ceb@syzkaller.appspotmail.com Fixes: f7f510ec1957 ("virtio: An entropy device, as suggested by hpa.") Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Acked-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/virtio-rng.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 0a7dde135db19..3a194eb3ce8ad 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -4,6 +4,7 @@ * Copyright (C) 2007, 2008 Rusty Russell IBM Corporation */
+#include <asm/barrier.h> #include <linux/err.h> #include <linux/hw_random.h> #include <linux/scatterlist.h> @@ -37,13 +38,13 @@ struct virtrng_info { static void random_recv_done(struct virtqueue *vq) { struct virtrng_info *vi = vq->vdev->priv; + unsigned int len;
/* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */ - if (!virtqueue_get_buf(vi->vq, &vi->data_avail)) + if (!virtqueue_get_buf(vi->vq, &len)) return;
- vi->data_idx = 0; - + smp_store_release(&vi->data_avail, len); complete(&vi->have_data); }
@@ -52,7 +53,6 @@ static void request_entropy(struct virtrng_info *vi) struct scatterlist sg;
reinit_completion(&vi->have_data); - vi->data_avail = 0; vi->data_idx = 0;
sg_init_one(&sg, vi->data, sizeof(vi->data)); @@ -88,7 +88,7 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) read = 0;
/* copy available data */ - if (vi->data_avail) { + if (smp_load_acquire(&vi->data_avail)) { chunk = copy_data(vi, buf, size); size -= chunk; read += chunk;
From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit d0acc76a49aa917c1a455d11d32d34a01e8b2835 ]
find_extable_entry_size() is completely broken. It has awesome comments about how to calculate sizeof(struct exception_table_entry).
It was based on these assumptions:
- struct exception_table_entry has two fields - both of the fields have the same size
Then, we came up with this equation:
(offset of the second field) * 2 == (size of struct)
It was true for all architectures when commit 52dc0595d540 ("modpost: handle relocations mismatch in __ex_table.") was applied.
Our mathematics broke when commit 548acf19234d ("x86/mm: Expand the exception table logic to allow new handling options") introduced the third field.
Now, the definition of exception_table_entry is highly arch-dependent.
For x86, sizeof(struct exception_table_entry) is apparently 12, but find_extable_entry_size() sets extable_entry_size to 8.
I could fix it, but I do not see much value in this code.
extable_entry_size is used just for selecting a slightly different error message.
If the first field ("insn") references to a non-executable section,
The relocation at %s+0x%lx references section "%s" which is not executable, IOW it is not possible for the kernel to fault at that address. Something is seriously wrong and should be fixed.
If the second field ("fixup") references to a non-executable section,
The relocation at %s+0x%lx references section "%s" which is not executable, IOW the kernel will fault if it ever tries to jump to it. Something is seriously wrong and should be fixed.
Merge the two error messages rather than adding even more complexity.
Change fatal() to error() to make it continue running and catch more possible errors.
Fixes: 548acf19234d ("x86/mm: Expand the exception table logic to allow new handling options") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/mod/modpost.c | 60 +++---------------------------------------- 1 file changed, 3 insertions(+), 57 deletions(-)
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b284ee01fdebb..b29af4ad08321 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1612,43 +1612,6 @@ static int is_executable_section(struct elf_info* elf, unsigned int section_inde return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR); }
-/* - * We rely on a gross hack in section_rel[a]() calling find_extable_entry_size() - * to know the sizeof(struct exception_table_entry) for the target architecture. - */ -static unsigned int extable_entry_size = 0; -static void find_extable_entry_size(const char* const sec, const Elf_Rela* r) -{ - /* - * If we're currently checking the second relocation within __ex_table, - * that relocation offset tells us the offsetof(struct - * exception_table_entry, fixup) which is equal to sizeof(struct - * exception_table_entry) divided by two. We use that to our advantage - * since there's no portable way to get that size as every architecture - * seems to go with different sized types. Not pretty but better than - * hard-coding the size for every architecture.. - */ - if (!extable_entry_size) - extable_entry_size = r->r_offset * 2; -} - -static inline bool is_extable_fault_address(Elf_Rela *r) -{ - /* - * extable_entry_size is only discovered after we've handled the - * _second_ relocation in __ex_table, so only abort when we're not - * handling the first reloc and extable_entry_size is zero. - */ - if (r->r_offset && extable_entry_size == 0) - fatal("extable_entry size hasn't been discovered!\n"); - - return ((r->r_offset == 0) || - (r->r_offset % extable_entry_size == 0)); -} - -#define is_second_extable_reloc(Start, Cur, Sec) \ - (((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0)) - static void report_extable_warnings(const char* modname, struct elf_info* elf, const struct sectioncheck* const mismatch, Elf_Rela* r, Elf_Sym* sym, @@ -1705,22 +1668,9 @@ static void extable_mismatch_handler(const char* modname, struct elf_info *elf, "You might get more information about where this is\n" "coming from by using scripts/check_extable.sh %s\n", fromsec, (long)r->r_offset, tosec, modname); - else if (!is_executable_section(elf, get_secindex(elf, sym))) { - if (is_extable_fault_address(r)) - fatal("The relocation at %s+0x%lx references\n" - "section "%s" which is not executable, IOW\n" - "it is not possible for the kernel to fault\n" - "at that address. Something is seriously wrong\n" - "and should be fixed.\n", - fromsec, (long)r->r_offset, tosec); - else - fatal("The relocation at %s+0x%lx references\n" - "section "%s" which is not executable, IOW\n" - "the kernel will fault if it ever tries to\n" - "jump to it. Something is seriously wrong\n" - "and should be fixed.\n", - fromsec, (long)r->r_offset, tosec); - } + else if (!is_executable_section(elf, get_secindex(elf, sym))) + error("%s+0x%lx references non-executable section '%s'\n", + fromsec, (long)r->r_offset, tosec); }
static void check_section_mismatch(const char *modname, struct elf_info *elf, @@ -1871,8 +1821,6 @@ static void section_rela(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - if (is_second_extable_reloc(start, rela, fromsec)) - find_extable_entry_size(fromsec, &r); check_section_mismatch(modname, elf, &r, sym, fromsec); } } @@ -1931,8 +1879,6 @@ static void section_rel(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - if (is_second_extable_reloc(start, rel, fromsec)) - find_extable_entry_size(fromsec, &r); check_section_mismatch(modname, elf, &r, sym, fromsec); } }
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit b04b076fb56560b39d695ac3744db457e12278fd ]
Fix build warnings when DEBUG_FS is not enabled by using an empty do-while loop instead of a value:
In file included from ../drivers/crypto/nx/nx.c:27: ../drivers/crypto/nx/nx.c: In function 'nx_register_algs': ../drivers/crypto/nx/nx.h:173:33: warning: statement with no effect [-Wunused-value] 173 | #define NX_DEBUGFS_INIT(drv) (0) ../drivers/crypto/nx/nx.c:573:9: note: in expansion of macro 'NX_DEBUGFS_INIT' 573 | NX_DEBUGFS_INIT(&nx_driver); ../drivers/crypto/nx/nx.c: In function 'nx_remove': ../drivers/crypto/nx/nx.h:174:33: warning: statement with no effect [-Wunused-value] 174 | #define NX_DEBUGFS_FINI(drv) (0) ../drivers/crypto/nx/nx.c:793:17: note: in expansion of macro 'NX_DEBUGFS_FINI' 793 | NX_DEBUGFS_FINI(&nx_driver);
Also, there is no need to build nx_debugfs.o when DEBUG_FS is not enabled, so change the Makefile to accommodate that.
Fixes: ae0222b7289d ("powerpc/crypto: nx driver code supporting nx encryption") Fixes: aef7b31c8833 ("powerpc/crypto: Build files for the nx device driver") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Breno Leitão leitao@debian.org Cc: Nayna Jain nayna@linux.ibm.com Cc: Paulo Flabiano Smorigo pfsmorigo@gmail.com Cc: Herbert Xu herbert@gondor.apana.org.au Cc: "David S. Miller" davem@davemloft.net Cc: linux-crypto@vger.kernel.org Cc: Michael Ellerman mpe@ellerman.id.au Cc: Nicholas Piggin npiggin@gmail.com Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/nx/Makefile | 2 +- drivers/crypto/nx/nx.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/nx/Makefile b/drivers/crypto/nx/Makefile index d00181a26dd65..483cef62acee8 100644 --- a/drivers/crypto/nx/Makefile +++ b/drivers/crypto/nx/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_CRYPTO_DEV_NX_ENCRYPT) += nx-crypto.o nx-crypto-objs := nx.o \ - nx_debugfs.o \ nx-aes-cbc.o \ nx-aes-ecb.o \ nx-aes-gcm.o \ @@ -11,6 +10,7 @@ nx-crypto-objs := nx.o \ nx-sha256.o \ nx-sha512.o
+nx-crypto-$(CONFIG_DEBUG_FS) += nx_debugfs.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o nx-compress.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o nx-compress.o nx-compress-objs := nx-842.o diff --git a/drivers/crypto/nx/nx.h b/drivers/crypto/nx/nx.h index c6233173c612e..2697baebb6a35 100644 --- a/drivers/crypto/nx/nx.h +++ b/drivers/crypto/nx/nx.h @@ -170,8 +170,8 @@ struct nx_sg *nx_walk_and_build(struct nx_sg *, unsigned int, void nx_debugfs_init(struct nx_crypto_driver *); void nx_debugfs_fini(struct nx_crypto_driver *); #else -#define NX_DEBUGFS_INIT(drv) (0) -#define NX_DEBUGFS_FINI(drv) (0) +#define NX_DEBUGFS_INIT(drv) do {} while (0) +#define NX_DEBUGFS_FINI(drv) do {} while (0) #endif
#define NX_PAGE_NUM(x) ((u64)(x) & 0xfffffffffffff000ULL)
From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit b7c63520f6703a25eebb4f8138fed764fcae1c6f ]
addend_arm_rel() processes R_ARM_ABS32 in a wrong way.
Here, test code.
[test code 1]
#include <linux/init.h>
int __initdata foo; int get_foo(void) { return foo; }
If you compile it with ARM versatile_defconfig, modpost will show the symbol name, (unknown).
WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> (unknown) (section: .init.data)
(You need to use GNU linker instead of LLD to reproduce it.)
If you compile it for other architectures, modpost will show the correct symbol name.
WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> foo (section: .init.data)
For R_ARM_ABS32, addend_arm_rel() sets r->r_addend to a wrong value.
I just mimicked the code in arch/arm/kernel/module.c.
However, there is more difficulty for ARM.
Here, test code.
[test code 2]
#include <linux/init.h>
int __initdata foo; int get_foo(void) { return foo; }
int __initdata bar; int get_bar(void) { return bar; }
With this commit applied, modpost will show the following messages for ARM versatile_defconfig:
WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> foo (section: .init.data) WARNING: modpost: vmlinux.o: section mismatch in reference: get_bar (section: .text) -> foo (section: .init.data)
The reference from 'get_bar' to 'foo' seems wrong.
I have no solution for this because it is true in assembly level.
In the following output, relocation at 0x1c is no longer associated with 'bar'. The two relocation entries point to the same symbol, and the offset to 'bar' is encoded in the instruction 'r0, [r3, #4]'.
Disassembly of section .text:
00000000 <get_foo>: 0: e59f3004 ldr r3, [pc, #4] @ c <get_foo+0xc> 4: e5930000 ldr r0, [r3] 8: e12fff1e bx lr c: 00000000 .word 0x00000000
00000010 <get_bar>: 10: e59f3004 ldr r3, [pc, #4] @ 1c <get_bar+0xc> 14: e5930004 ldr r0, [r3, #4] 18: e12fff1e bx lr 1c: 00000000 .word 0x00000000
Relocation section '.rel.text' at offset 0x244 contains 2 entries: Offset Info Type Sym.Value Sym. Name 0000000c 00000c02 R_ARM_ABS32 00000000 .init.data 0000001c 00000c02 R_ARM_ABS32 00000000 .init.data
When find_elf_symbol() gets into a situation where relsym->st_name is zero, there is no guarantee to get the symbol name as written in C.
I am keeping the current logic because it is useful in many architectures, but the symbol name is not always correct depending on the optimization. I left some comments in find_tosym().
Fixes: 56a974fa2d59 ("kbuild: make better section mismatch reports on arm") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/mod/modpost.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b29af4ad08321..789e0ddb41ae4 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1302,6 +1302,10 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr, if (relsym->st_name != 0) return relsym;
+ /* + * Strive to find a better symbol name, but the resulting name may not + * match the symbol referenced in the original code. + */ relsym_secindex = get_secindex(elf, relsym); for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { if (get_secindex(elf, sym) != relsym_secindex) @@ -1734,12 +1738,14 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) { unsigned int r_typ = ELF_R_TYPE(r->r_info); + Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info); + void *loc = reloc_location(elf, sechdr, r); + uint32_t inst;
switch (r_typ) { case R_ARM_ABS32: - /* From ARM ABI: (S + A) | T */ - r->r_addend = (int)(long) - (elf->symtab_start + ELF_R_SYM(r->r_info)); + inst = TO_NATIVE(*(uint32_t *)loc); + r->r_addend = inst + sym->st_value; break; case R_ARM_PC24: case R_ARM_CALL:
From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit 56a24b8ce6a7f9c4a21b2276a8644f6f3d8fc14d ]
addend_arm_rel() processes R_ARM_PC24, R_ARM_CALL, R_ARM_JUMP24 in a wrong way.
Here, test code.
[test code for R_ARM_JUMP24]
.section .init.text,"ax" bar: bx lr
.section .text,"ax" .globl foo foo: b bar
[test code for R_ARM_CALL]
.section .init.text,"ax" bar: bx lr
.section .text,"ax" .globl foo foo: push {lr} bl bar pop {pc}
If you compile it with ARM multi_v7_defconfig, modpost will show the symbol name, (unknown).
WARNING: modpost: vmlinux.o: section mismatch in reference: foo (section: .text) -> (unknown) (section: .init.text)
(You need to use GNU linker instead of LLD to reproduce it.)
Fix the code to make modpost show the correct symbol name.
I imported (with adjustment) sign_extend32() from include/linux/bitops.h.
The '+8' is the compensation for pc-relative instruction. It is documented in "ELF for the Arm Architecture" [1].
"If the relocation is pc-relative then compensation for the PC bias (the PC value is 8 bytes ahead of the executing instruction in Arm state and 4 bytes in Thumb state) must be encoded in the relocation by the object producer."
[1]: https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst
Fixes: 56a974fa2d59 ("kbuild: make better section mismatch reports on arm") Fixes: 6e2e340b59d2 ("ARM: 7324/1: modpost: Fix section warnings for ARM for many compilers") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/mod/modpost.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 789e0ddb41ae4..78859ef4e03ad 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1735,12 +1735,20 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) #define R_ARM_THM_JUMP19 51 #endif
+static int32_t sign_extend32(int32_t value, int index) +{ + uint8_t shift = 31 - index; + + return (int32_t)(value << shift) >> shift; +} + static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) { unsigned int r_typ = ELF_R_TYPE(r->r_info); Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info); void *loc = reloc_location(elf, sechdr, r); uint32_t inst; + int32_t offset;
switch (r_typ) { case R_ARM_ABS32: @@ -1750,6 +1758,10 @@ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) case R_ARM_PC24: case R_ARM_CALL: case R_ARM_JUMP24: + inst = TO_NATIVE(*(uint32_t *)loc); + offset = sign_extend32((inst & 0x00ffffff) << 2, 25); + r->r_addend = offset + sym->st_value + 8; + break; case R_ARM_THM_CALL: case R_ARM_THM_JUMP24: case R_ARM_THM_JUMP19:
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit efbc7764c4446566edb76ca05e903b5905673d2e ]
Commit df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3") uncovered a type mismatch in cesa 3des support that leads to a memcpy beyond the end of a structure:
In function 'fortify_memcpy_chk', inlined from 'mv_cesa_des3_ede_setkey' at drivers/crypto/marvell/cesa/cipher.c:307:2: include/linux/fortify-string.h:583:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning] 583 | __write_overflow_field(p_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is probably harmless as the actual data that is copied has the correct type, but clearly worth fixing nonetheless.
Fixes: 4ada48397823 ("crypto: marvell/cesa - add Triple-DES support") Cc: Kees Cook keescook@chromium.org Cc: Gustavo A. R. Silva gustavoars@kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/marvell/cesa/cipher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/marvell/cesa/cipher.c b/drivers/crypto/marvell/cesa/cipher.c index c6f2fa753b7c0..0f37dfd42d850 100644 --- a/drivers/crypto/marvell/cesa/cipher.c +++ b/drivers/crypto/marvell/cesa/cipher.c @@ -297,7 +297,7 @@ static int mv_cesa_des_setkey(struct crypto_skcipher *cipher, const u8 *key, static int mv_cesa_des3_ede_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int len) { - struct mv_cesa_des_ctx *ctx = crypto_skcipher_ctx(cipher); + struct mv_cesa_des3_ctx *ctx = crypto_skcipher_ctx(cipher); int err;
err = verify_skcipher_des3_key(cipher, key);
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit 3a3f1e573a105328a2cca45a7cfbebabbf5e3192 ]
The > comparison should be >= to prevent an out of bounds array access.
Fixes: 52dc0595d540 ("modpost: handle relocations mismatch in __ex_table.") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 78859ef4e03ad..c6e655e0ed988 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1610,7 +1610,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
static int is_executable_section(struct elf_info* elf, unsigned int section_index) { - if (section_index > elf->num_sections) + if (section_index >= elf->num_sections) fatal("section_index is outside elf->num_sections!\n");
return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR);
From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit 92e2921eeafdfca9acd9b83f07d2b7ca099bac24 ]
ASM_NL is useful not only in *.S files but also in .c files for using inline assembler in C code.
On ARC, however, ASM_NL is evaluated inconsistently. It is expanded to a backquote (`) in *.S files, but a semicolon (;) in *.c files because arch/arc/include/asm/linkage.h defines it inside #ifdef __ASSEMBLY__, so the definition for C code falls back to the default value defined in include/linux/linkage.h.
If ASM_NL is used in inline assembler in .c files, it will result in wrong assembly code because a semicolon is not an instruction separator, but the start of a comment for ARC.
Move ASM_NL (also __ALIGN and __ALIGN_STR) out of the #ifdef.
Fixes: 9df62f054406 ("arch: use ASM_NL instead of ';' for assembler new line character in the macro") Fixes: 8d92e992a785 ("ARC: define __ALIGN_STR and __ALIGN symbols for ARC") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arc/include/asm/linkage.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arc/include/asm/linkage.h b/arch/arc/include/asm/linkage.h index c9434ff3aa4ce..8a3fb71e9cfad 100644 --- a/arch/arc/include/asm/linkage.h +++ b/arch/arc/include/asm/linkage.h @@ -8,6 +8,10 @@
#include <asm/dwarf.h>
+#define ASM_NL ` /* use '`' to mark new line in macro */ +#define __ALIGN .align 4 +#define __ALIGN_STR __stringify(__ALIGN) + #ifdef __ASSEMBLY__
.macro ST2 e, o, off @@ -28,10 +32,6 @@ #endif .endm
-#define ASM_NL ` /* use '`' to mark new line in macro */ -#define __ALIGN .align 4 -#define __ALIGN_STR __stringify(__ALIGN) - /* annotation for data we want in DCCM - if enabled in .config */ .macro ARCFP_DATA nm #ifdef CONFIG_ARC_HAS_DCCM
From: Giovanni Cabiddu giovanni.cabiddu@intel.com
[ Upstream commit 8fb203c65a795b96faa1836b5086a5d6eb5c5e99 ]
If a request has the flag CRYPTO_TFM_REQ_MAY_SLEEP set, allocate memory using the flag GFP_KERNEL otherwise use GFP_ATOMIC.
Signed-off-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Reviewed-by: Adam Guerin adam.guerin@intel.com Reviewed-by: Wojciech Ziemba wojciech.ziemba@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Stable-dep-of: eb7713f5ca97 ("crypto: qat - unmap buffer before free for DH") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/qat_algs.c | 19 ++++++++++++------- drivers/crypto/qat/qat_common/qat_asym_algs.c | 17 ++++++++++------- drivers/crypto/qat/qat_common/qat_crypto.h | 5 +++++ 3 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c index 906082fbdd67b..d36f90628603c 100644 --- a/drivers/crypto/qat/qat_common/qat_algs.c +++ b/drivers/crypto/qat/qat_common/qat_algs.c @@ -706,7 +706,8 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst, static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, struct scatterlist *sgl, struct scatterlist *sglout, - struct qat_crypto_request *qat_req) + struct qat_crypto_request *qat_req, + gfp_t flags) { struct device *dev = &GET_DEV(inst->accel_dev); int i, sg_nctr = 0; @@ -727,7 +728,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, qat_req->buf.sgl_dst_valid = false;
if (n > QAT_MAX_BUFF_DESC) { - bufl = kzalloc_node(sz, GFP_ATOMIC, node); + bufl = kzalloc_node(sz, flags, node); if (unlikely(!bufl)) return -ENOMEM; } else { @@ -771,7 +772,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, sg_nctr = 0;
if (n > QAT_MAX_BUFF_DESC) { - buflout = kzalloc_node(sz_out, GFP_ATOMIC, node); + buflout = kzalloc_node(sz_out, flags, node); if (unlikely(!buflout)) goto err_in; } else { @@ -972,6 +973,7 @@ static int qat_alg_aead_dec(struct aead_request *areq) struct icp_qat_fw_la_auth_req_params *auth_param; struct icp_qat_fw_la_bulk_req *msg; int digst_size = crypto_aead_authsize(aead_tfm); + gfp_t f = qat_algs_alloc_flags(&areq->base); int ret; u32 cipher_len;
@@ -979,7 +981,7 @@ static int qat_alg_aead_dec(struct aead_request *areq) if (cipher_len % AES_BLOCK_SIZE != 0) return -EINVAL;
- ret = qat_alg_sgl_to_bufl(ctx->inst, areq->src, areq->dst, qat_req); + ret = qat_alg_sgl_to_bufl(ctx->inst, areq->src, areq->dst, qat_req, f); if (unlikely(ret)) return ret;
@@ -1014,6 +1016,7 @@ static int qat_alg_aead_enc(struct aead_request *areq) struct qat_crypto_request *qat_req = aead_request_ctx(areq); struct icp_qat_fw_la_cipher_req_params *cipher_param; struct icp_qat_fw_la_auth_req_params *auth_param; + gfp_t f = qat_algs_alloc_flags(&areq->base); struct icp_qat_fw_la_bulk_req *msg; u8 *iv = areq->iv; int ret; @@ -1021,7 +1024,7 @@ static int qat_alg_aead_enc(struct aead_request *areq) if (areq->cryptlen % AES_BLOCK_SIZE != 0) return -EINVAL;
- ret = qat_alg_sgl_to_bufl(ctx->inst, areq->src, areq->dst, qat_req); + ret = qat_alg_sgl_to_bufl(ctx->inst, areq->src, areq->dst, qat_req, f); if (unlikely(ret)) return ret;
@@ -1199,13 +1202,14 @@ static int qat_alg_skcipher_encrypt(struct skcipher_request *req) struct qat_alg_skcipher_ctx *ctx = crypto_tfm_ctx(tfm); struct qat_crypto_request *qat_req = skcipher_request_ctx(req); struct icp_qat_fw_la_cipher_req_params *cipher_param; + gfp_t f = qat_algs_alloc_flags(&req->base); struct icp_qat_fw_la_bulk_req *msg; int ret;
if (req->cryptlen == 0) return 0;
- ret = qat_alg_sgl_to_bufl(ctx->inst, req->src, req->dst, qat_req); + ret = qat_alg_sgl_to_bufl(ctx->inst, req->src, req->dst, qat_req, f); if (unlikely(ret)) return ret;
@@ -1264,13 +1268,14 @@ static int qat_alg_skcipher_decrypt(struct skcipher_request *req) struct qat_alg_skcipher_ctx *ctx = crypto_tfm_ctx(tfm); struct qat_crypto_request *qat_req = skcipher_request_ctx(req); struct icp_qat_fw_la_cipher_req_params *cipher_param; + gfp_t f = qat_algs_alloc_flags(&req->base); struct icp_qat_fw_la_bulk_req *msg; int ret;
if (req->cryptlen == 0) return 0;
- ret = qat_alg_sgl_to_bufl(ctx->inst, req->src, req->dst, qat_req); + ret = qat_alg_sgl_to_bufl(ctx->inst, req->src, req->dst, qat_req, f); if (unlikely(ret)) return ret;
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c index 5f11929cf9bac..11c7f2b6e5975 100644 --- a/drivers/crypto/qat/qat_common/qat_asym_algs.c +++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c @@ -224,9 +224,10 @@ static int qat_dh_compute_value(struct kpp_request *req) struct qat_asym_request *qat_req = PTR_ALIGN(kpp_request_ctx(req), 64); struct icp_qat_fw_pke_request *msg = &qat_req->req; - int ret; + gfp_t flags = qat_algs_alloc_flags(&req->base); int n_input_params = 0; u8 *vaddr; + int ret;
if (unlikely(!ctx->xa)) return -EINVAL; @@ -291,7 +292,7 @@ static int qat_dh_compute_value(struct kpp_request *req) } else { int shift = ctx->p_size - req->src_len;
- qat_req->src_align = kzalloc(ctx->p_size, GFP_KERNEL); + qat_req->src_align = kzalloc(ctx->p_size, flags); if (unlikely(!qat_req->src_align)) return ret;
@@ -317,7 +318,7 @@ static int qat_dh_compute_value(struct kpp_request *req) qat_req->dst_align = NULL; vaddr = sg_virt(req->dst); } else { - qat_req->dst_align = kzalloc(ctx->p_size, GFP_KERNEL); + qat_req->dst_align = kzalloc(ctx->p_size, flags); if (unlikely(!qat_req->dst_align)) goto unmap_src;
@@ -650,6 +651,7 @@ static int qat_rsa_enc(struct akcipher_request *req) struct qat_asym_request *qat_req = PTR_ALIGN(akcipher_request_ctx(req), 64); struct icp_qat_fw_pke_request *msg = &qat_req->req; + gfp_t flags = qat_algs_alloc_flags(&req->base); u8 *vaddr; int ret;
@@ -696,7 +698,7 @@ static int qat_rsa_enc(struct akcipher_request *req) } else { int shift = ctx->key_sz - req->src_len;
- qat_req->src_align = kzalloc(ctx->key_sz, GFP_KERNEL); + qat_req->src_align = kzalloc(ctx->key_sz, flags); if (unlikely(!qat_req->src_align)) return ret;
@@ -714,7 +716,7 @@ static int qat_rsa_enc(struct akcipher_request *req) qat_req->dst_align = NULL; vaddr = sg_virt(req->dst); } else { - qat_req->dst_align = kzalloc(ctx->key_sz, GFP_KERNEL); + qat_req->dst_align = kzalloc(ctx->key_sz, flags); if (unlikely(!qat_req->dst_align)) goto unmap_src; vaddr = qat_req->dst_align; @@ -783,6 +785,7 @@ static int qat_rsa_dec(struct akcipher_request *req) struct qat_asym_request *qat_req = PTR_ALIGN(akcipher_request_ctx(req), 64); struct icp_qat_fw_pke_request *msg = &qat_req->req; + gfp_t flags = qat_algs_alloc_flags(&req->base); u8 *vaddr; int ret;
@@ -839,7 +842,7 @@ static int qat_rsa_dec(struct akcipher_request *req) } else { int shift = ctx->key_sz - req->src_len;
- qat_req->src_align = kzalloc(ctx->key_sz, GFP_KERNEL); + qat_req->src_align = kzalloc(ctx->key_sz, flags); if (unlikely(!qat_req->src_align)) return ret;
@@ -857,7 +860,7 @@ static int qat_rsa_dec(struct akcipher_request *req) qat_req->dst_align = NULL; vaddr = sg_virt(req->dst); } else { - qat_req->dst_align = kzalloc(ctx->key_sz, GFP_KERNEL); + qat_req->dst_align = kzalloc(ctx->key_sz, flags); if (unlikely(!qat_req->dst_align)) goto unmap_src; vaddr = qat_req->dst_align; diff --git a/drivers/crypto/qat/qat_common/qat_crypto.h b/drivers/crypto/qat/qat_common/qat_crypto.h index 245b6d9a36507..df3c738ce323a 100644 --- a/drivers/crypto/qat/qat_common/qat_crypto.h +++ b/drivers/crypto/qat/qat_common/qat_crypto.h @@ -109,4 +109,9 @@ static inline bool adf_hw_dev_has_crypto(struct adf_accel_dev *accel_dev) return true; }
+static inline gfp_t qat_algs_alloc_flags(struct crypto_async_request *req) +{ + return req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; +} + #endif
From: Andre Przywara andre.przywara@arm.com
[ Upstream commit c2a1b91e47984e477298912ffd55570095d67318 ]
Currently the QAT driver code uses a self-defined wrapper function called get_current_node() when it wants to learn the current NUMA node. This implementation references the topology_physical_package_id[] array, which more or less coincidentally contains the NUMA node id, at least on x86.
Because this is not universal, and Linux offers a direct function to learn the NUMA node ID, replace that function with a call to numa_node_id(), which would work everywhere.
This fixes the QAT driver operation on arm64 machines.
Reported-by: Yoan Picchi Yoan.Picchi@arm.com Signed-off-by: Andre Przywara andre.przywara@arm.com Signed-off-by: Yoan Picchi yoan.picchi@arm.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Stable-dep-of: eb7713f5ca97 ("crypto: qat - unmap buffer before free for DH") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/adf_common_drv.h | 5 ----- drivers/crypto/qat/qat_common/qat_algs.c | 4 ++-- drivers/crypto/qat/qat_common/qat_asym_algs.c | 4 ++-- 3 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h index 4261749fae8d4..75693ca4afea1 100644 --- a/drivers/crypto/qat/qat_common/adf_common_drv.h +++ b/drivers/crypto/qat/qat_common/adf_common_drv.h @@ -49,11 +49,6 @@ struct service_hndl { struct list_head list; };
-static inline int get_current_node(void) -{ - return topology_physical_package_id(raw_smp_processor_id()); -} - int adf_service_register(struct service_hndl *service); int adf_service_unregister(struct service_hndl *service);
diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c index d36f90628603c..f56ee4cc5ae8b 100644 --- a/drivers/crypto/qat/qat_common/qat_algs.c +++ b/drivers/crypto/qat/qat_common/qat_algs.c @@ -605,7 +605,7 @@ static int qat_alg_aead_newkey(struct crypto_aead *tfm, const u8 *key, { struct qat_alg_aead_ctx *ctx = crypto_aead_ctx(tfm); struct qat_crypto_instance *inst = NULL; - int node = get_current_node(); + int node = numa_node_id(); struct device *dev; int ret;
@@ -1071,7 +1071,7 @@ static int qat_alg_skcipher_newkey(struct qat_alg_skcipher_ctx *ctx, { struct qat_crypto_instance *inst = NULL; struct device *dev; - int node = get_current_node(); + int node = numa_node_id(); int ret;
inst = qat_crypto_get_instance_node(node); diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c index 11c7f2b6e5975..85b0f30712e16 100644 --- a/drivers/crypto/qat/qat_common/qat_asym_algs.c +++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c @@ -489,7 +489,7 @@ static int qat_dh_init_tfm(struct crypto_kpp *tfm) { struct qat_dh_ctx *ctx = kpp_tfm_ctx(tfm); struct qat_crypto_instance *inst = - qat_crypto_get_instance_node(get_current_node()); + qat_crypto_get_instance_node(numa_node_id());
if (!inst) return -EINVAL; @@ -1225,7 +1225,7 @@ static int qat_rsa_init_tfm(struct crypto_akcipher *tfm) { struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm); struct qat_crypto_instance *inst = - qat_crypto_get_instance_node(get_current_node()); + qat_crypto_get_instance_node(numa_node_id());
if (!inst) return -EINVAL;
From: Damian Muszynski damian.muszynski@intel.com
[ Upstream commit 072d36eefd6fde17928d214df64fdac32f60b4f4 ]
When mapping the input and output parameters, the implementations of RSA and DH pass to the function dma_map_single() a pointer to the first member of the structure they want to map instead of a pointer to the actual structure. This results in set of warnings reported by the static analyser Smatch:
drivers/crypto/qat/qat_common/qat_asym_algs.c:335 qat_dh_compute_value() error: dma_map_single_attrs() '&qat_req->in.dh.in.b' too small (8 vs 64) drivers/crypto/qat/qat_common/qat_asym_algs.c:341 qat_dh_compute_value() error: dma_map_single_attrs() '&qat_req->out.dh.r' too small (8 vs 64) drivers/crypto/qat/qat_common/qat_asym_algs.c:732 qat_rsa_enc() error: dma_map_single_attrs() '&qat_req->in.rsa.enc.m' too small (8 vs 64) drivers/crypto/qat/qat_common/qat_asym_algs.c:738 qat_rsa_enc() error: dma_map_single_attrs() '&qat_req->out.rsa.enc.c' too small (8 vs 64) drivers/crypto/qat/qat_common/qat_asym_algs.c:878 qat_rsa_dec() error: dma_map_single_attrs() '&qat_req->in.rsa.dec.c' too small (8 vs 64) drivers/crypto/qat/qat_common/qat_asym_algs.c:884 qat_rsa_dec() error: dma_map_single_attrs() '&qat_req->out.rsa.dec.m' too small (8 vs 64)
Where the address of the first element of a structure is used as an input for the function dma_map_single(), replace it with the address of the structure. This fix does not introduce any functional change as the addresses are the same.
Signed-off-by: Damian Muszynski damian.muszynski@intel.com Signed-off-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Reviewed-by: Adam Guerin adam.guerin@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Stable-dep-of: eb7713f5ca97 ("crypto: qat - unmap buffer before free for DH") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/qat_asym_algs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c index 85b0f30712e16..94a26702aeae1 100644 --- a/drivers/crypto/qat/qat_common/qat_asym_algs.c +++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c @@ -332,13 +332,13 @@ static int qat_dh_compute_value(struct kpp_request *req) qat_req->in.dh.in_tab[n_input_params] = 0; qat_req->out.dh.out_tab[1] = 0; /* Mapping in.in.b or in.in_g2.xa is the same */ - qat_req->phy_in = dma_map_single(dev, &qat_req->in.dh.in.b, + qat_req->phy_in = dma_map_single(dev, &qat_req->in.dh, sizeof(struct qat_dh_input_params), DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev, qat_req->phy_in))) goto unmap_dst;
- qat_req->phy_out = dma_map_single(dev, &qat_req->out.dh.r, + qat_req->phy_out = dma_map_single(dev, &qat_req->out.dh, sizeof(struct qat_dh_output_params), DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev, qat_req->phy_out))) @@ -729,13 +729,13 @@ static int qat_rsa_enc(struct akcipher_request *req)
qat_req->in.rsa.in_tab[3] = 0; qat_req->out.rsa.out_tab[1] = 0; - qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa.enc.m, + qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa, sizeof(struct qat_rsa_input_params), DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev, qat_req->phy_in))) goto unmap_dst;
- qat_req->phy_out = dma_map_single(dev, &qat_req->out.rsa.enc.c, + qat_req->phy_out = dma_map_single(dev, &qat_req->out.rsa, sizeof(struct qat_rsa_output_params), DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev, qat_req->phy_out))) @@ -875,13 +875,13 @@ static int qat_rsa_dec(struct akcipher_request *req) else qat_req->in.rsa.in_tab[3] = 0; qat_req->out.rsa.out_tab[1] = 0; - qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa.dec.c, + qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa, sizeof(struct qat_rsa_input_params), DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev, qat_req->phy_in))) goto unmap_dst;
- qat_req->phy_out = dma_map_single(dev, &qat_req->out.rsa.dec.m, + qat_req->phy_out = dma_map_single(dev, &qat_req->out.rsa, sizeof(struct qat_rsa_output_params), DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev, qat_req->phy_out)))
From: Herbert Xu herbert@gondor.apana.org.au
[ Upstream commit 56861cbde1b9f3b34d300e6ba87f2c3de1a9c309 ]
The value of reqsize should only be changed through a helper. To do so we need to first add a helper for this.
Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Stable-dep-of: eb7713f5ca97 ("crypto: qat - unmap buffer before free for DH") Signed-off-by: Sasha Levin sashal@kernel.org --- include/crypto/internal/kpp.h | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/include/crypto/internal/kpp.h b/include/crypto/internal/kpp.h index 659b642efada1..05b25a819d0d1 100644 --- a/include/crypto/internal/kpp.h +++ b/include/crypto/internal/kpp.h @@ -18,6 +18,12 @@ static inline void *kpp_request_ctx(struct kpp_request *req) return req->__ctx; }
+static inline void kpp_set_reqsize(struct crypto_kpp *kpp, + unsigned int reqsize) +{ + crypto_kpp_alg(kpp)->reqsize = reqsize; +} + static inline void *kpp_tfm_ctx(struct crypto_kpp *tfm) { return tfm->base.__crt_ctx;
From: Herbert Xu herbert@gondor.apana.org.au
[ Upstream commit 80e62ad58db084920d8cf23323b713391e09f374 ]
The value of reqsize must only be changed through the helper.
Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Reviewed-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Stable-dep-of: eb7713f5ca97 ("crypto: qat - unmap buffer before free for DH") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/qat_asym_algs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c index 94a26702aeae1..935a7e012946e 100644 --- a/drivers/crypto/qat/qat_common/qat_asym_algs.c +++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c @@ -494,6 +494,8 @@ static int qat_dh_init_tfm(struct crypto_kpp *tfm) if (!inst) return -EINVAL;
+ kpp_set_reqsize(tfm, sizeof(struct qat_asym_request) + 64); + ctx->p_size = 0; ctx->g2 = false; ctx->inst = inst; @@ -1230,6 +1232,8 @@ static int qat_rsa_init_tfm(struct crypto_akcipher *tfm) if (!inst) return -EINVAL;
+ akcipher_set_reqsize(tfm, sizeof(struct qat_asym_request) + 64); + ctx->key_sz = 0; ctx->inst = inst; return 0; @@ -1252,7 +1256,6 @@ static struct akcipher_alg rsa = { .max_size = qat_rsa_max_size, .init = qat_rsa_init_tfm, .exit = qat_rsa_exit_tfm, - .reqsize = sizeof(struct qat_asym_request) + 64, .base = { .cra_name = "rsa", .cra_driver_name = "qat-rsa", @@ -1269,7 +1272,6 @@ static struct kpp_alg dh = { .max_size = qat_dh_max_size, .init = qat_dh_init_tfm, .exit = qat_dh_exit_tfm, - .reqsize = sizeof(struct qat_asym_request) + 64, .base = { .cra_name = "dh", .cra_driver_name = "qat-dh",
From: Hareshx Sankar Raj hareshx.sankar.raj@intel.com
[ Upstream commit eb7713f5ca97697b92f225127440d1525119b8de ]
The callback function for DH frees the memory allocated for the destination buffer before unmapping it. This sequence is wrong.
Change the cleanup sequence to unmap the buffer before freeing it.
Fixes: 029aa4624a7f ("crypto: qat - remove dma_free_coherent() for DH") Signed-off-by: Hareshx Sankar Raj hareshx.sankar.raj@intel.com Co-developed-by: Bolemx Sivanagaleela bolemx.sivanagaleela@intel.com Signed-off-by: Bolemx Sivanagaleela bolemx.sivanagaleela@intel.com Reviewed-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/qat_asym_algs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c index 935a7e012946e..8806242469a06 100644 --- a/drivers/crypto/qat/qat_common/qat_asym_algs.c +++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c @@ -170,15 +170,14 @@ static void qat_dh_cb(struct icp_qat_fw_pke_resp *resp) }
areq->dst_len = req->ctx.dh->p_size; + dma_unmap_single(dev, req->out.dh.r, req->ctx.dh->p_size, + DMA_FROM_DEVICE); if (req->dst_align) { scatterwalk_map_and_copy(req->dst_align, areq->dst, 0, areq->dst_len, 1); kfree_sensitive(req->dst_align); }
- dma_unmap_single(dev, req->out.dh.r, req->ctx.dh->p_size, - DMA_FROM_DEVICE); - dma_unmap_single(dev, req->phy_in, sizeof(struct qat_dh_input_params), DMA_TO_DEVICE); dma_unmap_single(dev, req->phy_out,
From: Hareshx Sankar Raj hareshx.sankar.raj@intel.com
[ Upstream commit d776b25495f2c71b9dbf1f5e53b642215ba72f3c ]
The callback function for RSA frees the memory allocated for the source and destination buffers before unmapping them. This sequence is wrong.
Change the cleanup sequence to unmap the buffers before freeing them.
Fixes: 3dfaf0071ed7 ("crypto: qat - remove dma_free_coherent() for RSA") Signed-off-by: Hareshx Sankar Raj hareshx.sankar.raj@intel.com Co-developed-by: Bolemx Sivanagaleela bolemx.sivanagaleela@intel.com Signed-off-by: Bolemx Sivanagaleela bolemx.sivanagaleela@intel.com Reviewed-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/qat_asym_algs.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c index 8806242469a06..4128200a90329 100644 --- a/drivers/crypto/qat/qat_common/qat_asym_algs.c +++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c @@ -520,12 +520,14 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
err = (err == ICP_QAT_FW_COMN_STATUS_FLAG_OK) ? 0 : -EINVAL;
- kfree_sensitive(req->src_align); - dma_unmap_single(dev, req->in.rsa.enc.m, req->ctx.rsa->key_sz, DMA_TO_DEVICE);
+ kfree_sensitive(req->src_align); + areq->dst_len = req->ctx.rsa->key_sz; + dma_unmap_single(dev, req->out.rsa.enc.c, req->ctx.rsa->key_sz, + DMA_FROM_DEVICE); if (req->dst_align) { scatterwalk_map_and_copy(req->dst_align, areq->dst, 0, areq->dst_len, 1); @@ -533,9 +535,6 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp) kfree_sensitive(req->dst_align); }
- dma_unmap_single(dev, req->out.rsa.enc.c, req->ctx.rsa->key_sz, - DMA_FROM_DEVICE); - dma_unmap_single(dev, req->phy_in, sizeof(struct qat_rsa_input_params), DMA_TO_DEVICE); dma_unmap_single(dev, req->phy_out,
From: Olga Kornievskaia kolga@netapp.com
[ Upstream commit c907e72f58ed979a24a9fdcadfbc447c51d5e509 ]
When the client received NFS4ERR_BADSESSION, it schedules recovery and start the state manager thread which in turn freezes the session table and does not allow for any new requests to use the no-longer valid session. However, it is possible that before the state manager thread runs, a new operation would use the released slot that received BADSESSION and was therefore not updated its sequence number. Such re-use of the slot can lead the application errors.
Fixes: 5c441544f045 ("NFSv4.x: Handle bad/dead sessions correctly in nfs41_sequence_process()") Signed-off-by: Olga Kornievskaia kolga@netapp.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4proc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0546fa1ac98f4..b1ec9b5d06e58 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -923,6 +923,7 @@ static int nfs41_sequence_process(struct rpc_task *task, out_noaction: return ret; session_recover: + set_bit(NFS4_SLOT_TBL_DRAINING, &session->fc_slot_table.slot_tbl_state); nfs4_schedule_session_recovery(session, status); dprintk("%s ERROR: %d Reset session\n", __func__, status); nfs41_sequence_free_slot(res);
From: Bharath SM bharathsm@microsoft.com
[ Upstream commit da787d5b74983f7525d1eb4b9c0b4aff2821511a ]
In case if all existing file handles are deferred handles and if all of them gets closed due to handle lease break then we dont need to send lease break acknowledgment to server, because last handle close will be considered as lease break ack. After closing deferred handels, we check for openfile list of inode, if its empty then we skip sending lease break ack.
Fixes: 59a556aebc43 ("SMB3: drop reference to cfile before sending oplock break") Reviewed-by: Tom Talpey tom@talpey.com Signed-off-by: Bharath SM bharathsm@microsoft.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/file.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index bda1ffe6e41f8..4e4f73a90574b 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -4923,20 +4923,19 @@ void cifs_oplock_break(struct work_struct *work)
_cifsFileInfo_put(cfile, false /* do not wait for ourself */, false); /* - * releasing stale oplock after recent reconnect of smb session using - * a now incorrect file handle is not a data integrity issue but do - * not bother sending an oplock release if session to server still is - * disconnected since oplock already released by the server + * MS-SMB2 3.2.5.19.1 and 3.2.5.19.2 (and MS-CIFS 3.2.5.42) do not require + * an acknowledgment to be sent when the file has already been closed. + * check for server null, since can race with kill_sb calling tree disconnect. */ - if (!oplock_break_cancelled) { - /* check for server null since can race with kill_sb calling tree disconnect */ - if (tcon->ses && tcon->ses->server) { - rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid, - volatile_fid, net_fid, cinode); - cifs_dbg(FYI, "Oplock release rc = %d\n", rc); - } else - pr_warn_once("lease break not sent for unmounted share\n"); - } + spin_lock(&cinode->open_file_lock); + if (tcon->ses && tcon->ses->server && !oplock_break_cancelled && + !list_empty(&cinode->openFileList)) { + spin_unlock(&cinode->open_file_lock); + rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid, + volatile_fid, net_fid, cinode); + cifs_dbg(FYI, "Oplock release rc = %d\n", rc); + } else + spin_unlock(&cinode->open_file_lock);
cifs_done_oplock_break(cinode); }
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit 6d24b170a9db0456f577b1ab01226a2254c016a8 ]
A CONFIG_DEBUG_KOBJECT_RELEASE test of removing a device-dax region provider (like modprobe -r dax_hmem) yields:
kobject: 'mapping0' (ffff93eb460e8800): kobject_release, parent 0000000000000000 (delayed 2000) [..] DEBUG_LOCKS_WARN_ON(1) WARNING: CPU: 23 PID: 282 at kernel/locking/lockdep.c:232 __lock_acquire+0x9fc/0x2260 [..] RIP: 0010:__lock_acquire+0x9fc/0x2260 [..] Call Trace: <TASK> [..] lock_acquire+0xd4/0x2c0 ? ida_free+0x62/0x130 _raw_spin_lock_irqsave+0x47/0x70 ? ida_free+0x62/0x130 ida_free+0x62/0x130 dax_mapping_release+0x1f/0x30 device_release+0x36/0x90 kobject_delayed_cleanup+0x46/0x150
Due to attempting ida_free() on an ida object that has already been freed. Devices typically only hold a reference on their parent while registered. If a child needs a parent object to complete its release it needs to hold a reference that it drops from its release callback. Arrange for a dax_mapping to pin its parent dev_dax instance until dax_mapping_release().
Fixes: 0b07ce872a9e ("device-dax: introduce 'mapping' devices") Signed-off-by: Dan Williams dan.j.williams@intel.com Link: https://lore.kernel.org/r/168577283412.1672036.16111545266174261446.stgit@dw... Reviewed-by: Dave Jiang dave.jiang@intel.com Reviewed-by: Fan Ni fan.ni@samsung.com Reviewed-by: Ira Weiny ira.weiny@intel.com Signed-off-by: Vishal Verma vishal.l.verma@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dax/bus.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index e75b9edc88a1f..ce010040bcef8 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -591,10 +591,12 @@ EXPORT_SYMBOL_GPL(alloc_dax_region); static void dax_mapping_release(struct device *dev) { struct dax_mapping *mapping = to_dax_mapping(dev); - struct dev_dax *dev_dax = to_dev_dax(dev->parent); + struct device *parent = dev->parent; + struct dev_dax *dev_dax = to_dev_dax(parent);
ida_free(&dev_dax->ida, mapping->id); kfree(mapping); + put_device(parent); }
static void unregister_dax_mapping(void *data) @@ -734,6 +736,7 @@ static int devm_register_dax_mapping(struct dev_dax *dev_dax, int range_id) dev = &mapping->dev; device_initialize(dev); dev->parent = &dev_dax->dev; + get_device(dev->parent); dev->type = &dax_mapping_type; dev_set_name(dev, "mapping%d", mapping->id); rc = device_add(dev);
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit 70aab281e18c68a1284bc387de127c2fc0bed3f8 ]
The reference counting of dax_region objects is needlessly complicated, has lead to confusion [1], and has hidden a bug [2]. Towards cleaning up that mess introduce alloc_dev_dax_id() to minimize the holding of a dax_region reference to only what dev_dax_release() needs, the dax_region->ida.
Part of the reason for the mess was the design to dereference a dax_region in all cases in free_dev_dax_id() even if the id was statically assigned by the upper level dax_region driver. Remove the need to call "is_static(dax_region)" by tracking whether the id is dynamic directly in the dev_dax instance itself.
With that flag the dax_region pinning and release per dev_dax instance can move to alloc_dev_dax_id() and free_dev_dax_id() respectively.
A follow-on cleanup address the unnecessary references in the dax_region setup and drivers.
Fixes: 0f3da14a4f05 ("device-dax: introduce 'seed' devices") Link: http://lore.kernel.org/r/20221203095858.612027-1-liuyongqiang13@huawei.com [1] Link: http://lore.kernel.org/r/3cf0890b-4eb0-e70e-cd9c-2ecc3d496263@hpe.com [2] Reported-by: Yongqiang Liu liuyongqiang13@huawei.com Reported-by: Paul Cassella cassella@hpe.com Reported-by: Ira Weiny ira.weiny@intel.com Signed-off-by: Dan Williams dan.j.williams@intel.com Link: https://lore.kernel.org/r/168577284563.1672036.13493034988900989554.stgit@dw... Reviewed-by: Ira Weiny ira.weiny@intel.com Signed-off-by: Vishal Verma vishal.l.verma@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dax/bus.c | 56 ++++++++++++++++++++++++--------------- drivers/dax/dax-private.h | 4 ++- 2 files changed, 37 insertions(+), 23 deletions(-)
diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index ce010040bcef8..7ad61c707687f 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -402,18 +402,34 @@ static void unregister_dev_dax(void *dev) put_device(dev); }
+static void dax_region_free(struct kref *kref) +{ + struct dax_region *dax_region; + + dax_region = container_of(kref, struct dax_region, kref); + kfree(dax_region); +} + +void dax_region_put(struct dax_region *dax_region) +{ + kref_put(&dax_region->kref, dax_region_free); +} +EXPORT_SYMBOL_GPL(dax_region_put); + /* a return value >= 0 indicates this invocation invalidated the id */ static int __free_dev_dax_id(struct dev_dax *dev_dax) { - struct dax_region *dax_region = dev_dax->region; struct device *dev = &dev_dax->dev; + struct dax_region *dax_region; int rc = dev_dax->id;
device_lock_assert(dev);
- if (is_static(dax_region) || dev_dax->id < 0) + if (!dev_dax->dyn_id || dev_dax->id < 0) return -1; + dax_region = dev_dax->region; ida_free(&dax_region->ida, dev_dax->id); + dax_region_put(dax_region); dev_dax->id = -1; return rc; } @@ -429,6 +445,20 @@ static int free_dev_dax_id(struct dev_dax *dev_dax) return rc; }
+static int alloc_dev_dax_id(struct dev_dax *dev_dax) +{ + struct dax_region *dax_region = dev_dax->region; + int id; + + id = ida_alloc(&dax_region->ida, GFP_KERNEL); + if (id < 0) + return id; + kref_get(&dax_region->kref); + dev_dax->dyn_id = true; + dev_dax->id = id; + return id; +} + static ssize_t delete_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { @@ -516,20 +546,6 @@ static const struct attribute_group *dax_region_attribute_groups[] = { NULL, };
-static void dax_region_free(struct kref *kref) -{ - struct dax_region *dax_region; - - dax_region = container_of(kref, struct dax_region, kref); - kfree(dax_region); -} - -void dax_region_put(struct dax_region *dax_region) -{ - kref_put(&dax_region->kref, dax_region_free); -} -EXPORT_SYMBOL_GPL(dax_region_put); - static void dax_region_unregister(void *region) { struct dax_region *dax_region = region; @@ -1254,12 +1270,10 @@ static const struct attribute_group *dax_attribute_groups[] = { static void dev_dax_release(struct device *dev) { struct dev_dax *dev_dax = to_dev_dax(dev); - struct dax_region *dax_region = dev_dax->region; struct dax_device *dax_dev = dev_dax->dax_dev;
put_dax(dax_dev); free_dev_dax_id(dev_dax); - dax_region_put(dax_region); kfree(dev_dax->pgmap); kfree(dev_dax); } @@ -1283,6 +1297,7 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data) if (!dev_dax) return ERR_PTR(-ENOMEM);
+ dev_dax->region = dax_region; if (is_static(dax_region)) { if (dev_WARN_ONCE(parent, data->id < 0, "dynamic id specified to static region\n")) { @@ -1298,13 +1313,11 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data) goto err_id; }
- rc = ida_alloc(&dax_region->ida, GFP_KERNEL); + rc = alloc_dev_dax_id(dev_dax); if (rc < 0) goto err_id; - dev_dax->id = rc; }
- dev_dax->region = dax_region; dev = &dev_dax->dev; device_initialize(dev); dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id); @@ -1342,7 +1355,6 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data) dev_dax->target_node = dax_region->target_node; dev_dax->align = dax_region->align; ida_init(&dev_dax->ida); - kref_get(&dax_region->kref);
inode = dax_inode(dax_dev); dev->devt = inode->i_rdev; diff --git a/drivers/dax/dax-private.h b/drivers/dax/dax-private.h index 1c974b7caae6e..afcada6fd2eda 100644 --- a/drivers/dax/dax-private.h +++ b/drivers/dax/dax-private.h @@ -52,7 +52,8 @@ struct dax_mapping { * @region - parent region * @dax_dev - core dax functionality * @target_node: effective numa node if dev_dax memory range is onlined - * @id: ida allocated id + * @dyn_id: is this a dynamic or statically created instance + * @id: ida allocated id when the dax_region is not static * @ida: mapping id allocator * @dev - device core * @pgmap - pgmap for memmap setup / lifetime (driver owned) @@ -64,6 +65,7 @@ struct dev_dax { struct dax_device *dax_dev; unsigned int align; int target_node; + bool dyn_id; int id; struct ida ida; struct device dev;
From: Tarun Sahu tsahu@linux.ibm.com
[ Upstream commit 46e66dab8565f742374e9cc4ff7d35f344d774e2 ]
memory_group_register_static takes maximum number of pages as the argument while dev_dax_kmem_probe passes total_len (in bytes) as the argument.
IIUC, I don't see any crash/panic impact as such. As, memory_group_register_static just set the max_pages limit which is used in auto_movable_zone_for_pfn to determine the zone.
which might cause these condition to behave differently,
This will be true always so jump will happen to kernel_zone ... if (!auto_movable_can_online_movable(NUMA_NO_NODE, group, nr_pages)) goto kernel_zone;
... kernel_zone: return default_kernel_zone_for_pfn(nid, pfn, nr_pages);
Here, In below, zone_intersects compare range will be larger as nr_pages will be higher (derived from total_len passed in dev_dax_kmem_probe).
... static struct zone *default_kernel_zone_for_pfn(int nid, unsigned long start_pfn, unsigned long nr_pages) { struct pglist_data *pgdat = NODE_DATA(nid); int zid;
for (zid = 0; zid < ZONE_NORMAL; zid++) { struct zone *zone = &pgdat->node_zones[zid];
if (zone_intersects(zone, start_pfn, nr_pages)) return zone; }
return &pgdat->node_zones[ZONE_NORMAL]; }
Incorrect zone will be returned here, which in later time might cause bigger problem.
Fixes: eedf634aac3b ("dax/kmem: use a single static memory group for a single probed unit") Signed-off-by: Tarun Sahu tsahu@linux.ibm.com Link: https://lore.kernel.org/r/20230621155025.370672-1-tsahu@linux.ibm.com Reviewed-by: Vishal Verma vishal.l.verma@intel.com Signed-off-by: Vishal Verma vishal.l.verma@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dax/kmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dax/kmem.c b/drivers/dax/kmem.c index 04f85f16720c8..97723ee15bc68 100644 --- a/drivers/dax/kmem.c +++ b/drivers/dax/kmem.c @@ -88,7 +88,7 @@ static int dev_dax_kmem_probe(struct dev_dax *dev_dax) if (!data->res_name) goto err_res_name;
- rc = memory_group_register_static(numa_node, total_len); + rc = memory_group_register_static(numa_node, PFN_UP(total_len)); if (rc < 0) goto err_reg_mgid; data->mgid = rc;
From: Martin Kaiser martin@kaiser.cx
[ Upstream commit 501e197a02d4aef157f53ba3a0b9049c3e52fedc ]
The st-rng driver uses devres to register itself with the hwrng core, the driver will be unregistered from hwrng when its device goes out of scope. This happens after the driver's remove function is called.
However, st-rng's clock is disabled in the remove function. There's a short timeframe where st-rng is still registered with the hwrng core although its clock is disabled. I suppose the clock must be active to access the hardware and serve requests from the hwrng core.
Switch to devm_clk_get_enabled and let devres disable the clock and unregister the hwrng. This avoids the race condition.
Fixes: 3e75241be808 ("hwrng: drivers - Use device-managed registration API") Signed-off-by: Martin Kaiser martin@kaiser.cx Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/st-rng.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-)
diff --git a/drivers/char/hw_random/st-rng.c b/drivers/char/hw_random/st-rng.c index 15ba1e6fae4d2..6e9dfac9fc9f4 100644 --- a/drivers/char/hw_random/st-rng.c +++ b/drivers/char/hw_random/st-rng.c @@ -42,7 +42,6 @@
struct st_rng_data { void __iomem *base; - struct clk *clk; struct hwrng ops; };
@@ -85,26 +84,18 @@ static int st_rng_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base);
- clk = devm_clk_get(&pdev->dev, NULL); + clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(clk)) return PTR_ERR(clk);
- ret = clk_prepare_enable(clk); - if (ret) - return ret; - ddata->ops.priv = (unsigned long)ddata; ddata->ops.read = st_rng_read; ddata->ops.name = pdev->name; ddata->base = base; - ddata->clk = clk; - - dev_set_drvdata(&pdev->dev, ddata);
ret = devm_hwrng_register(&pdev->dev, &ddata->ops); if (ret) { dev_err(&pdev->dev, "Failed to register HW RNG\n"); - clk_disable_unprepare(clk); return ret; }
@@ -113,15 +104,6 @@ static int st_rng_probe(struct platform_device *pdev) return 0; }
-static int st_rng_remove(struct platform_device *pdev) -{ - struct st_rng_data *ddata = dev_get_drvdata(&pdev->dev); - - clk_disable_unprepare(ddata->clk); - - return 0; -} - static const struct of_device_id st_rng_match[] __maybe_unused = { { .compatible = "st,rng" }, {}, @@ -134,7 +116,6 @@ static struct platform_driver st_rng_driver = { .of_match_table = of_match_ptr(st_rng_match), }, .probe = st_rng_probe, - .remove = st_rng_remove };
module_platform_driver(st_rng_driver);
From: Sami Tolvanen samitolvanen@google.com
[ Upstream commit 25a21fbb934a0d989e1858f83c2ddf4cfb2ebe30 ]
With GCOV_PROFILE_ALL, Clang injects __llvm_gcov_* functions to each object file, including the *.mod.o. As we filter out CC_FLAGS_CFI for *.mod.o, the compiler won't generate type hashes for the injected functions, and therefore indirectly calling them during module loading trips indirect call checking.
Enabling CFI for *.mod.o isn't sufficient to fix this issue after commit 0c3e806ec0f9 ("x86/cfi: Add boot time hash randomization"), as *.mod.o aren't processed by objtool, which means any hashes emitted there won't be randomized. Therefore, in addition to disabling CFI for *.mod.o, also disable GCOV, as the object files don't otherwise contain any executable code.
Fixes: cf68fffb66d6 ("add support for Clang CFI") Reported-by: Joe Fradley joefradley@google.com Signed-off-by: Sami Tolvanen samitolvanen@google.com Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Kees Cook keescook@chromium.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/Makefile.modfinal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index ce9661d968a3d..47f047458264f 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -23,7 +23,7 @@ modname = $(notdir $(@:.mod.o=)) part-of-module = y
quiet_cmd_cc_o_c = CC [M] $@ - cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI), $(c_flags)) -c -o $@ $< + cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI) $(CFLAGS_GCOV), $(c_flags)) -c -o $@ $<
%.mod.o: %.mod.c FORCE $(call if_changed_dep,cc_o_c)
From: Ard Biesheuvel ardb@kernel.org
[ Upstream commit 2e28a798c3092ea42b968fa16ac835969d124898 ]
Currently, the EFI stub will disable PCI DMA as the very last thing it does before calling ExitBootServices(), to avoid interfering with the firmware's normal operation as much as possible.
However, the stub will invoke DisconnectController() on all endpoints downstream of the PCI bridges it disables, and this may affect the layout of the EFI memory map, making it substantially more likely that ExitBootServices() will fail the first time around, and that the EFI memory map needs to be reloaded.
This, in turn, increases the likelihood that the slack space we allocated is insufficient (and we can no longer allocate memory via boot services after having called ExitBootServices() once), causing the second call to GetMemoryMap (and therefore the boot) to fail. This makes the PCI DMA disable feature a bit more fragile than it already is, so let's make it more robust, by allocating the space for the EFI memory map after disabling PCI DMA.
Fixes: 4444f8541dad16fe ("efi: Allow disabling PCI busmastering on bridges during boot") Reported-by: Glenn Washburn development@efficientek.com Acked-by: Matthew Garrett mjg59@srcf.ucam.org Signed-off-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/efi/libstub/efi-stub-helper.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index d489bdc645fe1..2a00eb627c3c3 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -439,8 +439,10 @@ efi_status_t efi_exit_boot_services(void *handle, { efi_status_t status;
- status = efi_get_memory_map(map); + if (efi_disable_pci_dma) + efi_pci_disable_bridge_busmaster();
+ status = efi_get_memory_map(map); if (status != EFI_SUCCESS) goto fail;
@@ -448,9 +450,6 @@ efi_status_t efi_exit_boot_services(void *handle, if (status != EFI_SUCCESS) goto free_map;
- if (efi_disable_pci_dma) - efi_pci_disable_bridge_busmaster(); - status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
if (status == EFI_INVALID_PARAMETER) {
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 9cedc58bdbe9fff9aacd0ca19ee5777659f28fd7 ]
clang warns about a possible field overflow in a memcpy:
In file included from fs/smb/server/smb_common.c:7: include/linux/fortify-string.h:583:4: error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning] __write_overflow_field(p_size_field, size);
It appears to interpret the "&out[baselen + 4]" as referring to a single byte of the character array, while the equivalen "out + baselen + 4" is seen as an offset into the array.
I don't see that kind of warning elsewhere, so just go with the simple rework.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ksmbd/smb_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ksmbd/smb_common.c b/fs/ksmbd/smb_common.c index f034b75c6d7f4..af583e4266215 100644 --- a/fs/ksmbd/smb_common.c +++ b/fs/ksmbd/smb_common.c @@ -423,7 +423,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname, out[baselen + 3] = PERIOD;
if (dot_present) - memcpy(&out[baselen + 4], extension, 4); + memcpy(out + baselen + 4, extension, 4); else out[baselen + 4] = '\0'; smbConvertToUTF16((__le16 *)shortname, out, PATH_MAX,
From: Kiran K kiran.k@intel.com
[ Upstream commit 2c5a06e5505a716387a4d86f1f39de506836435a ]
acpi_evaluate_dsm_typed() needs to be gaurded with CONFIG_ACPI to avoid a redefintion error when the stub is also enabled.
In file included from ../drivers/bluetooth/btintel.c:13: ../include/acpi/acpi_bus.h:57:1: error: redefinition of 'acpi_evaluate_dsm_typed' 57 | acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid,.. | ^~~~~~~~~~~~~~~~~~~~~~~ In file included from ../drivers/bluetooth/btintel.c:12: ../include/linux/acpi.h:967:34: note: previous definition of 'acpi_evaluate_dsm_typed' with type 'union acpi_object *(void *, const guid_t *, u64, u64, union acpi_object *, acpi_object_type)' {aka 'union acpi_object *(void *, const guid_t *, long long unsigned int, long long unsigned int, union acpi_object *, unsigned int)'} 967 | static inline union acpi_object *acpi_evaluate_dsm_typed(acpi_handle handle,
Fixes: 1b94ad7ccc21 ("ACPI: utils: Add acpi_evaluate_dsm_typed() and acpi_check_dsm() stubs") Signed-off-by: Kiran K kiran.k@intel.com [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/acpi/acpi_bus.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index e9c7d7b270e73..7a85ae6b7b005 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -52,7 +52,7 @@ bool acpi_dock_match(acpi_handle handle); bool acpi_check_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 funcs); union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 func, union acpi_object *argv4); - +#ifdef CONFIG_ACPI static inline union acpi_object * acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev, u64 func, union acpi_object *argv4, @@ -68,6 +68,7 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev,
return obj; } +#endif
#define ACPI_INIT_DSM_ARGV4(cnt, eles) \ { \
From: Liu Shixin liushixin2@huawei.com
commit 028725e73375a1ff080bbdf9fb503306d0116f28 upstream.
commit dd0ff4d12dd2 ("bootmem: remove the vmemmap pages from kmemleak in put_page_bootmem") fix an overlaps existing problem of kmemleak. But the problem still existed when HAVE_BOOTMEM_INFO_NODE is disabled, because in this case, free_bootmem_page() will call free_reserved_page() directly.
Fix the problem by adding kmemleak_free_part() in free_bootmem_page() when HAVE_BOOTMEM_INFO_NODE is disabled.
Link: https://lkml.kernel.org/r/20230704101942.2819426-1-liushixin2@huawei.com Fixes: f41f2ed43ca5 ("mm: hugetlb: free the vmemmap pages associated with each HugeTLB page") Signed-off-by: Liu Shixin liushixin2@huawei.com Acked-by: Muchun Song songmuchun@bytedance.com Cc: Matthew Wilcox willy@infradead.org Cc: Mike Kravetz mike.kravetz@oracle.com Cc: Oscar Salvador osalvador@suse.de 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/bootmem_info.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/linux/bootmem_info.h b/include/linux/bootmem_info.h index cc35d010fa94..e1a3c9c9754c 100644 --- a/include/linux/bootmem_info.h +++ b/include/linux/bootmem_info.h @@ -3,6 +3,7 @@ #define __LINUX_BOOTMEM_INFO_H
#include <linux/mm.h> +#include <linux/kmemleak.h>
/* * Types for free bootmem stored in page->lru.next. These have to be in @@ -59,6 +60,7 @@ static inline void get_page_bootmem(unsigned long info, struct page *page,
static inline void free_bootmem_page(struct page *page) { + kmemleak_free_part(page_to_virt(page), PAGE_SIZE); free_reserved_page(page); } #endif
From: Jens Axboe axboe@kernel.dk
No direct upstream commit exists for this issue. It was fixed in 5.18 as part of a larger rework of the completion side.
io_commit_cqring() writes the CQ ring tail to make it visible, but it also kicks off any deferred work we have. A ring setup with IOPOLL does not need any locking around the CQ ring updates, as we're always under the ctx uring_lock. But if we have deferred work that needs processing, then io_queue_deferred() assumes that the completion_lock is held, as it is for !IOPOLL.
Add a lockdep assertion to check and document this fact, and have io_iopoll_complete() check if we have deferred work and run that separately with the appropriate lock grabbed.
Cc: stable@vger.kernel.org # 5.10, 5.15 Reported-by: dghost david daviduniverse18@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- io_uring/io_uring.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-)
--- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1524,6 +1524,8 @@ static void io_kill_timeout(struct io_ki
static void io_queue_deferred(struct io_ring_ctx *ctx) { + lockdep_assert_held(&ctx->completion_lock); + while (!list_empty(&ctx->defer_list)) { struct io_defer_entry *de = list_first_entry(&ctx->defer_list, struct io_defer_entry, list); @@ -1575,14 +1577,24 @@ static void __io_commit_cqring_flush(str io_queue_deferred(ctx); }
-static inline void io_commit_cqring(struct io_ring_ctx *ctx) +static inline bool io_commit_needs_flush(struct io_ring_ctx *ctx) +{ + return ctx->off_timeout_used || ctx->drain_active; +} + +static inline void __io_commit_cqring(struct io_ring_ctx *ctx) { - if (unlikely(ctx->off_timeout_used || ctx->drain_active)) - __io_commit_cqring_flush(ctx); /* order cqe stores with ring update */ smp_store_release(&ctx->rings->cq.tail, ctx->cached_cq_tail); }
+static inline void io_commit_cqring(struct io_ring_ctx *ctx) +{ + if (unlikely(io_commit_needs_flush(ctx))) + __io_commit_cqring_flush(ctx); + __io_commit_cqring(ctx); +} + static inline bool io_sqring_full(struct io_ring_ctx *ctx) { struct io_rings *r = ctx->rings; @@ -2521,7 +2533,12 @@ static void io_iopoll_complete(struct io io_req_free_batch(&rb, req, &ctx->submit_state); }
- io_commit_cqring(ctx); + if (io_commit_needs_flush(ctx)) { + spin_lock(&ctx->completion_lock); + __io_commit_cqring_flush(ctx); + spin_unlock(&ctx->completion_lock); + } + __io_commit_cqring(ctx); io_cqring_ev_posted_iopoll(ctx); io_req_free_batch_finish(ctx, &rb); }
From: Davide Tronchin davide.tronchin.94@gmail.com
commit ffa5f7a3bf28c1306eef85d4056539c2d4b8eb09 upstream.
The new LARA-R6 product variant identified by the "01B" string can be configured (by AT interface) in three different USB modes:
* Default mode (Vendor ID: 0x1546 Product ID: 0x1311) with 4 serial interfaces
* RmNet mode (Vendor ID: 0x1546 Product ID: 0x1312) with 4 serial interfaces and 1 RmNet virtual network interface
* CDC-ECM mode (Vendor ID: 0x1546 Product ID: 0x1313) with 4 serial interface and 1 CDC-ECM virtual network interface The first 4 interfaces of all the 3 USB configurations (default, RmNet, CDC-ECM) are the same.
In default mode LARA-R6 01B exposes the following interfaces: If 0: Diagnostic If 1: AT parser If 2: AT parser If 3: AT parser/alternative functions
In RmNet mode LARA-R6 01B exposes the following interfaces: If 0: Diagnostic If 1: AT parser If 2: AT parser If 3: AT parser/alternative functions If 4: RMNET interface
In CDC-ECM mode LARA-R6 01B exposes the following interfaces: If 0: Diagnostic If 1: AT parser If 2: AT parser If 3: AT parser/alternative functions If 4: CDC-ECM interface
Signed-off-by: Davide Tronchin davide.tronchin.94@gmail.com Link: https://lore.kernel.org/r/20230622092921.12651-1-davide.tronchin.94@gmail.co... Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1151,6 +1151,10 @@ static const struct usb_device_id option { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x90fa), .driver_info = RSVD(3) }, /* u-blox products */ + { USB_DEVICE(UBLOX_VENDOR_ID, 0x1311) }, /* u-blox LARA-R6 01B */ + { USB_DEVICE(UBLOX_VENDOR_ID, 0x1312), /* u-blox LARA-R6 01B (RMNET) */ + .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(UBLOX_VENDOR_ID, 0x1313, 0xff) }, /* u-blox LARA-R6 01B (ECM) */ { USB_DEVICE(UBLOX_VENDOR_ID, 0x1341) }, /* u-blox LARA-L6 */ { USB_DEVICE(UBLOX_VENDOR_ID, 0x1342), /* u-blox LARA-L6 (RMNET) */ .driver_info = RSVD(4) },
From: Krishna Kurapati quic_kriskura@quicinc.com
commit c0aabed9cabe057309779a9e26fe86a113d24dad upstream.
In scenarios where pullup relies on resume (get sync) to initialize the controller and set the run stop bit, then core_init is followed by gadget_resume which will eventually set run stop bit.
But in cases where the core_init fails, the return value is not sent back to udc appropriately. So according to UDC the controller has started but in reality we never set the run stop bit.
On systems like Android, there are uevents sent to HAL depending on whether the configfs_bind / configfs_disconnect were invoked. In the above mentioned scnenario, if the core init fails, the run stop won't be set and the cable plug-out won't result in generation of any disconnect event and userspace would never get any uevent regarding cable plug out and we never call pullup(0) again. Furthermore none of the next Plug-In/Plug-Out's would be known to configfs.
Return back the appropriate result to UDC to let the userspace/ configfs know that the pullup failed so they can take appropriate action.
Fixes: 77adb8bdf422 ("usb: dwc3: gadget: Allow runtime suspend if UDC unbinded") Cc: stable stable@kernel.org Signed-off-by: Krishna Kurapati quic_kriskura@quicinc.com Acked-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Message-ID: 20230618120949.14868-1-quic_kriskura@quicinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc3/gadget.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2530,7 +2530,9 @@ static int dwc3_gadget_pullup(struct usb ret = pm_runtime_get_sync(dwc->dev); if (!ret || ret < 0) { pm_runtime_put(dwc->dev); - return 0; + if (ret < 0) + pm_runtime_set_suspended(dwc->dev); + return ret; }
if (dwc->pullups_connected == is_on) {
From: EJ Hsu ejh@nvidia.com
commit c0c2fcb1325d0d4f3b322b5ee49385f8eca2560d upstream.
For the dual-role port, it will assign the phy dev to usb-phy dev and use the port dev driver as the dev driver of usb-phy.
When we try to destroy the port dev, it will destroy its dev driver as well. But we did not remove the reference from usb-phy dev. This might cause the use-after-free issue in KASAN.
Fixes: e8f7d2f409a1 ("phy: tegra: xusb: Add usb-phy support") Cc: stable@vger.kernel.org
Signed-off-by: EJ Hsu ejh@nvidia.com Signed-off-by: Haotien Hsu haotienh@nvidia.com Acked-by: Thierry Reding treding@nvidia.com Acked-by: Jon Hunter jonathanh@nvidia.com Link: https://lore.kernel.org/r/20230609062932.3276509-1-haotienh@nvidia.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/phy/tegra/xusb.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -562,6 +562,7 @@ static void tegra_xusb_port_unregister(s usb_role_switch_unregister(port->usb_role_sw); cancel_work_sync(&port->usb_phy_work); usb_remove_phy(&port->usb_phy); + port->usb_phy.dev->driver = NULL; }
if (port->ops->remove)
From: Fabrizio Lamarque fl.scratchpad@gmail.com
commit 9e58e3a6f8e1c483c86a04903b7b7aa0923e4426 upstream.
Pointer to indio_dev structure is obtained via spi_get_drvdata() at the beginning of function ad7192_setup(), but the spi->dev->driver_data member is not initialized, hence a NULL pointer is returned.
Fix by changing ad7192_setup() signature to take pointer to struct iio_dev, and get ad7192_state pointer via st = iio_priv(indio_dev);
Fixes: bd5dcdeb3fd0 ("iio: adc: ad7192: convert to device-managed functions") Signed-off-by: Fabrizio Lamarque fl.scratchpad@gmail.com Reviewed-by: Nuno Sa nuno.sa@analog.com Cc: Stable@vger.kernel.org Link: https://lore.kernel.org/r/20230530075311.400686-2-fl.scratchpad@gmail.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/adc/ad7192.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/iio/adc/ad7192.c +++ b/drivers/iio/adc/ad7192.c @@ -340,9 +340,9 @@ static int ad7192_of_clock_select(struct return clock_sel; }
-static int ad7192_setup(struct ad7192_state *st, struct device_node *np) +static int ad7192_setup(struct iio_dev *indio_dev, struct device_node *np) { - struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi); + struct ad7192_state *st = iio_priv(indio_dev); bool rej60_en, refin2_en; bool buf_en, bipolar, burnout_curr_en; unsigned long long scale_uv; @@ -1015,7 +1015,7 @@ static int ad7192_probe(struct spi_devic } }
- ret = ad7192_setup(st, spi->dev.of_node); + ret = ad7192_setup(indio_dev, spi->dev.of_node); if (ret) return ret;
From: Fabrizio Lamarque fl.scratchpad@gmail.com
commit f7d9e21dd274b97dc0a8dbc136a2ea8506063a96 upstream.
Fix wrong selection of internal clock when mclk is defined.
Resolve a logical inversion introduced in c9ec2cb328e3.
Fixes: c9ec2cb328e3 ("iio: adc: ad7192: use devm_clk_get_optional() for mclk") Signed-off-by: Fabrizio Lamarque fl.scratchpad@gmail.com Reviewed-by: Nuno Sa nuno.sa@analog.com Cc: Stable@vger.kernel.org Link: https://lore.kernel.org/r/20230530075311.400686-3-fl.scratchpad@gmail.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/adc/ad7192.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/adc/ad7192.c +++ b/drivers/iio/adc/ad7192.c @@ -327,7 +327,7 @@ static int ad7192_of_clock_select(struct clock_sel = AD7192_CLK_INT;
/* use internal clock */ - if (st->mclk) { + if (!st->mclk) { if (of_property_read_bool(np, "adi,int-clock-output-enable")) clock_sel = AD7192_CLK_INT_CO; } else {
From: Sean Nyekjaer sean@geanix.com
commit b410a9307bc3a7cdee3c930c98f6fc9cf1d2c484 upstream.
Remove special errata handling if FXLS8964AF is used.
Fixes: af959b7b96b8 ("iio: accel: fxls8962af: fix errata bug E3 - I2C burst reads") Signed-off-by: Sean Nyekjaer sean@geanix.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230605103223.1400980-2-sean@geanix.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/accel/fxls8962af-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -656,9 +656,10 @@ static int fxls8962af_fifo_transfer(stru int total_length = samples * sample_length; int ret;
- if (i2c_verify_client(dev)) + if (i2c_verify_client(dev) && + data->chip_info->chip_id == FXLS8962AF_DEVICE_ID) /* - * Due to errata bug: + * Due to errata bug (only applicable on fxls8962af): * E3: FIFO burst read operation error using I2C interface * We have to avoid burst reads on I2C.. */
From: Sean Nyekjaer sean@geanix.com
commit d1cfbd52ede5e5fabc09992894c5733b4057f159 upstream.
Scan elements for x,y,z channels is little endian and requires no bit shifts. LE vs. BE is controlled in register SENS_CONFIG2 and bit LE_BE, default value is LE.
Fixes: a3e0b51884ee ("iio: accel: add support for FXLS8962AF/FXLS8964AF accelerometers") Signed-off-by: Sean Nyekjaer sean@geanix.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230605103223.1400980-1-sean@geanix.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/accel/fxls8962af-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -486,8 +486,7 @@ static int fxls8962af_set_watermark(stru .sign = 's', \ .realbits = 12, \ .storagebits = 16, \ - .shift = 4, \ - .endianness = IIO_BE, \ + .endianness = IIO_LE, \ }, \ }
From: Werner Sembach wse@tuxedocomputers.com
commit 22065e4214c1196b54fc164892c2e193a743caf3 upstream.
This applies a SND_PCI_QUIRK(...) to the Clevo NPx0SNx barebones fixing the microphone not being detected on the headset combo port.
Signed-off-by: Werner Sembach wse@tuxedocomputers.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230628155434.584159-1-wse@tuxedocomputers.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9242,6 +9242,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x1558, 0x971d, "Clevo N970T[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0xa500, "Clevo NL5[03]RU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0xa600, "Clevo NL50NU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1558, 0xa650, "Clevo NP[567]0SN[CD]", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0xa671, "Clevo NP70SN[CDE]", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0xb018, "Clevo NP50D[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0xb019, "Clevo NH77D[BE]Q", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
From: Takashi Iwai tiwai@suse.de
commit 89dbb335cb6a627a4067bc42caa09c8bc3326d40 upstream.
snd_jack_report() is supposed to be callable from an IRQ context, too, and it's indeed used in that way from virtsnd driver. The fix for input_dev race in commit 1b6a6fc5280e ("ALSA: jack: Access input_dev under mutex"), however, introduced a mutex lock in snd_jack_report(), and this resulted in a potential sleep-in-atomic.
For addressing that problem, this patch changes the relevant code to use the object get/put and removes the mutex usage. That is, snd_jack_report(), it takes input_get_device() and leaves with input_put_device() for assuring the input_dev being assigned.
Although the whole mutex could be reduced, we keep it because it can be still a protection for potential races between creation and deletion.
Fixes: 1b6a6fc5280e ("ALSA: jack: Access input_dev under mutex") Reported-by: Dan Carpenter dan.carpenter@linaro.org Closes: https://lore.kernel.org/r/cf95f7fe-a748-4990-8378-000491b40329@moroto.mounta... Tested-by: Amadeusz Sławiński amadeuszx.slawinski@linux.intel.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230706155357.3470-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/core/jack.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
--- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -654,6 +654,7 @@ void snd_jack_report(struct snd_jack *ja struct snd_jack_kctl *jack_kctl; unsigned int mask_bits = 0; #ifdef CONFIG_SND_JACK_INPUT_DEV + struct input_dev *idev; int i; #endif
@@ -670,17 +671,15 @@ void snd_jack_report(struct snd_jack *ja status & jack_kctl->mask_bits);
#ifdef CONFIG_SND_JACK_INPUT_DEV - mutex_lock(&jack->input_dev_lock); - if (!jack->input_dev) { - mutex_unlock(&jack->input_dev_lock); + idev = input_get_device(jack->input_dev); + if (!idev) return; - }
for (i = 0; i < ARRAY_SIZE(jack->key); i++) { int testbit = ((SND_JACK_BTN_0 >> i) & ~mask_bits);
if (jack->type & testbit) - input_report_key(jack->input_dev, jack->key[i], + input_report_key(idev, jack->key[i], status & testbit); }
@@ -688,13 +687,13 @@ void snd_jack_report(struct snd_jack *ja int testbit = ((1 << i) & ~mask_bits);
if (jack->type & testbit) - input_report_switch(jack->input_dev, + input_report_switch(idev, jack_switch_types[i], status & testbit); }
- input_sync(jack->input_dev); - mutex_unlock(&jack->input_dev_lock); + input_sync(idev); + input_put_device(idev); #endif /* CONFIG_SND_JACK_INPUT_DEV */ } EXPORT_SYMBOL(snd_jack_report);
From: Michael Schmitz schmitzmic@gmail.com
commit fc3d092c6bb48d5865fec15ed5b333c12f36288c upstream.
The Amiga partition parser module uses signed int for partition sector address and count, which will overflow for disks larger than 1 TB.
Use sector_t as type for sector address and size to allow using disks up to 2 TB without LBD support, and disks larger than 2 TB with LBD.
This bug was reported originally in 2012, and the fix was created by the RDB author, Joanne Dow jdow@earthlink.net. A patch had been discussed and reviewed on linux-m68k at that time but never officially submitted. This patch differs from Joanne's patch only in its use of sector_t instead of unsigned int. No checking for overflows is done (see patch 3 of this series for that).
Reported-by: Martin Steigerwald Martin@lichtvoll.de Closes: https://bugzilla.kernel.org/show_bug.cgi?id=43511 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Message-ID: 201206192146.09327.Martin@lichtvoll.de Cc: stable@vger.kernel.org # 5.2 Signed-off-by: Michael Schmitz schmitzmic@gmail.com Tested-by: Martin Steigerwald Martin@lichtvoll.de Reviewed-by: Geert Uytterhoeven geert@linux-m68k.org Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20230620201725.7020-2-schmitzmic@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/partitions/amiga.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/block/partitions/amiga.c +++ b/block/partitions/amiga.c @@ -31,7 +31,8 @@ int amiga_partition(struct parsed_partit unsigned char *data; struct RigidDiskBlock *rdb; struct PartitionBlock *pb; - int start_sect, nr_sects, blk, part, res = 0; + sector_t start_sect, nr_sects; + int blk, part, res = 0; int blksize = 1; /* Multiplier for disk block size */ int slot = 1;
@@ -96,14 +97,14 @@ int amiga_partition(struct parsed_partit
/* Tell Kernel about it */
- nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 - - be32_to_cpu(pb->pb_Environment[9])) * + nr_sects = ((sector_t)be32_to_cpu(pb->pb_Environment[10]) + 1 - + be32_to_cpu(pb->pb_Environment[9])) * be32_to_cpu(pb->pb_Environment[3]) * be32_to_cpu(pb->pb_Environment[5]) * blksize; if (!nr_sects) continue; - start_sect = be32_to_cpu(pb->pb_Environment[9]) * + start_sect = (sector_t)be32_to_cpu(pb->pb_Environment[9]) * be32_to_cpu(pb->pb_Environment[3]) * be32_to_cpu(pb->pb_Environment[5]) * blksize;
From: Michael Schmitz schmitzmic@gmail.com
commit b6f3f28f604ba3de4724ad82bea6adb1300c0b5f upstream.
The Amiga partition parser module uses signed int for partition sector address and count, which will overflow for disks larger than 1 TB.
Use u64 as type for sector address and size to allow using disks up to 2 TB without LBD support, and disks larger than 2 TB with LBD. The RBD format allows to specify disk sizes up to 2^128 bytes (though native OS limitations reduce this somewhat, to max 2^68 bytes), so check for u64 overflow carefully to protect against overflowing sector_t.
Bail out if sector addresses overflow 32 bits on kernels without LBD support.
This bug was reported originally in 2012, and the fix was created by the RDB author, Joanne Dow jdow@earthlink.net. A patch had been discussed and reviewed on linux-m68k at that time but never officially submitted (now resubmitted as patch 1 in this series). This patch adds additional error checking and warning messages.
Reported-by: Martin Steigerwald Martin@lichtvoll.de Closes: https://bugzilla.kernel.org/show_bug.cgi?id=43511 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Message-ID: 201206192146.09327.Martin@lichtvoll.de Cc: stable@vger.kernel.org # 5.2 Signed-off-by: Michael Schmitz schmitzmic@gmail.com Reviewed-by: Geert Uytterhoeven geert@linux-m68k.org Reviewed-by: Christoph Hellwig hch@infradead.org Link: https://lore.kernel.org/r/20230620201725.7020-4-schmitzmic@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/partitions/amiga.c | 103 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 85 insertions(+), 18 deletions(-)
--- a/block/partitions/amiga.c +++ b/block/partitions/amiga.c @@ -11,10 +11,18 @@ #define pr_fmt(fmt) fmt
#include <linux/types.h> +#include <linux/mm_types.h> +#include <linux/overflow.h> #include <linux/affs_hardblocks.h>
#include "check.h"
+/* magic offsets in partition DosEnvVec */ +#define NR_HD 3 +#define NR_SECT 5 +#define LO_CYL 9 +#define HI_CYL 10 + static __inline__ u32 checksum_block(__be32 *m, int size) { @@ -31,9 +39,12 @@ int amiga_partition(struct parsed_partit unsigned char *data; struct RigidDiskBlock *rdb; struct PartitionBlock *pb; - sector_t start_sect, nr_sects; - int blk, part, res = 0; - int blksize = 1; /* Multiplier for disk block size */ + u64 start_sect, nr_sects; + sector_t blk, end_sect; + u32 cylblk; /* rdb_CylBlocks = nr_heads*sect_per_track */ + u32 nr_hd, nr_sect, lo_cyl, hi_cyl; + int part, res = 0; + unsigned int blksize = 1; /* Multiplier for disk block size */ int slot = 1;
for (blk = 0; ; blk++, put_dev_sector(sect)) { @@ -41,7 +52,7 @@ int amiga_partition(struct parsed_partit goto rdb_done; data = read_part_sector(state, blk, §); if (!data) { - pr_err("Dev %s: unable to read RDB block %d\n", + pr_err("Dev %s: unable to read RDB block %llu\n", state->disk->disk_name, blk); res = -1; goto rdb_done; @@ -58,12 +69,12 @@ int amiga_partition(struct parsed_partit *(__be32 *)(data+0xdc) = 0; if (checksum_block((__be32 *)data, be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)==0) { - pr_err("Trashed word at 0xd0 in block %d ignored in checksum calculation\n", + pr_err("Trashed word at 0xd0 in block %llu ignored in checksum calculation\n", blk); break; }
- pr_err("Dev %s: RDB in block %d has bad checksum\n", + pr_err("Dev %s: RDB in block %llu has bad checksum\n", state->disk->disk_name, blk); }
@@ -80,10 +91,15 @@ int amiga_partition(struct parsed_partit blk = be32_to_cpu(rdb->rdb_PartitionList); put_dev_sector(sect); for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) { - blk *= blksize; /* Read in terms partition table understands */ + /* Read in terms partition table understands */ + if (check_mul_overflow(blk, (sector_t) blksize, &blk)) { + pr_err("Dev %s: overflow calculating partition block %llu! Skipping partitions %u and beyond\n", + state->disk->disk_name, blk, part); + break; + } data = read_part_sector(state, blk, §); if (!data) { - pr_err("Dev %s: unable to read partition block %d\n", + pr_err("Dev %s: unable to read partition block %llu\n", state->disk->disk_name, blk); res = -1; goto rdb_done; @@ -95,19 +111,70 @@ int amiga_partition(struct parsed_partit if (checksum_block((__be32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 ) continue;
- /* Tell Kernel about it */ + /* RDB gives us more than enough rope to hang ourselves with, + * many times over (2^128 bytes if all fields max out). + * Some careful checks are in order, so check for potential + * overflows. + * We are multiplying four 32 bit numbers to one sector_t! + */ + + nr_hd = be32_to_cpu(pb->pb_Environment[NR_HD]); + nr_sect = be32_to_cpu(pb->pb_Environment[NR_SECT]); + + /* CylBlocks is total number of blocks per cylinder */ + if (check_mul_overflow(nr_hd, nr_sect, &cylblk)) { + pr_err("Dev %s: heads*sects %u overflows u32, skipping partition!\n", + state->disk->disk_name, cylblk); + continue; + } + + /* check for consistency with RDB defined CylBlocks */ + if (cylblk > be32_to_cpu(rdb->rdb_CylBlocks)) { + pr_warn("Dev %s: cylblk %u > rdb_CylBlocks %u!\n", + state->disk->disk_name, cylblk, + be32_to_cpu(rdb->rdb_CylBlocks)); + } + + /* RDB allows for variable logical block size - + * normalize to 512 byte blocks and check result. + */ + + if (check_mul_overflow(cylblk, blksize, &cylblk)) { + pr_err("Dev %s: partition %u bytes per cyl. overflows u32, skipping partition!\n", + state->disk->disk_name, part); + continue; + } + + /* Calculate partition start and end. Limit of 32 bit on cylblk + * guarantees no overflow occurs if LBD support is enabled. + */ + + lo_cyl = be32_to_cpu(pb->pb_Environment[LO_CYL]); + start_sect = ((u64) lo_cyl * cylblk); + + hi_cyl = be32_to_cpu(pb->pb_Environment[HI_CYL]); + nr_sects = (((u64) hi_cyl - lo_cyl + 1) * cylblk);
- nr_sects = ((sector_t)be32_to_cpu(pb->pb_Environment[10]) + 1 - - be32_to_cpu(pb->pb_Environment[9])) * - be32_to_cpu(pb->pb_Environment[3]) * - be32_to_cpu(pb->pb_Environment[5]) * - blksize; if (!nr_sects) continue; - start_sect = (sector_t)be32_to_cpu(pb->pb_Environment[9]) * - be32_to_cpu(pb->pb_Environment[3]) * - be32_to_cpu(pb->pb_Environment[5]) * - blksize; + + /* Warn user if partition end overflows u32 (AmigaDOS limit) */ + + if ((start_sect + nr_sects) > UINT_MAX) { + pr_warn("Dev %s: partition %u (%llu-%llu) needs 64 bit device support!\n", + state->disk->disk_name, part, + start_sect, start_sect + nr_sects); + } + + if (check_add_overflow(start_sect, nr_sects, &end_sect)) { + pr_err("Dev %s: partition %u (%llu-%llu) needs LBD device support, skipping partition!\n", + state->disk->disk_name, part, + start_sect, end_sect); + continue; + } + + /* Tell Kernel about it */ + put_partition(state,slot++,start_sect,nr_sects); { /* Be even more informative to aid mounting */
From: Michael Schmitz schmitzmic@gmail.com
commit 95a55437dc49fb3342c82e61f5472a71c63d9ed0 upstream.
The Amiga partition parser module uses signed int for partition sector address and count, which will overflow for disks larger than 1 TB.
Use u64 as type for sector address and size to allow using disks up to 2 TB without LBD support, and disks larger than 2 TB with LBD. The RBD format allows to specify disk sizes up to 2^128 bytes (though native OS limitations reduce this somewhat, to max 2^68 bytes), so check for u64 overflow carefully to protect against overflowing sector_t.
This bug was reported originally in 2012, and the fix was created by the RDB author, Joanne Dow jdow@earthlink.net. A patch had been discussed and reviewed on linux-m68k at that time but never officially submitted (now resubmitted as patch 1 of this series).
Patch 3 (this series) adds additional error checking and warning messages. One of the error checks now makes use of the previously unused rdb_CylBlocks field, which causes a 'sparse' warning (cast to restricted __be32).
Annotate all 32 bit fields in affs_hardblocks.h as __be32, as the on-disk format of RDB and partition blocks is always big endian.
Reported-by: Martin Steigerwald Martin@lichtvoll.de Closes: https://bugzilla.kernel.org/show_bug.cgi?id=43511 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Message-ID: 201206192146.09327.Martin@lichtvoll.de Cc: stable@vger.kernel.org # 5.2 Signed-off-by: Michael Schmitz schmitzmic@gmail.com Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Geert Uytterhoeven geert@linux-m68k.org Link: https://lore.kernel.org/r/20230620201725.7020-3-schmitzmic@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/uapi/linux/affs_hardblocks.h | 68 +++++++++++++++++------------------ 1 file changed, 34 insertions(+), 34 deletions(-)
--- a/include/uapi/linux/affs_hardblocks.h +++ b/include/uapi/linux/affs_hardblocks.h @@ -7,42 +7,42 @@ /* Just the needed definitions for the RDB of an Amiga HD. */
struct RigidDiskBlock { - __u32 rdb_ID; + __be32 rdb_ID; __be32 rdb_SummedLongs; - __s32 rdb_ChkSum; - __u32 rdb_HostID; + __be32 rdb_ChkSum; + __be32 rdb_HostID; __be32 rdb_BlockBytes; - __u32 rdb_Flags; - __u32 rdb_BadBlockList; + __be32 rdb_Flags; + __be32 rdb_BadBlockList; __be32 rdb_PartitionList; - __u32 rdb_FileSysHeaderList; - __u32 rdb_DriveInit; - __u32 rdb_Reserved1[6]; - __u32 rdb_Cylinders; - __u32 rdb_Sectors; - __u32 rdb_Heads; - __u32 rdb_Interleave; - __u32 rdb_Park; - __u32 rdb_Reserved2[3]; - __u32 rdb_WritePreComp; - __u32 rdb_ReducedWrite; - __u32 rdb_StepRate; - __u32 rdb_Reserved3[5]; - __u32 rdb_RDBBlocksLo; - __u32 rdb_RDBBlocksHi; - __u32 rdb_LoCylinder; - __u32 rdb_HiCylinder; - __u32 rdb_CylBlocks; - __u32 rdb_AutoParkSeconds; - __u32 rdb_HighRDSKBlock; - __u32 rdb_Reserved4; + __be32 rdb_FileSysHeaderList; + __be32 rdb_DriveInit; + __be32 rdb_Reserved1[6]; + __be32 rdb_Cylinders; + __be32 rdb_Sectors; + __be32 rdb_Heads; + __be32 rdb_Interleave; + __be32 rdb_Park; + __be32 rdb_Reserved2[3]; + __be32 rdb_WritePreComp; + __be32 rdb_ReducedWrite; + __be32 rdb_StepRate; + __be32 rdb_Reserved3[5]; + __be32 rdb_RDBBlocksLo; + __be32 rdb_RDBBlocksHi; + __be32 rdb_LoCylinder; + __be32 rdb_HiCylinder; + __be32 rdb_CylBlocks; + __be32 rdb_AutoParkSeconds; + __be32 rdb_HighRDSKBlock; + __be32 rdb_Reserved4; char rdb_DiskVendor[8]; char rdb_DiskProduct[16]; char rdb_DiskRevision[4]; char rdb_ControllerVendor[8]; char rdb_ControllerProduct[16]; char rdb_ControllerRevision[4]; - __u32 rdb_Reserved5[10]; + __be32 rdb_Reserved5[10]; };
#define IDNAME_RIGIDDISK 0x5244534B /* "RDSK" */ @@ -50,16 +50,16 @@ struct RigidDiskBlock { struct PartitionBlock { __be32 pb_ID; __be32 pb_SummedLongs; - __s32 pb_ChkSum; - __u32 pb_HostID; + __be32 pb_ChkSum; + __be32 pb_HostID; __be32 pb_Next; - __u32 pb_Flags; - __u32 pb_Reserved1[2]; - __u32 pb_DevFlags; + __be32 pb_Flags; + __be32 pb_Reserved1[2]; + __be32 pb_DevFlags; __u8 pb_DriveName[32]; - __u32 pb_Reserved2[15]; + __be32 pb_Reserved2[15]; __be32 pb_Environment[17]; - __u32 pb_EReserved[15]; + __be32 pb_EReserved[15]; };
#define IDNAME_PARTITION 0x50415254 /* "PART" */
From: Demi Marie Obenour demi@invisiblethingslab.com
commit b90ecc0379eb7bbe79337b0c7289390a98752646 upstream.
Currently, associating a loop device with a different file descriptor does not increment its diskseq. This allows the following race condition:
1. Program X opens a loop device 2. Program X gets the diskseq of the loop device. 3. Program X associates a file with the loop device. 4. Program X passes the loop device major, minor, and diskseq to something. 5. Program X exits. 6. Program Y detaches the file from the loop device. 7. Program Y attaches a different file to the loop device. 8. The opener finally gets around to opening the loop device and checks that the diskseq is what it expects it to be. Even though the diskseq is the expected value, the result is that the opener is accessing the wrong file.
From discussions with Christoph Hellwig, it appears that
disk_force_media_change() was supposed to call inc_diskseq(), but in fact it does not. Adding a Fixes: tag to indicate this. Christoph's Reported-by is because he stated that disk_force_media_change() calls inc_diskseq(), which is what led me to discover that it should but does not.
Reported-by: Christoph Hellwig hch@infradead.org Signed-off-by: Demi Marie Obenour demi@invisiblethingslab.com Fixes: e6138dc12de9 ("block: add a helper to raise a media changed event") Cc: stable@vger.kernel.org # 5.15+ Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20230607170837.1559-1-demi@invisiblethingslab.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/disk-events.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/block/disk-events.c b/block/disk-events.c index 8b1b63225738..0cfac464e6d1 100644 --- a/block/disk-events.c +++ b/block/disk-events.c @@ -307,6 +307,7 @@ bool disk_force_media_change(struct gendisk *disk, unsigned int events) if (!(events & DISK_EVENT_MEDIA_CHANGE)) return false;
+ inc_diskseq(disk); if (__invalidate_device(disk->part0, true)) pr_warn("VFS: busy inodes on changed media %s\n", disk->disk_name);
From: Ding Hui dinghui@sangfor.com.cn
commit fc80fc2d4e39137869da3150ee169b40bf879287 upstream.
After the listener svc_sock is freed, and before invoking svc_tcp_accept() for the established child sock, there is a window that the newsock retaining a freed listener svc_sock in sk_user_data which cloning from parent. In the race window, if data is received on the newsock, we will observe use-after-free report in svc_tcp_listen_data_ready().
Reproduce by two tasks:
1. while :; do rpc.nfsd 0 ; rpc.nfsd; done 2. while :; do echo "" | ncat -4 127.0.0.1 2049 ; done
KASAN report:
================================================================== BUG: KASAN: slab-use-after-free in svc_tcp_listen_data_ready+0x1cf/0x1f0 [sunrpc] Read of size 8 at addr ffff888139d96228 by task nc/102553 CPU: 7 PID: 102553 Comm: nc Not tainted 6.3.0+ #18 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 Call Trace: <IRQ> dump_stack_lvl+0x33/0x50 print_address_description.constprop.0+0x27/0x310 print_report+0x3e/0x70 kasan_report+0xae/0xe0 svc_tcp_listen_data_ready+0x1cf/0x1f0 [sunrpc] tcp_data_queue+0x9f4/0x20e0 tcp_rcv_established+0x666/0x1f60 tcp_v4_do_rcv+0x51c/0x850 tcp_v4_rcv+0x23fc/0x2e80 ip_protocol_deliver_rcu+0x62/0x300 ip_local_deliver_finish+0x267/0x350 ip_local_deliver+0x18b/0x2d0 ip_rcv+0x2fb/0x370 __netif_receive_skb_one_core+0x166/0x1b0 process_backlog+0x24c/0x5e0 __napi_poll+0xa2/0x500 net_rx_action+0x854/0xc90 __do_softirq+0x1bb/0x5de do_softirq+0xcb/0x100 </IRQ> <TASK> ... </TASK>
Allocated by task 102371: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 __kasan_kmalloc+0x7b/0x90 svc_setup_socket+0x52/0x4f0 [sunrpc] svc_addsock+0x20d/0x400 [sunrpc] __write_ports_addfd+0x209/0x390 [nfsd] write_ports+0x239/0x2c0 [nfsd] nfsctl_transaction_write+0xac/0x110 [nfsd] vfs_write+0x1c3/0xae0 ksys_write+0xed/0x1c0 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc
Freed by task 102551: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 kasan_save_free_info+0x2a/0x50 __kasan_slab_free+0x106/0x190 __kmem_cache_free+0x133/0x270 svc_xprt_free+0x1e2/0x350 [sunrpc] svc_xprt_destroy_all+0x25a/0x440 [sunrpc] nfsd_put+0x125/0x240 [nfsd] nfsd_svc+0x2cb/0x3c0 [nfsd] write_threads+0x1ac/0x2a0 [nfsd] nfsctl_transaction_write+0xac/0x110 [nfsd] vfs_write+0x1c3/0xae0 ksys_write+0xed/0x1c0 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc
Fix the UAF by simply doing nothing in svc_tcp_listen_data_ready() if state != TCP_LISTEN, that will avoid dereferencing svsk for all child socket.
Link: https://lore.kernel.org/lkml/20230507091131.23540-1-dinghui@sangfor.com.cn/ Fixes: fa9251afc33c ("SUNRPC: Call the default socket callbacks instead of open coding") Signed-off-by: Ding Hui dinghui@sangfor.com.cn Cc: stable@vger.kernel.org Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/sunrpc/svcsock.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
--- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -685,12 +685,6 @@ static void svc_tcp_listen_data_ready(st { struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data;
- if (svsk) { - /* Refer to svc_setup_socket() for details. */ - rmb(); - svsk->sk_odata(sk); - } - /* * This callback may called twice when a new connection * is established as a child socket inherits everything @@ -699,13 +693,18 @@ static void svc_tcp_listen_data_ready(st * when one of child sockets become ESTABLISHED. * 2) data_ready method of the child socket may be called * when it receives data before the socket is accepted. - * In case of 2, we should ignore it silently. + * In case of 2, we should ignore it silently and DO NOT + * dereference svsk. */ - if (sk->sk_state == TCP_LISTEN) { - if (svsk) { - set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); - svc_xprt_enqueue(&svsk->sk_xprt); - } + if (sk->sk_state != TCP_LISTEN) + return; + + if (svsk) { + /* Refer to svc_setup_socket() for details. */ + rmb(); + svsk->sk_odata(sk); + set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); + svc_xprt_enqueue(&svsk->sk_xprt); } }
From: Stefan Wahren stefan.wahren@i2se.com
[ Upstream commit dca5480ab7b77a889088ab7cac81934604510ac7 ]
The commit 67b392f7b8ed ("w1_therm: optimizing temperature read timings") accidentially inverted the logic for lock handling of the bus mutex.
Before: pullup -> release lock before sleep no pullup -> release lock after sleep
After: pullup -> release lock after sleep no pullup -> release lock before sleep
This cause spurious measurements of 85 degree (powerup value) on the Tarragon board with connected 1-w temperature sensor (w1_therm.w1_strong_pull=0).
In the meantime a new feature for polling the conversion completion has been integrated in these branches with commit 021da53e65fd ("w1: w1_therm: Add sysfs entries to control conversion time and driver features"). But this feature isn't available for parasite power mode, so handle this separately.
Link: https://lore.kernel.org/regressions/2023042645-attentive-amends-7b0b@gregkh/... Fixes: 67b392f7b8ed ("w1_therm: optimizing temperature read timings") Signed-off-by: Stefan Wahren stefan.wahren@i2se.com Link: https://lore.kernel.org/r/20230427112152.12313-1-stefan.wahren@i2se.com Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/w1/slaves/w1_therm.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 9cbeeb4923ecf..67d1cfbbb5f7f 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -1093,29 +1093,26 @@ static int convert_t(struct w1_slave *sl, struct therm_info *info)
w1_write_8(dev_master, W1_CONVERT_TEMP);
- if (strong_pullup) { /*some device need pullup */ + if (SLAVE_FEATURES(sl) & W1_THERM_POLL_COMPLETION) { + ret = w1_poll_completion(dev_master, W1_POLL_CONVERT_TEMP); + if (ret) { + dev_dbg(&sl->dev, "%s: Timeout\n", __func__); + goto mt_unlock; + } + mutex_unlock(&dev_master->bus_mutex); + } else if (!strong_pullup) { /*no device need pullup */ sleep_rem = msleep_interruptible(t_conv); if (sleep_rem != 0) { ret = -EINTR; goto mt_unlock; } mutex_unlock(&dev_master->bus_mutex); - } else { /*no device need pullup */ - if (SLAVE_FEATURES(sl) & W1_THERM_POLL_COMPLETION) { - ret = w1_poll_completion(dev_master, W1_POLL_CONVERT_TEMP); - if (ret) { - dev_dbg(&sl->dev, "%s: Timeout\n", __func__); - goto mt_unlock; - } - mutex_unlock(&dev_master->bus_mutex); - } else { - /* Fixed delay */ - mutex_unlock(&dev_master->bus_mutex); - sleep_rem = msleep_interruptible(t_conv); - if (sleep_rem != 0) { - ret = -EINTR; - goto dec_refcnt; - } + } else { /*some device need pullup */ + mutex_unlock(&dev_master->bus_mutex); + sleep_rem = msleep_interruptible(t_conv); + if (sleep_rem != 0) { + ret = -EINTR; + goto dec_refcnt; } } ret = read_scratchpad(sl, info);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 83f3fcf96fcc7e5405b37d9424c7ef26bfa203f8 ]
The __w1_remove_master_device() function calls:
list_del(&dev->w1_master_entry);
So presumably this can cause an endless loop.
Fixes: 7785925dd8e0 ("[PATCH] w1: cleanups.") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/w1/w1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 4a2ddf730a3ac..2eee26b7fc4a3 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -1263,10 +1263,10 @@ static int __init w1_init(void)
static void __exit w1_fini(void) { - struct w1_master *dev; + struct w1_master *dev, *n;
/* Set netlink removal messages and some cleanup */ - list_for_each_entry(dev, &w1_masters, w1_master_entry) + list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) __w1_remove_master_device(dev);
w1_fini_netlink();
From: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de
[ Upstream commit bc9d1f0cecd2407cfb2364a7d4be2f52d1d46a9d ]
Addresses the following warning when building j2_defconfig:
arch/sh/kernel/cpu/sh2/probe.c: In function 'scan_cache': arch/sh/kernel/cpu/sh2/probe.c:24:16: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 24 | j2_ccr_base = (u32 __iomem *)of_flat_dt_translate_address(node); |
Fixes: 5a846abad07f ("sh: add support for J-Core J2 processor") Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Tested-by: Rob Landley rob@landley.net Signed-off-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Link: https://lore.kernel.org/r/20230503125746.331835-1-glaubitz@physik.fu-berlin.... Signed-off-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sh/kernel/cpu/sh2/probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index d342ea08843f6..70a07f4f2142f 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -21,7 +21,7 @@ static int __init scan_cache(unsigned long node, const char *uname, if (!of_flat_dt_is_compatible(node, "jcore,cache")) return 0;
- j2_ccr_base = (u32 __iomem *)of_flat_dt_translate_address(node); + j2_ccr_base = ioremap(of_flat_dt_translate_address(node), 4);
return 1; }
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 55f223b8b408cbfd85fb1c5b74ab85ccab319a69 ]
Returning an error value in a platform driver's remove callback results in a generic error message being emitted by the driver core, but otherwise it doesn't make a difference. The device goes away anyhow.
For each case where ret is non-zero the driver already emits an error message, so suppress the generic error message by returning zero unconditionally. (Side note: The return value handling was unreliable anyhow as the value returned by dwc2_exit_hibernation() was overwritten anyhow if hsotg->in_ppd was non-zero.)
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Acked-by: Minas Harutyunyan hminas@synopsys.com Link: https://lore.kernel.org/r/20221017195914.1426297-1-u.kleine-koenig@pengutron... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Stable-dep-of: ada050c69108 ("usb: dwc2: Fix some error handling paths") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc2/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 7a09476e9f193..ad8c7de4bfb19 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -355,7 +355,7 @@ static int dwc2_driver_remove(struct platform_device *dev) reset_control_assert(hsotg->reset); reset_control_assert(hsotg->reset_ecc);
- return ret; + return 0; }
/**
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit ada050c69108bc34be13ecc11f7fad0f20ebadc4 ]
dwc2_driver_probe() calls dwc2_lowlevel_hw_init() which deassert some reset lines. Should an error happen in dwc2_lowlevel_hw_init() after calling reset_control_deassert() or in the probe after calling dwc2_lowlevel_hw_init(), the reset lines remain deasserted.
Add some devm_add_action_or_reset() calls to re-assert the lines if needed.
Update the remove function accordingly.
This change is compile-tested only.
Fixes: 83f8da562f8b ("usb: dwc2: Add reset control to dwc2") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/c64537b5339342bd00f7c2152b8fc23792b9f95a.168330647... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc2/platform.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index ad8c7de4bfb19..6496bfbd34ed9 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -205,6 +205,11 @@ int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) return ret; }
+static void dwc2_reset_control_assert(void *data) +{ + reset_control_assert(data); +} + static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) { int i, ret; @@ -217,6 +222,10 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) }
reset_control_deassert(hsotg->reset); + ret = devm_add_action_or_reset(hsotg->dev, dwc2_reset_control_assert, + hsotg->reset); + if (ret) + return ret;
hsotg->reset_ecc = devm_reset_control_get_optional(hsotg->dev, "dwc2-ecc"); if (IS_ERR(hsotg->reset_ecc)) { @@ -226,6 +235,10 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) }
reset_control_deassert(hsotg->reset_ecc); + ret = devm_add_action_or_reset(hsotg->dev, dwc2_reset_control_assert, + hsotg->reset_ecc); + if (ret) + return ret;
/* * Attempt to find a generic PHY, then look for an old style @@ -352,9 +365,6 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg);
- reset_control_assert(hsotg->reset); - reset_control_assert(hsotg->reset_ecc); - return 0; }
From: Tony Lindgren tony@atomide.com
[ Upstream commit b9ab22c2bc8652324a803b3e2be69838920b4025 ]
If serial8250_register_8250_port() fails, the SoC can hang as the deferred PMQoS work will still run as is not flushed and removed.
Fixes: 61929cf0169d ("tty: serial: Add 8250-core based omap driver") Signed-off-by: Tony Lindgren tony@atomide.com Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/r/20230508082014.23083-2-tony@atomide.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_omap.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 078a7028ee5a2..6fa0e3ca469a0 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -1469,7 +1469,9 @@ static int omap8250_probe(struct platform_device *pdev) err: pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_put_sync(&pdev->dev); + flush_work(&priv->qos_work); pm_runtime_disable(&pdev->dev); + cpu_latency_qos_remove_request(&priv->pm_qos_request); return ret; }
From: Taniya Das quic_tdas@quicinc.com
[ Upstream commit 3e4d179532423f299554cd0dedabdd9d2fdd238d ]
Camera titan top GDSC is a parent supply to all other camera GDSCs. Titan top GDSC is required to be enabled before enabling any other camera GDSCs and it should be disabled only after all other camera GDSCs are disabled. Ensure this behavior by marking titan top GDSC as parent of all other camera GDSCs.
Fixes: 15d09e830bbc ("clk: qcom: camcc: Add camera clock controller driver for SC7180") Signed-off-by: Taniya Das quic_tdas@quicinc.com Acked-by: Stephen Boyd sboyd@kernel.org Reviewed-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230501142932.13049-1-quic_tdas@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/camcc-sc7180.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/qcom/camcc-sc7180.c b/drivers/clk/qcom/camcc-sc7180.c index ce73ee9037cb0..4b3e3902b7eed 100644 --- a/drivers/clk/qcom/camcc-sc7180.c +++ b/drivers/clk/qcom/camcc-sc7180.c @@ -1493,12 +1493,21 @@ static struct clk_branch cam_cc_sys_tmr_clk = { }, };
+static struct gdsc titan_top_gdsc = { + .gdscr = 0xb134, + .pd = { + .name = "titan_top_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + static struct gdsc bps_gdsc = { .gdscr = 0x6004, .pd = { .name = "bps_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, .flags = HW_CTRL, };
@@ -1508,6 +1517,7 @@ static struct gdsc ife_0_gdsc = { .name = "ife_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, };
static struct gdsc ife_1_gdsc = { @@ -1516,6 +1526,7 @@ static struct gdsc ife_1_gdsc = { .name = "ife_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, };
static struct gdsc ipe_0_gdsc = { @@ -1525,15 +1536,9 @@ static struct gdsc ipe_0_gdsc = { }, .pwrsts = PWRSTS_OFF_ON, .flags = HW_CTRL, + .parent = &titan_top_gdsc.pd, };
-static struct gdsc titan_top_gdsc = { - .gdscr = 0xb134, - .pd = { - .name = "titan_top_gdsc", - }, - .pwrsts = PWRSTS_OFF_ON, -};
static struct clk_hw *cam_cc_sc7180_hws[] = { [CAM_CC_PLL2_OUT_EARLY] = &cam_cc_pll2_out_early.hw,
From: Mantas Pucka mantas@8devices.com
[ Upstream commit 56e5ae0116aef87273cf1812d608645b076e4f02 ]
SDCC clocks must be rounded down to avoid overclocking the controller.
Fixes: d9db07f088af ("clk: qcom: Add ipq6018 Global Clock Controller support") Signed-off-by: Mantas Pucka mantas@8devices.com Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/1682413909-24927-1-git-send-email-mantas@8devices.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gcc-ipq6018.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/gcc-ipq6018.c b/drivers/clk/qcom/gcc-ipq6018.c index 3f9c2f61a5d93..5c5d1b04ea7af 100644 --- a/drivers/clk/qcom/gcc-ipq6018.c +++ b/drivers/clk/qcom/gcc-ipq6018.c @@ -1654,7 +1654,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = { .name = "sdcc1_apps_clk_src", .parent_data = gcc_xo_gpll0_gpll2_gpll0_out_main_div2, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, };
From: Daniil Dulov d.dulov@aladdin.ru
[ Upstream commit fdaca63186f59fc664b346c45b76576624b48e57 ]
If az6007_read() returns error, there is no sence to continue.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 3af2f4f15a61 ("[media] az6007: Change the az6007 read/write routine parameter") Signed-off-by: Daniil Dulov d.dulov@aladdin.ru Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/dvb-usb-v2/az6007.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c index 62ee09f28a0bc..7524c90f5da61 100644 --- a/drivers/media/usb/dvb-usb-v2/az6007.c +++ b/drivers/media/usb/dvb-usb-v2/az6007.c @@ -202,7 +202,8 @@ static int az6007_rc_query(struct dvb_usb_device *d) unsigned code; enum rc_proto proto;
- az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); + if (az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10) < 0) + return -EIO;
if (st->data[1] == 0x44) return 0;
From: Marek Vasut marex@denx.de
[ Upstream commit 26ae58f65e64fa7ba61d64bae752e59e08380c6a ]
VIDIOC_ENUMINPUT documentation describes the tuner field of struct v4l2_input as index:
Documentation/userspace-api/media/v4l/vidioc-enuminput.rst " * - __u32 - ``tuner`` - Capture devices can have zero or more tuners (RF demodulators). When the ``type`` is set to ``V4L2_INPUT_TYPE_TUNER`` this is an RF connector and this field identifies the tuner. It corresponds to struct :c:type:`v4l2_tuner` field ``index``. For details on tuners see :ref:`tuner`. "
Drivers I could find also use the 'tuner' field as an index, e.g.: drivers/media/pci/bt8xx/bttv-driver.c bttv_enum_input() drivers/media/usb/go7007/go7007-v4l2.c vidioc_enum_input()
However, the UAPI comment claims this field is 'enum v4l2_tuner_type': include/uapi/linux/videodev2.h
This field being 'enum v4l2_tuner_type' is unlikely as it seems to be never used that way in drivers, and documentation confirms it. It seem this comment got in accidentally in the commit which this patch fixes. Fix the UAPI comment to stop confusion.
This was pointed out by Dmitry while reviewing VIDIOC_ENUMINPUT support for strace.
Fixes: 6016af82eafc ("[media] v4l2: use __u32 rather than enums in ioctl() structs") Signed-off-by: Marek Vasut marex@denx.de Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- include/uapi/linux/videodev2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 61c5011dfc13d..f5c6758464f25 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1652,7 +1652,7 @@ struct v4l2_input { __u8 name[32]; /* Label */ __u32 type; /* Type of input */ __u32 audioset; /* Associated audios (bitfield) */ - __u32 tuner; /* enum v4l2_tuner_type */ + __u32 tuner; /* Tuner index */ v4l2_std_id std; __u32 status; __u32 capabilities;
From: Duoming Zhou duoming@zju.edu.cn
[ Upstream commit 6f489a966fbeb0da63d45c2c66a8957eab604bf6 ]
The previous commit ebad8e731c1c ("media: usb: siano: Fix use after free bugs caused by do_submit_urb") adds cancel_work_sync() in smsusb_stop_streaming(). But smsusb_stop_streaming() may be called, even if the work_struct surb->wq has not been initialized. As a result, the warning will occur. One of the processes that could lead to warning is shown below:
smsusb_probe() smsusb_init_device() if (!dev->in_ep || !dev->out_ep || align < 0) { smsusb_term_device(intf); smsusb_stop_streaming() cancel_work_sync(&dev->surbs[i].wq); __cancel_work_timer() __flush_work() if (WARN_ON(!work->func)) // work->func is null
The log reported by syzbot is shown below:
WARNING: CPU: 0 PID: 897 at kernel/workqueue.c:3066 __flush_work+0x798/0xa80 kernel/workqueue.c:3063 Modules linked in: CPU: 0 PID: 897 Comm: kworker/0:2 Not tainted 6.2.0-rc1-syzkaller #0 RIP: 0010:__flush_work+0x798/0xa80 kernel/workqueue.c:3066 ... RSP: 0018:ffffc9000464ebf8 EFLAGS: 00010246 RAX: 1ffff11002dbb420 RBX: 0000000000000021 RCX: 1ffffffff204fa4e RDX: dffffc0000000000 RSI: 0000000000000001 RDI: ffff888016dda0e8 RBP: ffffc9000464ed98 R08: 0000000000000001 R09: ffffffff90253b2f R10: 0000000000000001 R11: 0000000000000000 R12: ffff888016dda0e8 R13: ffff888016dda0e8 R14: ffff888016dda100 R15: 0000000000000001 FS: 0000000000000000(0000) GS:ffff8880b9a00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffd4331efe8 CR3: 000000000b48e000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> __cancel_work_timer+0x315/0x460 kernel/workqueue.c:3160 smsusb_stop_streaming drivers/media/usb/siano/smsusb.c:182 [inline] smsusb_term_device+0xda/0x2d0 drivers/media/usb/siano/smsusb.c:344 smsusb_init_device+0x400/0x9ce drivers/media/usb/siano/smsusb.c:419 smsusb_probe+0xbbd/0xc55 drivers/media/usb/siano/smsusb.c:567 ...
This patch adds check before cancel_work_sync(). If surb->wq has not been initialized, the cancel_work_sync() will not be executed.
Reported-by: syzbot+27b0b464864741b18b99@syzkaller.appspotmail.com Fixes: ebad8e731c1c ("media: usb: siano: Fix use after free bugs caused by do_submit_urb") Signed-off-by: Duoming Zhou duoming@zju.edu.cn Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/siano/smsusb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index 1babfe6e2c361..5c223b5498b4b 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -179,7 +179,8 @@ static void smsusb_stop_streaming(struct smsusb_device_t *dev)
for (i = 0; i < MAX_URBS; i++) { usb_kill_urb(&dev->surbs[i].urb); - cancel_work_sync(&dev->surbs[i].wq); + if (dev->surbs[i].wq.func) + cancel_work_sync(&dev->surbs[i].wq);
if (dev->surbs[i].cb) { smscore_putbuffer(dev->coredev, dev->surbs[i].cb);
From: Daniel Scally dan.scally@ideasonboard.com
[ Upstream commit 306c3190b30d4d6a098888b9d7d4cefaa0ddcb91 ]
Format propagation in the st-mipid02 driver is incorrect in that when setting format for V4L2_SUBDEV_FORMAT_TRY on the source pad, the _active_ rather than _try_ format from the sink pad is propagated. This causes problems with format negotiation - update the function to propagate the correct format.
Fixes: 642bb5e88fed ("media: st-mipid02: MIPID02 CSI-2 to PARALLEL bridge driver") Signed-off-by: Daniel Scally dan.scally@ideasonboard.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/st-mipid02.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c index f630b88cbfaa9..cf55c57a79707 100644 --- a/drivers/media/i2c/st-mipid02.c +++ b/drivers/media/i2c/st-mipid02.c @@ -710,8 +710,13 @@ static void mipid02_set_fmt_source(struct v4l2_subdev *sd, { struct mipid02_dev *bridge = to_mipid02_dev(sd);
- /* source pad mirror active sink pad */ - format->format = bridge->fmt; + /* source pad mirror sink pad */ + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + format->format = bridge->fmt; + else + format->format = *v4l2_subdev_get_try_format(sd, sd_state, + MIPID02_SINK_0); + /* but code may need to be converted */ format->format.code = serial_to_parallel_code(format->format.code);
From: Stephan Gerhold stephan.gerhold@kernkonzept.com
[ Upstream commit 2cb8a39b6781ea23accd1fa93b3ad000d0948aec ]
The amount of time required between asserting and deasserting the reset signal can vary depending on the involved hardware component. Sometimes 1 us might not be enough and a larger delay is necessary to conform to the specifications.
Usually this is worked around in the consuming drivers, by replacing reset_control_reset() with a sequence of reset_control_assert(), waiting for a custom delay, followed by reset_control_deassert().
However, in some cases the driver making use of the reset is generic and can be used with different reset controllers. In this case the reset time requirement is better handled directly by the reset controller driver.
Make this possible by adding an "udelay" field to the qcom_reset_map that allows setting a different reset delay (in microseconds).
Signed-off-by: Stephan Gerhold stephan.gerhold@kernkonzept.com Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20220706134132.3623415-4-stephan.gerhold@kernkonze... Stable-dep-of: 349b5bed539b ("clk: qcom: ipq6018: fix networking resets") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/reset.c | 4 +++- drivers/clk/qcom/reset.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c index 819d194be8f7b..2a16adb572d2b 100644 --- a/drivers/clk/qcom/reset.c +++ b/drivers/clk/qcom/reset.c @@ -13,8 +13,10 @@
static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id) { + struct qcom_reset_controller *rst = to_qcom_reset_controller(rcdev); + rcdev->ops->assert(rcdev, id); - udelay(1); + udelay(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */ rcdev->ops->deassert(rcdev, id); return 0; } diff --git a/drivers/clk/qcom/reset.h b/drivers/clk/qcom/reset.h index 2a08b5e282c77..b8c113582072b 100644 --- a/drivers/clk/qcom/reset.h +++ b/drivers/clk/qcom/reset.h @@ -11,6 +11,7 @@ struct qcom_reset_map { unsigned int reg; u8 bit; + u8 udelay; };
struct regmap;
From: Robert Marko robimarko@gmail.com
[ Upstream commit 4a5210893625f89723ea210d7c630b730abb37ad ]
This patch adds the support for giving the complete bitmask in reset structure and reset operation will use this bitmask for all reset operations.
Currently, reset structure only takes a single bit for each reset and then calculates the bitmask by using the BIT() macro.
However, this is not sufficient anymore for newer SoC-s like IPQ8074, IPQ6018 and more, since their networking resets require multiple bits to be asserted in order to properly reset the HW block completely.
So, in order to allow asserting multiple bits add "bitmask" field to qcom_reset_map, and then use that bitmask value if its populated in the driver, if its not populated, then we just default to existing behaviour and calculate the bitmask on the fly.
Signed-off-by: Robert Marko robimarko@gmail.com Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20221107132901.489240-1-robimarko@gmail.com Stable-dep-of: 349b5bed539b ("clk: qcom: ipq6018: fix networking resets") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/reset.c | 4 ++-- drivers/clk/qcom/reset.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c index 2a16adb572d2b..0e914ec7aeae1 100644 --- a/drivers/clk/qcom/reset.c +++ b/drivers/clk/qcom/reset.c @@ -30,7 +30,7 @@ qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
rst = to_qcom_reset_controller(rcdev); map = &rst->reset_map[id]; - mask = BIT(map->bit); + mask = map->bitmask ? map->bitmask : BIT(map->bit);
return regmap_update_bits(rst->regmap, map->reg, mask, mask); } @@ -44,7 +44,7 @@ qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
rst = to_qcom_reset_controller(rcdev); map = &rst->reset_map[id]; - mask = BIT(map->bit); + mask = map->bitmask ? map->bitmask : BIT(map->bit);
return regmap_update_bits(rst->regmap, map->reg, mask, 0); } diff --git a/drivers/clk/qcom/reset.h b/drivers/clk/qcom/reset.h index b8c113582072b..9a47c838d9b1b 100644 --- a/drivers/clk/qcom/reset.h +++ b/drivers/clk/qcom/reset.h @@ -12,6 +12,7 @@ struct qcom_reset_map { unsigned int reg; u8 bit; u8 udelay; + u32 bitmask; };
struct regmap;
From: Robert Marko robimarko@gmail.com
[ Upstream commit 349b5bed539b491b7894a5186a895751fd8ba6c7 ]
Networking resets in IPQ6018 all use bitmask as they require multiple bits to be set and cleared instead of a single bit.
So, current networking resets have the same register and bit 0 set which is clearly incorrect.
Fixes: d9db07f088af ("clk: qcom: Add ipq6018 Global Clock Controller support") Signed-off-by: Robert Marko robimarko@gmail.com Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230526190855.2941291-2-robimarko@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gcc-ipq6018.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/clk/qcom/gcc-ipq6018.c b/drivers/clk/qcom/gcc-ipq6018.c index 5c5d1b04ea7af..cde62a11f5736 100644 --- a/drivers/clk/qcom/gcc-ipq6018.c +++ b/drivers/clk/qcom/gcc-ipq6018.c @@ -4517,24 +4517,24 @@ static const struct qcom_reset_map gcc_ipq6018_resets[] = { [GCC_PCIE0_AHB_ARES] = { 0x75040, 5 }, [GCC_PCIE0_AXI_MASTER_STICKY_ARES] = { 0x75040, 6 }, [GCC_PCIE0_AXI_SLAVE_STICKY_ARES] = { 0x75040, 7 }, - [GCC_PPE_FULL_RESET] = { 0x68014, 0 }, - [GCC_UNIPHY0_SOFT_RESET] = { 0x56004, 0 }, + [GCC_PPE_FULL_RESET] = { .reg = 0x68014, .bitmask = 0xf0000 }, + [GCC_UNIPHY0_SOFT_RESET] = { .reg = 0x56004, .bitmask = 0x3ff2 }, [GCC_UNIPHY0_XPCS_RESET] = { 0x56004, 2 }, - [GCC_UNIPHY1_SOFT_RESET] = { 0x56104, 0 }, + [GCC_UNIPHY1_SOFT_RESET] = { .reg = 0x56104, .bitmask = 0x32 }, [GCC_UNIPHY1_XPCS_RESET] = { 0x56104, 2 }, - [GCC_EDMA_HW_RESET] = { 0x68014, 0 }, - [GCC_NSSPORT1_RESET] = { 0x68014, 0 }, - [GCC_NSSPORT2_RESET] = { 0x68014, 0 }, - [GCC_NSSPORT3_RESET] = { 0x68014, 0 }, - [GCC_NSSPORT4_RESET] = { 0x68014, 0 }, - [GCC_NSSPORT5_RESET] = { 0x68014, 0 }, - [GCC_UNIPHY0_PORT1_ARES] = { 0x56004, 0 }, - [GCC_UNIPHY0_PORT2_ARES] = { 0x56004, 0 }, - [GCC_UNIPHY0_PORT3_ARES] = { 0x56004, 0 }, - [GCC_UNIPHY0_PORT4_ARES] = { 0x56004, 0 }, - [GCC_UNIPHY0_PORT5_ARES] = { 0x56004, 0 }, - [GCC_UNIPHY0_PORT_4_5_RESET] = { 0x56004, 0 }, - [GCC_UNIPHY0_PORT_4_RESET] = { 0x56004, 0 }, + [GCC_EDMA_HW_RESET] = { .reg = 0x68014, .bitmask = 0x300000 }, + [GCC_NSSPORT1_RESET] = { .reg = 0x68014, .bitmask = 0x1000003 }, + [GCC_NSSPORT2_RESET] = { .reg = 0x68014, .bitmask = 0x200000c }, + [GCC_NSSPORT3_RESET] = { .reg = 0x68014, .bitmask = 0x4000030 }, + [GCC_NSSPORT4_RESET] = { .reg = 0x68014, .bitmask = 0x8000300 }, + [GCC_NSSPORT5_RESET] = { .reg = 0x68014, .bitmask = 0x10000c00 }, + [GCC_UNIPHY0_PORT1_ARES] = { .reg = 0x56004, .bitmask = 0x30 }, + [GCC_UNIPHY0_PORT2_ARES] = { .reg = 0x56004, .bitmask = 0xc0 }, + [GCC_UNIPHY0_PORT3_ARES] = { .reg = 0x56004, .bitmask = 0x300 }, + [GCC_UNIPHY0_PORT4_ARES] = { .reg = 0x56004, .bitmask = 0xc00 }, + [GCC_UNIPHY0_PORT5_ARES] = { .reg = 0x56004, .bitmask = 0x3000 }, + [GCC_UNIPHY0_PORT_4_5_RESET] = { .reg = 0x56004, .bitmask = 0x3c02 }, + [GCC_UNIPHY0_PORT_4_RESET] = { .reg = 0x56004, .bitmask = 0xc02 }, [GCC_LPASS_BCR] = {0x1F000, 0}, [GCC_UBI32_TBU_BCR] = {0x65000, 0}, [GCC_LPASS_TBU_BCR] = {0x6C000, 0},
From: Vladislav Efanov VEfanov@ispras.ru
[ Upstream commit 097fb3ee710d4de83b8d4f5589e8ee13e0f0541e ]
Function dwc3_qcom_probe() allocates memory for resource structure which is pointed by parent_res pointer. This memory is not freed. This leads to memory leak. Use stack memory to prevent memory leak.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 2bc02355f8ba ("usb: dwc3: qcom: Add support for booting with ACPI") Signed-off-by: Vladislav Efanov VEfanov@ispras.ru Acked-by: Shawn Guo shawn.guo@linaro.org Link: https://lore.kernel.org/r/20230517172518.442591-1-VEfanov@ispras.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/dwc3-qcom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index 28bc7480acf3c..c55f939168fce 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -727,6 +727,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct dwc3_qcom *qcom; struct resource *res, *parent_res = NULL; + struct resource local_res; int ret, i; bool ignore_pipe_clk;
@@ -777,9 +778,8 @@ static int dwc3_qcom_probe(struct platform_device *pdev) if (np) { parent_res = res; } else { - parent_res = kmemdup(res, sizeof(struct resource), GFP_KERNEL); - if (!parent_res) - return -ENOMEM; + memcpy(&local_res, res, sizeof(struct resource)); + parent_res = &local_res;
parent_res->start = res->start + qcom->acpi_pdata->qscratch_base_offset;
From: Prashanth K quic_prashk@quicinc.com
[ Upstream commit 2f6ecb89fe8feb2b60a53325b0eeb9866d88909a ]
Consider a case where gserial_disconnect has already cleared gser->ioport. And if gserial_suspend gets called afterwards, it will lead to accessing of gser->ioport and thus causing null pointer dereference.
Avoid this by adding a null pointer check. Added a static spinlock to prevent gser->ioport from becoming null after the newly added null pointer check.
Fixes: aba3a8d01d62 ("usb: gadget: u_serial: add suspend resume callbacks") Signed-off-by: Prashanth K quic_prashk@quicinc.com Link: https://lore.kernel.org/r/1683278317-11774-1-git-send-email-quic_prashk@quic... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/u_serial.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 116d2e15e9b22..a8d1e8b192c55 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -1419,10 +1419,19 @@ EXPORT_SYMBOL_GPL(gserial_disconnect);
void gserial_suspend(struct gserial *gser) { - struct gs_port *port = gser->ioport; + struct gs_port *port; unsigned long flags;
- spin_lock_irqsave(&port->port_lock, flags); + spin_lock_irqsave(&serial_port_lock, flags); + port = gser->ioport; + + if (!port) { + spin_unlock_irqrestore(&serial_port_lock, flags); + return; + } + + spin_lock(&port->port_lock); + spin_unlock(&serial_port_lock); port->suspended = true; spin_unlock_irqrestore(&port->port_lock, flags); }
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 7e77e0b7a9f4cdf91cb0950749b40c840ea63efc ]
Kernel documentation has to be synchronized with a code, otherwise the validator is not happy:
Function parameter or member 'usb_propval' not described in 'extcon_cable' Function parameter or member 'chg_propval' not described in 'extcon_cable' Function parameter or member 'jack_propval' not described in 'extcon_cable' Function parameter or member 'disp_propval' not described in 'extcon_cable'
Describe the fields added in the past.
Fixes: 067c1652e7a7 ("extcon: Add the support for extcon property according to extcon type") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Chanwoo Choi cw00.choi@samsung.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/extcon/extcon.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index f305503ec27ed..6b0681666e8e1 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -196,6 +196,10 @@ static const struct __extcon_info { * @attr_name: "name" sysfs entry * @attr_state: "state" sysfs entry * @attrs: the array pointing to attr_name and attr_state for attr_g + * @usb_propval: the array of USB connector properties + * @chg_propval: the array of charger connector properties + * @jack_propval: the array of jack connector properties + * @disp_propval: the array of display connector properties */ struct extcon_cable { struct extcon_dev *edev;
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 73346b9965ebda2feb7fef8629e9b28baee820e3 ]
Kernel documentation has to be synchronized with a code, otherwise the validator is not happy:
Function parameter or member 'usb_bits' not described in 'extcon_cable' Function parameter or member 'chg_bits' not described in 'extcon_cable' Function parameter or member 'jack_bits' not described in 'extcon_cable' Function parameter or member 'disp_bits' not described in 'extcon_cable'
Describe the fields added in the past.
Fixes: ceaa98f442cf ("extcon: Add the support for the capability of each property") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Chanwoo Choi cw00.choi@samsung.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/extcon/extcon.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 6b0681666e8e1..6a0d55d627ad0 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -200,6 +200,10 @@ static const struct __extcon_info { * @chg_propval: the array of charger connector properties * @jack_propval: the array of jack connector properties * @disp_propval: the array of display connector properties + * @usb_bits: the bit array of the USB connector property capabilities + * @chg_bits: the bit array of the charger connector property capabilities + * @jack_bits: the bit array of the jack connector property capabilities + * @disp_bits: the bit array of the display connector property capabilities */ struct extcon_cable { struct extcon_dev *edev;
From: Li Yang lidaxian@hust.edu.cn
[ Upstream commit 342161c11403ea00e9febc16baab1d883d589d04 ]
Smatch reports: drivers/usb/phy/phy-tahvo.c: tahvo_usb_probe() warn: missing unwind goto?
After geting irq, if ret < 0, it will return without error handling to free memory. Just add error handling to fix this problem.
Fixes: 0d45a1373e66 ("usb: phy: tahvo: add IRQ check") Signed-off-by: Li Yang lidaxian@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Link: https://lore.kernel.org/r/20230420140832.9110-1-lidaxian@hust.edu.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/phy/phy-tahvo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c index a3e043e3e4aae..d0672b6712985 100644 --- a/drivers/usb/phy/phy-tahvo.c +++ b/drivers/usb/phy/phy-tahvo.c @@ -395,7 +395,7 @@ static int tahvo_usb_probe(struct platform_device *pdev)
tu->irq = ret = platform_get_irq(pdev, 0); if (ret < 0) - return ret; + goto err_remove_phy; ret = request_threaded_irq(tu->irq, NULL, tahvo_usb_vbus_interrupt, IRQF_ONESHOT, "tahvo-vbus", tu);
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 8e6bd945e6dde64fbc60ec3fe252164493a8d3a2 ]
The declaration is in an #ifdef, which causes warnings when building with 'make W=1' and without CONFIG_PM:
drivers/usb/core/devio.c:742:6: error: no previous prototype for 'usbfs_notify_suspend' drivers/usb/core/devio.c:747:6: error: no previous prototype for 'usbfs_notify_resume'
Use the same #ifdef check around the function definitions to avoid the warnings and slightly shrink the USB core.
Fixes: 7794f486ed0b ("usbfs: Add ioctls for runtime power management") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.com Acked-by: Alan Stern stern@rowland.harvard.edu Link: https://lore.kernel.org/r/20230516202103.558301-1-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/core/devio.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 5e34986fac96f..5cd0a724b425e 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -735,6 +735,7 @@ static int driver_resume(struct usb_interface *intf) return 0; }
+#ifdef CONFIG_PM /* The following routines apply to the entire device, not interfaces */ void usbfs_notify_suspend(struct usb_device *udev) { @@ -753,6 +754,7 @@ void usbfs_notify_resume(struct usb_device *udev) } mutex_unlock(&usbfs_mutex); } +#endif
struct usb_driver usbfs_driver = { .name = "usbfs",
From: John Ogness john.ogness@linutronix.de
[ Upstream commit ca73a892c5bec4b08a2fa22b3015e98ed905abb7 ]
The uarts_ops stop_rx() callback expects that the port->lock is taken and interrupts are disabled.
Fixes: 1fe0e1fa3209 ("serial: 8250_omap: Handle optional overrun-throttle-ms property") Signed-off-by: John Ogness john.ogness@linutronix.de Reviewed-by: Tony Lindgren tony@atomide.com Link: https://lore.kernel.org/r/20230525093159.223817-4-john.ogness@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_omap.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 6fa0e3ca469a0..28e243312286f 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -655,7 +655,9 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id)
up->ier = port->serial_in(port, UART_IER); if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { + spin_lock(&port->lock); port->ops->stop_rx(port); + spin_unlock(&port->lock); } else { /* Keep restarting the timer until * the input overrun subsides.
From: John Ogness john.ogness@linutronix.de
[ Upstream commit 25614735a647693c1260f253dc3ab32127697806 ]
omap8250_irq() accesses UART_IER. This register is modified twice by each console write (serial8250_console_write()) under the port lock. omap8250_irq() must also take the port lock to guanentee synchronized access to UART_IER.
Since the port lock is already being taken for the stop_rx() callback and since it is safe to call cancel_delayed_work() while holding the port lock, simply extend the port lock region to include UART_IER access.
Fixes: 1fe0e1fa3209 ("serial: 8250_omap: Handle optional overrun-throttle-ms property") Signed-off-by: John Ogness john.ogness@linutronix.de Reviewed-by: Tony Lindgren tony@atomide.com Link: https://lore.kernel.org/r/20230525093159.223817-8-john.ogness@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_omap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 28e243312286f..de0447c87846b 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -653,17 +653,18 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) if ((lsr & UART_LSR_OE) && up->overrun_backoff_time_ms > 0) { unsigned long delay;
+ /* Synchronize UART_IER access against the console. */ + spin_lock(&port->lock); up->ier = port->serial_in(port, UART_IER); if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { - spin_lock(&port->lock); port->ops->stop_rx(port); - spin_unlock(&port->lock); } else { /* Keep restarting the timer until * the input overrun subsides. */ cancel_delayed_work(&up->overrun_backoff); } + spin_unlock(&port->lock);
delay = msecs_to_jiffies(up->overrun_backoff_time_ms); schedule_delayed_work(&up->overrun_backoff, delay);
From: Muchun Song songmuchun@bytedance.com
[ Upstream commit 30480b988f88c279752f3202a26b6fee5f586aef ]
The root->ino_idr is supposed to be protected by kernfs_idr_lock, fix it.
Fixes: 488dee96bb62 ("kernfs: allow creating kernfs objects with arbitrary uid/gid") Signed-off-by: Muchun Song songmuchun@bytedance.com Acked-by: Tejun Heo tj@kernel.org Link: https://lore.kernel.org/r/20230523024017.24851-1-songmuchun@bytedance.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/kernfs/dir.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 90677cfbcf9c2..6a1cb2a182b67 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -637,7 +637,9 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, return kn;
err_out3: + spin_lock(&kernfs_idr_lock); idr_remove(&root->ino_idr, (u32)kernfs_ino(kn)); + spin_unlock(&kernfs_idr_lock); err_out2: kmem_cache_free(kernfs_node_cache, kn); err_out1:
From: James Clark james.clark@arm.com
[ Upstream commit c45b2835e7b205783bdfe08cc98fa86a7c5eeb74 ]
child_fwnode should be a read only property based on the DT or ACPI. If it's cleared on the parent device when a child is unloaded, then when the child is loaded again the connection won't be remade.
child_dev should be cleared instead which signifies that the connection should be remade when the child_fwnode registers a new coresight_device.
Similarly the reference count shouldn't be decremented as long as the parent device exists. The correct place to drop the reference is in coresight_release_platform_data() which is already done.
Reproducible on Juno with the following steps:
# load all coresight modules. $ cd /sys/bus/coresight/devices/ $ echo 1 > tmc_etr0/enable_sink $ echo 1 > etm0/enable_source # Works fine ^
$ echo 0 > etm0/enable_source $ rmmod coresight-funnel $ modprobe coresight-funnel $ echo 1 > etm0/enable_source -bash: echo: write error: Invalid argument
Fixes: 37ea1ffddffa ("coresight: Use fwnode handle instead of device names") Fixes: 2af89ebacf29 ("coresight: Clear the connection field properly") Tested-by: Suzuki K Poulose suzuki.poulose@arm.com Reviewed-by: Mike Leach mike.leach@linaro.org Signed-off-by: James Clark james.clark@arm.com Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Link: https://lore.kernel.org/r/20230425143542.2305069-2-james.clark@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwtracing/coresight/coresight-core.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 6471f4232a2e0..3ea6900542223 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -1421,13 +1421,8 @@ static int coresight_remove_match(struct device *dev, void *data) if (csdev->dev.fwnode == conn->child_fwnode) { iterator->orphan = true; coresight_remove_links(iterator, conn); - /* - * Drop the reference to the handle for the remote - * device acquired in parsing the connections from - * platform data. - */ - fwnode_handle_put(conn->child_fwnode); - conn->child_fwnode = NULL; + + conn->child_dev = NULL; /* No need to continue */ break; }
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit 43db1344e0f8c1eb687a1d6cd5b0de3009ab66cb ]
The fuel gauge in the RT5033 PMIC (rt5033-battery) has its own I2C bus and interrupt lines. Therefore, it is not part of the MFD device and needs to be specified separately in the device tree.
Fixes: 0b271258544b ("mfd: rt5033: Add Richtek RT5033 driver core.") Signed-off-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Jakob Hauser jahau@rocketmail.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Lee Jones lee@kernel.org Link: https://lore.kernel.org/r/6a8a19bc67b5be3732882e8131ad2ffcb546ac03.168418296... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/rt5033.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c index f1236a9acf304..df095e91e2666 100644 --- a/drivers/mfd/rt5033.c +++ b/drivers/mfd/rt5033.c @@ -41,9 +41,6 @@ static const struct mfd_cell rt5033_devs[] = { { .name = "rt5033-charger", .of_compatible = "richtek,rt5033-charger", - }, { - .name = "rt5033-battery", - .of_compatible = "richtek,rt5033-battery", }, { .name = "rt5033-led", .of_compatible = "richtek,rt5033-led",
From: Rikard Falkeborn rikard.falkeborn@gmail.com
[ Upstream commit 927e78ac8bc58155316cf6f46026e1912bbbbcfc ]
ALIGN() expects its second argument to be a power of 2, otherwise incorrect results are produced for some inputs. The output can be both larger or smaller than what is expected.
For example, ALIGN(304, 192) equals 320 instead of 384, and ALIGN(65, 192) equals 256 instead of 192.
However, nestling two ALIGN() as is done in this case seem to only produce results equal to or bigger than the expected result if ALIGN() had handled non powers of two, and that in turn results in framesizes that are either the correct size or too large.
Fortunately, since 192 * 4 / 3 equals 256, it turns out that one ALIGN() is sufficient.
Fixes: ab1eda449c6e ("media: venus: vdec: handle 10bit bitstreams") Signed-off-by: Rikard Falkeborn rikard.falkeborn@gmail.com Signed-off-by: Stanimir Varbanov stanimir.k.varbanov@gmail.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/qcom/venus/helpers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 8012f5c7bf344..ff705d513aae4 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -981,8 +981,8 @@ static u32 get_framesize_raw_yuv420_tp10_ubwc(u32 width, u32 height) u32 extradata = SZ_16K; u32 size;
- y_stride = ALIGN(ALIGN(width, 192) * 4 / 3, 256); - uv_stride = ALIGN(ALIGN(width, 192) * 4 / 3, 256); + y_stride = ALIGN(width * 4 / 3, 256); + uv_stride = ALIGN(width * 4 / 3, 256); y_sclines = ALIGN(height, 16); uv_sclines = ALIGN((height + 1) >> 1, 16);
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit 1657f2934daf89e8d9fa4b2697008909eb22c73e ]
Ideally, strlen(cur->string.pointer) and strlen(out) would be the same. But this code is using strscpy() to avoid a potential buffer overflow. So in the same way we should take the strlen() of the smaller string to avoid a buffer overflow in the caller, gmin_get_var_int().
Link: https://lore.kernel.org/r/26124bcd-8132-4483-9d67-225c87d424e8@kili.mountain
Fixes: 387041cda44e ("media: atomisp: improve sensor detection code to use _DSM table") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c index cd0a771454da4..2a8ef766b25a4 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c +++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c @@ -1198,7 +1198,7 @@ static int gmin_get_config_dsm_var(struct device *dev, dev_info(dev, "found _DSM entry for '%s': %s\n", var, cur->string.pointer); strscpy(out, cur->string.pointer, *out_len); - *out_len = strlen(cur->string.pointer); + *out_len = strlen(out);
ACPI_FREE(obj); return 0;
From: Nico Boehr nrb@linux.ibm.com
[ Upstream commit 285cff4c0454340a4dc53f46e67f2cb1c293bd74 ]
The KVM_S390_GET_CMMA_BITS ioctl may return incorrect values when userspace specifies a start_gfn outside of memslots.
This can occur when a VM has multiple memslots with a hole in between:
+-----+----------+--------+--------+ | ... | Slot N-1 | <hole> | Slot N | +-----+----------+--------+--------+ ^ ^ ^ ^ | | | | GFN A A+B | | A+B+C | A+B+C+D
When userspace specifies a GFN in [A+B, A+B+C), it would expect to get the CMMA values of the first dirty page in Slot N. However, userspace may get a start_gfn of A+B+C+D with a count of 0, hence completely skipping over any dirty pages in slot N.
The error is in kvm_s390_next_dirty_cmma(), which assumes gfn_to_memslot_approx() will return the memslot _below_ the specified GFN when the specified GFN lies outside a memslot. In reality it may return either the memslot below or above the specified GFN.
When a memslot above the specified GFN is returned this happens:
- ofs is calculated, but since the memslot's base_gfn is larger than the specified cur_gfn, ofs will underflow to a huge number. - ofs is passed to find_next_bit(). Since ofs will exceed the memslot's number of pages, the number of pages in the memslot is returned, completely skipping over all bits in the memslot userspace would be interested in.
Fix this by resetting ofs to zero when a memslot _above_ cur_gfn is returned (cur_gfn < ms->base_gfn).
Signed-off-by: Nico Boehr nrb@linux.ibm.com Reviewed-by: Claudio Imbrenda imbrenda@linux.ibm.com Fixes: afdad61615cc ("KVM: s390: Fix storage attributes migration with memory slots") Message-Id: 20230324145424.293889-2-nrb@linux.ibm.com Signed-off-by: Claudio Imbrenda imbrenda@linux.ibm.com Signed-off-by: Janosch Frank frankja@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kvm/kvm-s390.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index d7aa442ceaf1c..eb97db59b2365 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -2030,6 +2030,10 @@ static unsigned long kvm_s390_next_dirty_cmma(struct kvm_memslots *slots, ms = slots->memslots + slotidx; ofs = 0; } + + if (cur_gfn < ms->base_gfn) + ofs = 0; + ofs = find_next_bit(kvm_second_dirty_bitmap(ms), ms->npages, ofs); while ((slotidx > 0) && (ofs >= ms->npages)) { slotidx--;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 8fd95da2cfb5046c4bb5a3cdc9eb7963ba8b10dd ]
In the probe, some resources are allocated with dwc3_qcom_of_register_core() or dwc3_qcom_acpi_register_core(). The corresponding resources are already coorectly freed in the error handling path of the probe, but not in the remove function.
Fix it.
Fixes: 2bc02355f8ba ("usb: dwc3: qcom: Add support for booting with ACPI") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Andrew Halaney ahalaney@redhat.com Message-ID: c0215a84cdf18fb3514c81842783ec53cf149deb.1685891059.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/dwc3-qcom.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index c55f939168fce..3a81b95accdf4 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -873,11 +873,15 @@ static int dwc3_qcom_probe(struct platform_device *pdev) static int dwc3_qcom_remove(struct platform_device *pdev) { struct dwc3_qcom *qcom = platform_get_drvdata(pdev); + struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev; int i;
device_remove_software_node(&qcom->dwc3->dev); - of_platform_depopulate(dev); + if (np) + of_platform_depopulate(&pdev->dev); + else + platform_device_put(pdev);
for (i = qcom->num_clocks - 1; i >= 0; i--) { clk_disable_unprepare(qcom->clks[i]);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 4a944da707123686d372ec01ea60056902fadf35 ]
If dwc3_qcom_create_urs_usb_platdev() fails, some resources still need to be released, as already done in the other error handling path of the probe.
Fixes: c25c210f590e ("usb: dwc3: qcom: add URS Host support for sdm845 ACPI boot") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Andrew Halaney ahalaney@redhat.com Message-ID: b69fa8dd68d816e7d24c88d3eda776ceb28c5dc5.1685890571.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/dwc3-qcom.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index 3a81b95accdf4..73c0c381e5d05 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -791,9 +791,10 @@ static int dwc3_qcom_probe(struct platform_device *pdev) if (IS_ERR_OR_NULL(qcom->urs_usb)) { dev_err(dev, "failed to create URS USB platdev\n"); if (!qcom->urs_usb) - return -ENODEV; + ret = -ENODEV; else - return PTR_ERR(qcom->urs_usb); + ret = PTR_ERR(qcom->urs_usb); + goto clk_disable; } } }
From: Prashanth K quic_prashk@quicinc.com
[ Upstream commit edd60d24bd858cef165274e4cd6cab43bdc58d15 ]
Currently if we bootup a device without cable connected, then usb-conn-gpio won't call set_role() since last_role is same as current role. This happens because during probe last_role gets initialised to zero.
To avoid this, added a new constant in enum usb_role, last_role is set to USB_ROLE_UNKNOWN before performing initial detection.
While at it, also handle default case for the usb_role switch in cdns3, intel-xhci-usb-role-switch & musb/jz4740 to avoid build warnings.
Fixes: 4602f3bff266 ("usb: common: add USB GPIO based connection detection driver") Signed-off-by: Prashanth K quic_prashk@quicinc.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Message-ID: 1685544074-17337-1-git-send-email-quic_prashk@quicinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/cdns3/core.c | 2 ++ drivers/usb/common/usb-conn-gpio.c | 3 +++ drivers/usb/musb/jz4740.c | 2 ++ drivers/usb/roles/intel-xhci-usb-role-switch.c | 2 ++ include/linux/usb/role.h | 1 + 5 files changed, 10 insertions(+)
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index dbcdf3b24b477..69d2921f2d3b5 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -252,6 +252,8 @@ static enum usb_role cdns_hw_role_state_machine(struct cdns *cdns) if (!vbus) role = USB_ROLE_NONE; break; + default: + break; }
dev_dbg(cdns->dev, "role %d -> %d\n", cdns->role, role); diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c index 0158148cb0546..25e2910fdb008 100644 --- a/drivers/usb/common/usb-conn-gpio.c +++ b/drivers/usb/common/usb-conn-gpio.c @@ -272,6 +272,9 @@ static int usb_conn_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, info);
+ /* Set last role to unknown before performing the initial detection */ + info->last_role = USB_ROLE_UNKNOWN; + /* Perform initial detection */ usb_conn_queue_dwork(info, 0);
diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index 5b7d576bf6ee8..e3a53b57d3245 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c @@ -91,6 +91,8 @@ static int jz4740_musb_role_switch_set(struct usb_role_switch *sw, case USB_ROLE_HOST: atomic_notifier_call_chain(&phy->notifier, USB_EVENT_ID, phy); break; + default: + break; }
return 0; diff --git a/drivers/usb/roles/intel-xhci-usb-role-switch.c b/drivers/usb/roles/intel-xhci-usb-role-switch.c index 5c96e929acea0..4d6a3dd06e011 100644 --- a/drivers/usb/roles/intel-xhci-usb-role-switch.c +++ b/drivers/usb/roles/intel-xhci-usb-role-switch.c @@ -97,6 +97,8 @@ static int intel_xhci_usb_set_role(struct usb_role_switch *sw, val |= SW_VBUS_VALID; drd_config = DRD_CONFIG_STATIC_DEVICE; break; + default: + break; } val |= SW_IDPIN_EN; if (data->enable_sw_switch) { diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index b5deafd91f67b..65e790a28913e 100644 --- a/include/linux/usb/role.h +++ b/include/linux/usb/role.h @@ -11,6 +11,7 @@ enum usb_role { USB_ROLE_NONE, USB_ROLE_HOST, USB_ROLE_DEVICE, + USB_ROLE_UNKNOWN, };
typedef int (*usb_role_switch_set_t)(struct usb_role_switch *sw,
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 01052b91c9808e3c3b068ae2721cb728ec9aa4c0 ]
If dwc3_meson_g12a_otg_init() fails, resources allocated by the previous of_platform_populate() call should be released, as already done in the error handling path.
Fixes: 1e355f21d3fb ("usb: dwc3: Add Amlogic A1 DWC3 glue") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Message-ID: 9d28466de1808ccc756b4cc25fc72c482d133d13.1686403934.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/dwc3-meson-g12a.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c index bd814df3bf8b8..8f94bc4a82cf2 100644 --- a/drivers/usb/dwc3/dwc3-meson-g12a.c +++ b/drivers/usb/dwc3/dwc3-meson-g12a.c @@ -805,7 +805,7 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
ret = dwc3_meson_g12a_otg_init(pdev, priv); if (ret) - goto err_phys_power; + goto err_plat_depopulate;
pm_runtime_set_active(dev); pm_runtime_enable(dev); @@ -813,6 +813,9 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
return 0;
+err_plat_depopulate: + of_platform_depopulate(dev); + err_phys_power: for (i = 0 ; i < PHY_COUNT ; ++i) phy_power_off(priv->phys[i]);
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit d918e0d5824495a75d00b879118b098fcab36fdb ]
Add the missing check for platform_get_resource and return error if it fails.
Fixes: 4b45efe85263 ("mfd: Add support for Intel Sunrisepoint LPSS devices") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Signed-off-by: Lee Jones lee@kernel.org Link: https://lore.kernel.org/r/20230609014818.28475-1-jiasheng@iscas.ac.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/intel-lpss-acpi.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c index f2ea6540a01e1..4c43d71cddbdc 100644 --- a/drivers/mfd/intel-lpss-acpi.c +++ b/drivers/mfd/intel-lpss-acpi.c @@ -148,6 +148,9 @@ static int intel_lpss_acpi_probe(struct platform_device *pdev) return -ENOMEM;
info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!info->mem) + return -ENODEV; + info->irq = platform_get_irq(pdev, 0);
ret = intel_lpss_probe(&pdev->dev, info);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
[ Upstream commit df49f2a0ac4a34c0cb4b5c233fcfa0add644c43c ]
This reverts commit edd60d24bd858cef165274e4cd6cab43bdc58d15.
Heikki reports that this should not be a global flag just to work around one broken driver and should be fixed differently, so revert it.
Reported-by: Heikki Krogerus heikki.krogerus@linux.intel.com Fixes: edd60d24bd85 ("usb: common: usb-conn-gpio: Set last role to unknown before initial detection") Link: https://lore.kernel.org/r/ZImE4L3YgABnCIsP@kuha.fi.intel.com Cc: Prashanth K quic_prashk@quicinc.com Cc: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/cdns3/core.c | 2 -- drivers/usb/common/usb-conn-gpio.c | 3 --- drivers/usb/musb/jz4740.c | 2 -- drivers/usb/roles/intel-xhci-usb-role-switch.c | 2 -- include/linux/usb/role.h | 1 - 5 files changed, 10 deletions(-)
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 69d2921f2d3b5..dbcdf3b24b477 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -252,8 +252,6 @@ static enum usb_role cdns_hw_role_state_machine(struct cdns *cdns) if (!vbus) role = USB_ROLE_NONE; break; - default: - break; }
dev_dbg(cdns->dev, "role %d -> %d\n", cdns->role, role); diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c index 25e2910fdb008..0158148cb0546 100644 --- a/drivers/usb/common/usb-conn-gpio.c +++ b/drivers/usb/common/usb-conn-gpio.c @@ -272,9 +272,6 @@ static int usb_conn_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, info);
- /* Set last role to unknown before performing the initial detection */ - info->last_role = USB_ROLE_UNKNOWN; - /* Perform initial detection */ usb_conn_queue_dwork(info, 0);
diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index e3a53b57d3245..5b7d576bf6ee8 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c @@ -91,8 +91,6 @@ static int jz4740_musb_role_switch_set(struct usb_role_switch *sw, case USB_ROLE_HOST: atomic_notifier_call_chain(&phy->notifier, USB_EVENT_ID, phy); break; - default: - break; }
return 0; diff --git a/drivers/usb/roles/intel-xhci-usb-role-switch.c b/drivers/usb/roles/intel-xhci-usb-role-switch.c index 4d6a3dd06e011..5c96e929acea0 100644 --- a/drivers/usb/roles/intel-xhci-usb-role-switch.c +++ b/drivers/usb/roles/intel-xhci-usb-role-switch.c @@ -97,8 +97,6 @@ static int intel_xhci_usb_set_role(struct usb_role_switch *sw, val |= SW_VBUS_VALID; drd_config = DRD_CONFIG_STATIC_DEVICE; break; - default: - break; } val |= SW_IDPIN_EN; if (data->enable_sw_switch) { diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index 65e790a28913e..b5deafd91f67b 100644 --- a/include/linux/usb/role.h +++ b/include/linux/usb/role.h @@ -11,7 +11,6 @@ enum usb_role { USB_ROLE_NONE, USB_ROLE_HOST, USB_ROLE_DEVICE, - USB_ROLE_UNKNOWN, };
typedef int (*usb_role_switch_set_t)(struct usb_role_switch *sw,
From: Tony Lindgren tony@atomide.com
[ Upstream commit 20a41a62618df85f3a2981008edec5cadd785e0a ]
We should not rely on autosuspend timeout for system suspend. Instead, let's use force_suspend and force_resume functions. Otherwise the serial port controller device may not be idled on suspend.
As we are doing a register write on suspend to configure the serial port, we still need to runtime PM resume the port on suspend.
While at it, let's switch to pm_runtime_resume_and_get() and check for errors returned. And let's add the missing line break before return to the suspend function while at it.
Fixes: 09d8b2bdbc5c ("serial: 8250: omap: Provide ability to enable/disable UART as wakeup source") Signed-off-by: Tony Lindgren tony@atomide.com Tested-by: Dhruva Gole d-gole@ti.com Message-ID: 20230614045922.4798-1-tony@atomide.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_omap.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index de0447c87846b..a6b374c026a87 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -1521,25 +1521,35 @@ static int omap8250_suspend(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = serial8250_get_port(priv->line); + int err;
serial8250_suspend_port(priv->line);
- pm_runtime_get_sync(dev); + err = pm_runtime_resume_and_get(dev); + if (err) + return err; if (!device_may_wakeup(dev)) priv->wer = 0; serial_out(up, UART_OMAP_WER, priv->wer); - pm_runtime_mark_last_busy(dev); - pm_runtime_put_autosuspend(dev); - + err = pm_runtime_force_suspend(dev); flush_work(&priv->qos_work); - return 0; + + return err; }
static int omap8250_resume(struct device *dev) { struct omap8250_priv *priv = dev_get_drvdata(dev); + int err;
+ err = pm_runtime_force_resume(dev); + if (err) + return err; serial8250_resume_port(priv->line); + /* Paired with pm_runtime_resume_and_get() in omap8250_suspend() */ + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return 0; } #else
From: Mirsad Goran Todorovac mirsad.todorovac@alu.unizg.hr
[ Upstream commit 7dae593cd226a0bca61201cf85ceb9335cf63682 ]
In a couple of situations like
name = kstrndup(buf, count, GFP_KERNEL); if (!name) return -ENOSPC;
the error is not actually "No space left on device", but "Out of memory".
It is semantically correct to return -ENOMEM in all failed kstrndup() and kzalloc() cases in this driver, as it is not a problem with disk space, but with kernel memory allocator failing allocation.
The semantically correct should be:
name = kstrndup(buf, count, GFP_KERNEL); if (!name) return -ENOMEM;
Cc: Dan Carpenter error27@gmail.com Cc: Takashi Iwai tiwai@suse.de Cc: Kees Cook keescook@chromium.org Cc: "Luis R. Rodriguez" mcgrof@ruslug.rutgers.edu Cc: Scott Branden sbranden@broadcom.com Cc: Hans de Goede hdegoede@redhat.com Cc: Brian Norris briannorris@chromium.org Fixes: c92316bf8e948 ("test_firmware: add batched firmware tests") Fixes: 0a8adf584759c ("test: add firmware_class loader test") Fixes: 548193cba2a7d ("test_firmware: add support for firmware_request_platform") Fixes: eb910947c82f9 ("test: firmware_class: add asynchronous request trigger") Fixes: 061132d2b9c95 ("test_firmware: add test custom fallback trigger") Fixes: 7feebfa487b92 ("test_firmware: add support for request_firmware_into_buf") Signed-off-by: Mirsad Goran Todorovac mirsad.todorovac@alu.unizg.hr Reviewed-by: Dan Carpenter dan.carpenter@linaro.org Message-ID: 20230606070808.9300-1-mirsad.todorovac@alu.unizg.hr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/test_firmware.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/lib/test_firmware.c b/lib/test_firmware.c index 2a4078946a3fd..b64f87f4f2284 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c @@ -183,7 +183,7 @@ static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp) { *dst = kstrndup(name, count, gfp); if (!*dst) - return -ENOSPC; + return -ENOMEM; return count; }
@@ -606,7 +606,7 @@ static ssize_t trigger_request_store(struct device *dev,
name = kstrndup(buf, count, GFP_KERNEL); if (!name) - return -ENOSPC; + return -ENOMEM;
pr_info("loading '%s'\n", name);
@@ -654,7 +654,7 @@ static ssize_t trigger_request_platform_store(struct device *dev,
name = kstrndup(buf, count, GFP_KERNEL); if (!name) - return -ENOSPC; + return -ENOMEM;
pr_info("inserting test platform fw '%s'\n", name); efi_embedded_fw.name = name; @@ -707,7 +707,7 @@ static ssize_t trigger_async_request_store(struct device *dev,
name = kstrndup(buf, count, GFP_KERNEL); if (!name) - return -ENOSPC; + return -ENOMEM;
pr_info("loading '%s'\n", name);
@@ -752,7 +752,7 @@ static ssize_t trigger_custom_fallback_store(struct device *dev,
name = kstrndup(buf, count, GFP_KERNEL); if (!name) - return -ENOSPC; + return -ENOMEM;
pr_info("loading '%s' using custom fallback mechanism\n", name);
@@ -803,7 +803,7 @@ static int test_fw_run_batch_request(void *data)
test_buf = kzalloc(TEST_FIRMWARE_BUF_SIZE, GFP_KERNEL); if (!test_buf) - return -ENOSPC; + return -ENOMEM;
if (test_fw_config->partial) req->rc = request_partial_firmware_into_buf
On 21.7.2023. 18:03, Greg Kroah-Hartman wrote:
From: Mirsad Goran Todorovac mirsad.todorovac@alu.unizg.hr
[ Upstream commit 7dae593cd226a0bca61201cf85ceb9335cf63682 ]
In a couple of situations like
name = kstrndup(buf, count, GFP_KERNEL); if (!name) return -ENOSPC;
the error is not actually "No space left on device", but "Out of memory".
It is semantically correct to return -ENOMEM in all failed kstrndup() and kzalloc() cases in this driver, as it is not a problem with disk space, but with kernel memory allocator failing allocation.
The semantically correct should be:
name = kstrndup(buf, count, GFP_KERNEL); if (!name) return -ENOMEM;
Cc: Dan Carpenter error27@gmail.com Cc: Takashi Iwai tiwai@suse.de Cc: Kees Cook keescook@chromium.org Cc: "Luis R. Rodriguez" mcgrof@ruslug.rutgers.edu Cc: Scott Branden sbranden@broadcom.com Cc: Hans de Goede hdegoede@redhat.com Cc: Brian Norris briannorris@chromium.org Fixes: c92316bf8e948 ("test_firmware: add batched firmware tests") Fixes: 0a8adf584759c ("test: add firmware_class loader test") Fixes: 548193cba2a7d ("test_firmware: add support for firmware_request_platform") Fixes: eb910947c82f9 ("test: firmware_class: add asynchronous request trigger") Fixes: 061132d2b9c95 ("test_firmware: add test custom fallback trigger") Fixes: 7feebfa487b92 ("test_firmware: add support for request_firmware_into_buf") Signed-off-by: Mirsad Goran Todorovac mirsad.todorovac@alu.unizg.hr Reviewed-by: Dan Carpenter dan.carpenter@linaro.org Message-ID: 20230606070808.9300-1-mirsad.todorovac@alu.unizg.hr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org
lib/test_firmware.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/lib/test_firmware.c b/lib/test_firmware.c index 2a4078946a3fd..b64f87f4f2284 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c @@ -183,7 +183,7 @@ static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp) { *dst = kstrndup(name, count, gfp); if (!*dst)
return -ENOSPC;
return count; }return -ENOMEM;
@@ -606,7 +606,7 @@ static ssize_t trigger_request_store(struct device *dev, name = kstrndup(buf, count, GFP_KERNEL); if (!name)
return -ENOSPC;
return -ENOMEM;
pr_info("loading '%s'\n", name); @@ -654,7 +654,7 @@ static ssize_t trigger_request_platform_store(struct device *dev, name = kstrndup(buf, count, GFP_KERNEL); if (!name)
return -ENOSPC;
return -ENOMEM;
pr_info("inserting test platform fw '%s'\n", name); efi_embedded_fw.name = name; @@ -707,7 +707,7 @@ static ssize_t trigger_async_request_store(struct device *dev, name = kstrndup(buf, count, GFP_KERNEL); if (!name)
return -ENOSPC;
return -ENOMEM;
pr_info("loading '%s'\n", name); @@ -752,7 +752,7 @@ static ssize_t trigger_custom_fallback_store(struct device *dev, name = kstrndup(buf, count, GFP_KERNEL); if (!name)
return -ENOSPC;
return -ENOMEM;
pr_info("loading '%s' using custom fallback mechanism\n", name); @@ -803,7 +803,7 @@ static int test_fw_run_batch_request(void *data) test_buf = kzalloc(TEST_FIRMWARE_BUF_SIZE, GFP_KERNEL); if (!test_buf)
return -ENOSPC;
return -ENOMEM;
if (test_fw_config->partial) req->rc = request_partial_firmware_into_buf
Just to note: this patch went to 5.10, 5.15 and 6.4, but not to 6.1 LTS.
Is there a particular reason for that, or is it a patchwork glitch?
Thanks, Mirsad
From: Phil Elwell phil@raspberrypi.com
[ Upstream commit 09dd7b993eddb3b48634fd5ddf27aa799785a9ee ]
It is reasonable to declare multiple nvmem blocks. Unless a unique 'id' is passed in for each block there may be name clashes.
Avoid this by using the magic token NVMEM_DEVID_AUTO.
Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem") Signed-off-by: Phil Elwell phil@raspberrypi.com Signed-off-by: Ivan T. Ivanov iivanov@suse.de Reviewed-by: Stefan Wahren stefan.wahren@i2se.com Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Message-ID: 20230611140330.154222-6-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvmem/rmem.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c index 80cb187f14817..752d0bf4445ee 100644 --- a/drivers/nvmem/rmem.c +++ b/drivers/nvmem/rmem.c @@ -71,6 +71,7 @@ static int rmem_probe(struct platform_device *pdev) config.dev = dev; config.priv = priv; config.name = "rmem"; + config.id = NVMEM_DEVID_AUTO; config.size = mem->size; config.reg_read = rmem_read;
From: Amelie Delaunay amelie.delaunay@foss.st.com
[ Upstream commit f592cf624531286f8b52e40dcfc157a5a7fb115c ]
In error path, disable vdd regulator if it exists, but don't overload ret. Because if regulator_disable() is successful, stmfx_chip_init will exit successfully while chip init failed.
Fixes: 06252ade9156 ("mfd: Add ST Multi-Function eXpander (STMFX) core driver") Signed-off-by: Amelie Delaunay amelie.delaunay@foss.st.com Link: https://lore.kernel.org/r/20230609092804.793100-1-amelie.delaunay@foss.st.co... Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/stmfx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c index e095a39301423..6e1629beb8094 100644 --- a/drivers/mfd/stmfx.c +++ b/drivers/mfd/stmfx.c @@ -387,7 +387,7 @@ static int stmfx_chip_init(struct i2c_client *client)
err: if (stmfx->vdd) - return regulator_disable(stmfx->vdd); + regulator_disable(stmfx->vdd);
return ret; }
From: Amelie Delaunay amelie.delaunay@foss.st.com
[ Upstream commit 7c81582c0bccb4757186176f0ee12834597066ad ]
Nullify stmfx->vdd in case devm_regulator_get_optional() returns an error. And simplify code by returning an error only if return code is not -ENODEV, which means there is no vdd regulator and it is not an issue.
Fixes: d75846ed08e6 ("mfd: stmfx: Fix dev_err_probe() call in stmfx_chip_init()") Signed-off-by: Amelie Delaunay amelie.delaunay@foss.st.com Link: https://lore.kernel.org/r/20230609092804.793100-2-amelie.delaunay@foss.st.co... Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/stmfx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c index 6e1629beb8094..9852f49c3f881 100644 --- a/drivers/mfd/stmfx.c +++ b/drivers/mfd/stmfx.c @@ -330,9 +330,8 @@ static int stmfx_chip_init(struct i2c_client *client) stmfx->vdd = devm_regulator_get_optional(&client->dev, "vdd"); ret = PTR_ERR_OR_ZERO(stmfx->vdd); if (ret) { - if (ret == -ENODEV) - stmfx->vdd = NULL; - else + stmfx->vdd = NULL; + if (ret != -ENODEV) return dev_err_probe(&client->dev, ret, "Failed to get VDD regulator\n"); }
From: Pierre Morel pmorel@linux.ibm.com
[ Upstream commit 246be7d2720ea9a795b576067ecc5e5c7a1e7848 ]
bit_and() uses the count of bits as the woking length. Fix the previous implementation and effectively use the right bitmap size.
Fixes: 19fd83a64718 ("KVM: s390: vsie: allow CRYCB FORMAT-1") Fixes: 56019f9aca22 ("KVM: s390: vsie: Allow CRYCB FORMAT-2")
Signed-off-by: Pierre Morel pmorel@linux.ibm.com Reviewed-by: Janosch Frank frankja@linux.ibm.com Link: https://lore.kernel.org/kvm/20230511094719.9691-1-pmorel@linux.ibm.com/ Signed-off-by: Janosch Frank frankja@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kvm/vsie.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index 2c0704f5eb3c6..e07bc0d3df6ff 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c @@ -169,7 +169,8 @@ static int setup_apcb00(struct kvm_vcpu *vcpu, unsigned long *apcb_s, sizeof(struct kvm_s390_apcb0))) return -EFAULT;
- bitmap_and(apcb_s, apcb_s, apcb_h, sizeof(struct kvm_s390_apcb0)); + bitmap_and(apcb_s, apcb_s, apcb_h, + BITS_PER_BYTE * sizeof(struct kvm_s390_apcb0));
return 0; } @@ -191,7 +192,8 @@ static int setup_apcb11(struct kvm_vcpu *vcpu, unsigned long *apcb_s, sizeof(struct kvm_s390_apcb1))) return -EFAULT;
- bitmap_and(apcb_s, apcb_s, apcb_h, sizeof(struct kvm_s390_apcb1)); + bitmap_and(apcb_s, apcb_s, apcb_h, + BITS_PER_BYTE * sizeof(struct kvm_s390_apcb1));
return 0; }
From: Christian Borntraeger borntraeger@linux.ibm.com
[ Upstream commit 0bc380beb78aa352eadbc21d934dd9606fcee808 ]
We do check for target CPU == -1, but this might change at the time we are going to use it. Hold the physical target CPU in a local variable to avoid out-of-bound accesses to the cpu arrays.
Cc: Pierre Morel pmorel@linux.ibm.com Fixes: 87e28a15c42c ("KVM: s390: diag9c (directed yield) forwarding") Reported-by: Marc Hartmayer mhartmay@linux.ibm.com Reviewed-by: Nico Boehr nrb@linux.ibm.com Reviewed-by: Pierre Morel pmorel@linux.ibm.com Signed-off-by: Christian Borntraeger borntraeger@linux.ibm.com Signed-off-by: Janosch Frank frankja@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kvm/diag.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 807fa9da1e721..3c65b8258ae67 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c @@ -166,6 +166,7 @@ static int diag9c_forwarding_overrun(void) static int __diag_time_slice_end_directed(struct kvm_vcpu *vcpu) { struct kvm_vcpu *tcpu; + int tcpu_cpu; int tid;
tid = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4]; @@ -181,14 +182,15 @@ static int __diag_time_slice_end_directed(struct kvm_vcpu *vcpu) goto no_yield;
/* target guest VCPU already running */ - if (READ_ONCE(tcpu->cpu) >= 0) { + tcpu_cpu = READ_ONCE(tcpu->cpu); + if (tcpu_cpu >= 0) { if (!diag9c_forwarding_hz || diag9c_forwarding_overrun()) goto no_yield;
/* target host CPU already running */ - if (!vcpu_is_preempted(tcpu->cpu)) + if (!vcpu_is_preempted(tcpu_cpu)) goto no_yield; - smp_yield_cpu(tcpu->cpu); + smp_yield_cpu(tcpu_cpu); VCPU_EVENT(vcpu, 5, "diag time slice end directed to %d: yield forwarded", tid);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 104d32bd81f620bb9f67fbf7d1159c414e89f05f ]
In stmpe_probe(), if some regulator_enable() calls fail, probing continues and there is only a dev_warn().
So, if stmpe_probe() is called the regulator may not be enabled. It is cleaner to test it before calling regulator_disable() in the remove function.
Fixes: 9c9e321455fb ("mfd: stmpe: add optional regulators") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Linus Walleij linus.walleij@linaro.org Link: https://lore.kernel.org/r/8de3aaf297931d655b9ad6aed548f4de8b85425a.168699857... Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/stmpe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 58d09c615e673..743afbe4e99b7 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -1498,9 +1498,9 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum)
int stmpe_remove(struct stmpe *stmpe) { - if (!IS_ERR(stmpe->vio)) + if (!IS_ERR(stmpe->vio) && regulator_is_enabled(stmpe->vio)) regulator_disable(stmpe->vio); - if (!IS_ERR(stmpe->vcc)) + if (!IS_ERR(stmpe->vcc) && regulator_is_enabled(stmpe->vcc)) regulator_disable(stmpe->vcc);
__stmpe_disable(stmpe, STMPE_BLOCK_ADC);
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 44faada0f38fc333d392af04c343b0e23f8f5d81 ]
devm_kzalloc() returns a pointer to dynamically allocated memory. Pointer could be NULL in case allocation fails. Check pointer validity. Identified with coccinelle (kmerr.cocci script).
Fixes: f67213cee2b3 ("phy: tegra: xusb: Add usb-role-switch support") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Acked-by: Thierry Reding treding@nvidia.com Link: https://lore.kernel.org/r/20230531073950.145339-1-claudiu.beznea@microchip.c... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/tegra/xusb.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index bdcf217bf3f88..119e2c039225f 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -669,6 +669,9 @@ static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port) port->dev.driver = devm_kzalloc(&port->dev, sizeof(struct device_driver), GFP_KERNEL); + if (!port->dev.driver) + return -ENOMEM; + port->dev.driver->owner = THIS_MODULE;
port->usb_role_sw = usb_role_switch_register(&port->dev,
From: Fancy Fang chen.fang@nxp.com
[ Upstream commit 661dfb7f46298e53f6c3deaa772fa527aae86193 ]
During suspend, all the tpm registers will lose values. So the 'real_period' value of struct 'imx_tpm_pwm_chip' should be forced to be zero to force the period update code can be executed after system resume back.
Signed-off-by: Fancy Fang chen.fang@nxp.com Signed-off-by: Clark Wang xiaoning.wang@nxp.com Acked-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Fixes: 738a1cfec2ed ("pwm: Add i.MX TPM PWM driver support") Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-imx-tpm.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/pwm/pwm-imx-tpm.c b/drivers/pwm/pwm-imx-tpm.c index e5e7b7c339a8f..7a53bf51964f2 100644 --- a/drivers/pwm/pwm-imx-tpm.c +++ b/drivers/pwm/pwm-imx-tpm.c @@ -397,6 +397,13 @@ static int __maybe_unused pwm_imx_tpm_suspend(struct device *dev) if (tpm->enable_count > 0) return -EBUSY;
+ /* + * Force 'real_period' to be zero to force period update code + * can be executed after system resume back, since suspend causes + * the period related registers to become their reset values. + */ + tpm->real_period = 0; + clk_disable_unprepare(tpm->clk);
return 0;
From: Marek Vasut marex@denx.de
[ Upstream commit 38ba83598633373f47951384cfc389181c8d1bed ]
If the PWM is exported but not enabled, do not call pwm_class_apply_state(). First of all, in this case, period may still be unconfigured and this would make pwm_class_apply_state() return -EINVAL, and then suspend would fail. Second, it makes little sense to apply state onto PWM that is not enabled before suspend.
Failing case: " $ echo 1 > /sys/class/pwm/pwmchip4/export $ echo mem > /sys/power/state ... pwm pwmchip4: PM: dpm_run_callback(): pwm_class_suspend+0x1/0xa8 returns -22 pwm pwmchip4: PM: failed to suspend: error -22 PM: Some devices failed to suspend, or early wake event detected "
Working case: " $ echo 1 > /sys/class/pwm/pwmchip4/export $ echo 100 > /sys/class/pwm/pwmchip4/pwm1/period $ echo 10 > /sys/class/pwm/pwmchip4/pwm1/duty_cycle $ echo mem > /sys/power/state ... "
Do not call pwm_class_apply_state() in case the PWM is disabled to fix this issue.
Fixes: 7fd4edc57bbae ("pwm: sysfs: Add suspend/resume support") Signed-off-by: Marek Vasut marex@denx.de Fixes: ef2bf4997f7d ("pwm: Improve args checking in pwm_apply_state()") Reviewed-by: Brian Norris briannorris@chromium.org Reviewed-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/sysfs.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c index 9903c3a7ecedc..b8417a8d2ef97 100644 --- a/drivers/pwm/sysfs.c +++ b/drivers/pwm/sysfs.c @@ -424,6 +424,13 @@ static int pwm_class_resume_npwm(struct device *parent, unsigned int npwm) if (!export) continue;
+ /* If pwmchip was not enabled before suspend, do nothing. */ + if (!export->suspend.enabled) { + /* release lock taken in pwm_class_get_state */ + mutex_unlock(&export->lock); + continue; + } + state.enabled = export->suspend.enabled; ret = pwm_class_apply_state(export, pwm, &state); if (ret < 0) @@ -448,7 +455,17 @@ static int __maybe_unused pwm_class_suspend(struct device *parent) if (!export) continue;
+ /* + * If pwmchip was not enabled before suspend, save + * state for resume time and do nothing else. + */ export->suspend = state; + if (!state.enabled) { + /* release lock taken in pwm_class_get_state */ + mutex_unlock(&export->lock); + continue; + } + state.enabled = false; ret = pwm_class_apply_state(export, pwm, &state); if (ret < 0) {
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit cdcffafc4d845cc0c6392cba168c7a942734cce7 ]
This code accidentally return positive EINVAL instead of negative -EINVAL.
Fixes: eb41f334589d ("pwm: ab8500: Fix register offset calculation to not depend on probe order") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Reviewed-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-ab8500.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pwm/pwm-ab8500.c b/drivers/pwm/pwm-ab8500.c index ad37bc46f2721..5fa91f4cda7ac 100644 --- a/drivers/pwm/pwm-ab8500.c +++ b/drivers/pwm/pwm-ab8500.c @@ -96,7 +96,7 @@ static int ab8500_pwm_probe(struct platform_device *pdev) int err;
if (pdev->id < 1 || pdev->id > 31) - return dev_err_probe(&pdev->dev, EINVAL, "Invalid device id %d\n", pdev->id); + return dev_err_probe(&pdev->dev, -EINVAL, "Invalid device id %d\n", pdev->id);
/* * Nothing to be done in probe, this is required to get the
From: Shuijing Li shuijing.li@mediatek.com
[ Upstream commit bc13d60e4e1e945b34769a4a4c2b172e8552abe5 ]
There is a flow error in the original mtk_disp_pwm_apply() function. If this function is called when the clock is disabled, there will be a chance to operate the disp_pwm register, resulting in disp_pwm exception. Fix this accordingly.
Fixes: 888a623db5d0 ("pwm: mtk-disp: Implement atomic API .apply()") Signed-off-by: Shuijing Li shuijing.li@mediatek.com Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Tested-by: Fei Shao fshao@chromium.org Acked-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Reviewed-by: Alexandre Mergnat amergnat@baylibre.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-mtk-disp.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index 92ba02cfec92f..a581d8adab59c 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c @@ -79,14 +79,11 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (state->polarity != PWM_POLARITY_NORMAL) return -EINVAL;
- if (!state->enabled) { - mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask, - 0x0); - - if (mdp->enabled) { - clk_disable_unprepare(mdp->clk_mm); - clk_disable_unprepare(mdp->clk_main); - } + if (!state->enabled && mdp->enabled) { + mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, + mdp->data->enable_mask, 0x0); + clk_disable_unprepare(mdp->clk_mm); + clk_disable_unprepare(mdp->clk_main);
mdp->enabled = false; return 0;
From: Li Nan linan122@huawei.com
[ Upstream commit 125bfc7cd750e68c99f1d446e2c22abea08c237f ]
/sys/block/[device]/queue/iostats is used to control whether to count io stat. Write 0 to it will clear queue_flags QUEUE_FLAG_IO_STAT which means iostats is disabled. If we disable iostats and later endable it, the io issued during this period will be counted incorrectly, inflight will be decreased to -1.
//T1 set iostats echo 0 > /sys/block/md0/queue/iostats clear QUEUE_FLAG_IO_STAT
//T2 issue io if (QUEUE_FLAG_IO_STAT) -> false bio_start_io_acct inflight++
echo 1 > /sys/block/md0/queue/iostats set QUEUE_FLAG_IO_STAT
//T3 io end if (QUEUE_FLAG_IO_STAT) -> true bio_end_io_acct inflight-- -> -1
Also, if iostats is enabled while issuing io but disabled while io end, inflight will never be decreased.
Fix it by checking start_time when io end. If start_time is not 0, call bio_end_io_acct().
Fixes: 528bc2cf2fcc ("md/raid10: enable io accounting") Signed-off-by: Li Nan linan122@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230609094320.2397604-1-linan666@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/raid10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 99607d51d128d..edd3b65c447db 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -297,7 +297,7 @@ static void raid_end_bio_io(struct r10bio *r10_bio) if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) bio->bi_status = BLK_STS_IOERR;
- if (blk_queue_io_stat(bio->bi_bdev->bd_disk->queue)) + if (r10_bio->start_time) bio_end_io_acct(bio, r10_bio->start_time); bio_endio(bio); /*
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 06c6e1b01d9261f03629cefd1f3553503291e6cf ]
If an error occurs after clk_get(), the corresponding resources should be released.
Use devm_clk_get() to fix it.
Fixes: b5b2bdfc2893 ("rtc: st: Add new driver for ST's LPC RTC") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/866af6adbc7454a7b4505eb6c28fbdc86ccff39e.168625145... Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-st-lpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c index 0f8e4231098ef..d04d46f9cc65a 100644 --- a/drivers/rtc/rtc-st-lpc.c +++ b/drivers/rtc/rtc-st-lpc.c @@ -228,7 +228,7 @@ static int st_rtc_probe(struct platform_device *pdev) enable_irq_wake(rtc->irq); disable_irq(rtc->irq);
- rtc->clk = clk_get(&pdev->dev, NULL); + rtc->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(rtc->clk)) { dev_err(&pdev->dev, "Unable to request clock\n"); return PTR_ERR(rtc->clk);
From: Jouni Högander jouni.hogander@intel.com
[ Upstream commit 5311892a0ad1d301aafd53ca0154091b3eb407ea ]
Encoder compute config is changing hw.adjusted mode. Uapi.adjusted mode doesn't get updated before psr compute config gets called. This causes io and fast wake line calculation using adjusted mode containing values before encoder adjustments. Fix this by using hw.adjusted mode instead of uapi.adjusted mode.
Cc: Stanislav Lisovskiy stanislav.lisovskiy@intel.com
Signed-off-by: Jouni Högander jouni.hogander@intel.com Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8475 Fixes: cb42e8ede5b4 ("drm/i915/psr: Use calculated io and fast wake lines") Reviewed-by: Mika Kahola mika.kahola@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230620111745.2870706-1-jouni... (cherry picked from commit ef0af9db2a21257885116949f471fe5565b2f0ab) Signed-off-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/display/intel_psr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index cf1e92486cbc9..93d2fd4cd16b7 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -862,9 +862,9 @@ static bool _compute_psr2_wake_times(struct intel_dp *intel_dp, }
io_wake_lines = intel_usecs_to_scanlines( - &crtc_state->uapi.adjusted_mode, io_wake_time); + &crtc_state->hw.adjusted_mode, io_wake_time); fast_wake_lines = intel_usecs_to_scanlines( - &crtc_state->uapi.adjusted_mode, fast_wake_time); + &crtc_state->hw.adjusted_mode, fast_wake_time);
if (io_wake_lines > max_wake_lines || fast_wake_lines > max_wake_lines)
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 29f96ac23648b2259f42d40703c47dd18fd172ca ]
Selecting only REGMAP_I2C can leave REGMAP unset, causing build errors, so also select REGMAP to prevent the build errors.
../drivers/media/cec/i2c/ch7322.c:158:21: error: variable 'ch7322_regmap' has initializer but incomplete type 158 | static const struct regmap_config ch7322_regmap = { ../drivers/media/cec/i2c/ch7322.c:159:10: error: 'const struct regmap_config' has no member named 'reg_bits' 159 | .reg_bits = 8, ../drivers/media/cec/i2c/ch7322.c:159:21: warning: excess elements in struct initializer 159 | .reg_bits = 8, ../drivers/media/cec/i2c/ch7322.c:160:10: error: 'const struct regmap_config' has no member named 'val_bits' 160 | .val_bits = 8, ../drivers/media/cec/i2c/ch7322.c:160:21: warning: excess elements in struct initializer 160 | .val_bits = 8, ../drivers/media/cec/i2c/ch7322.c:161:10: error: 'const struct regmap_config' has no member named 'max_register' 161 | .max_register = 0x7f, ../drivers/media/cec/i2c/ch7322.c:161:25: warning: excess elements in struct initializer 161 | .max_register = 0x7f, ../drivers/media/cec/i2c/ch7322.c:162:10: error: 'const struct regmap_config' has no member named 'disable_locking' 162 | .disable_locking = true, ../drivers/media/cec/i2c/ch7322.c:162:28: warning: excess elements in struct initializer 162 | .disable_locking = true, ../drivers/media/cec/i2c/ch7322.c: In function 'ch7322_probe': ../drivers/media/cec/i2c/ch7322.c:468:26: error: implicit declaration of function 'devm_regmap_init_i2c' [-Werror=implicit-function-declaration] 468 | ch7322->regmap = devm_regmap_init_i2c(client, &ch7322_regmap); ../drivers/media/cec/i2c/ch7322.c:468:24: warning: assignment to 'struct regmap *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 468 | ch7322->regmap = devm_regmap_init_i2c(client, &ch7322_regmap); ../drivers/media/cec/i2c/ch7322.c: At top level: ../drivers/media/cec/i2c/ch7322.c:158:35: error: storage size of 'ch7322_regmap' isn't known 158 | static const struct regmap_config ch7322_regmap = {
Link: https://lore.kernel.org/linux-media/20230608025435.29249-1-rdunlap@infradead... Fixes: 21b9a47e0ec7 ("media: cec: i2c: ch7322: Add ch7322 CEC controller driver") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Jeff Chase jnchase@google.com Cc: Hans Verkuil hverkuil-cisco@xs4all.nl Cc: Joe Tessler jrt@google.com Cc: Arnd Bergmann arnd@arndb.de Cc: Mark Brown broonie@kernel.org Cc: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/cec/i2c/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/media/cec/i2c/Kconfig b/drivers/media/cec/i2c/Kconfig index 70432a1d69186..d912d143fb312 100644 --- a/drivers/media/cec/i2c/Kconfig +++ b/drivers/media/cec/i2c/Kconfig @@ -5,6 +5,7 @@ config CEC_CH7322 tristate "Chrontel CH7322 CEC controller" depends on I2C + select REGMAP select REGMAP_I2C select CEC_CORE help
From: Chengfeng Ye dg573847474@gmail.com
[ Upstream commit 6feb37b3b06e9049e20dcf7e23998f92c9c5be9a ]
As &net->sctp.addr_wq_lock is also acquired by the timer sctp_addr_wq_timeout_handler() in protocal.c, the same lock acquisition at sctp_auto_asconf_init() seems should disable irq since it is called from sctp_accept() under process context.
Possible deadlock scenario: sctp_accept() -> sctp_sock_migrate() -> sctp_auto_asconf_init() -> spin_lock(&net->sctp.addr_wq_lock) <timer interrupt> -> sctp_addr_wq_timeout_handler() -> spin_lock_bh(&net->sctp.addr_wq_lock); (deadlock here)
This flaw was found using an experimental static analysis tool we are developing for irq-related deadlock.
The tentative patch fix the potential deadlock by spin_lock_bh().
Signed-off-by: Chengfeng Ye dg573847474@gmail.com Fixes: 34e5b0118685 ("sctp: delay auto_asconf init until binding the first addr") Acked-by: Xin Long lucien.xin@gmail.com Link: https://lore.kernel.org/r/20230627120340.19432-1-dg573847474@gmail.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sctp/socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ed35d4a4c5253..f10ad80fd6948 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -362,9 +362,9 @@ static void sctp_auto_asconf_init(struct sctp_sock *sp) struct net *net = sock_net(&sp->inet.sk);
if (net->sctp.default_auto_asconf) { - spin_lock(&net->sctp.addr_wq_lock); + spin_lock_bh(&net->sctp.addr_wq_lock); list_add_tail(&sp->auto_asconf_list, &net->sctp.auto_asconf_splist); - spin_unlock(&net->sctp.addr_wq_lock); + spin_unlock_bh(&net->sctp.addr_wq_lock); sp->do_auto_asconf = 1; } }
From: Florian Westphal fw@strlen.de
[ Upstream commit b4ee93380b3c891fea996af8d1d3ca0e36ad31f0 ]
Looks like "tc" hard-codes "mangle" as the only supported table name, but on kernel side there are no checks.
This is wrong. Not all xtables targets are safe to call from tc. E.g. "nat" targets assume skb has a conntrack object assigned to it. Normally those get called from netfilter nat core which consults the nat table to obtain the address mapping.
"tc" userspace either sets PRE or POSTROUTING as hook number, but there is no validation of this on kernel side, so update netlink policy to reject bogus numbers. Some targets may assume skb_dst is set for input/forward hooks, so prevent those from being used.
act_ipt uses the hook number in two places: 1. the state hook number, this is fine as-is 2. to set par.hook_mask
The latter is a bit mask, so update the assignment to make xt_check_target() to the right thing.
Followup patch adds required checks for the skb/packet headers before calling the targets evaluation function.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Florian Westphal fw@strlen.de Reviewed-by: Simon Horman simon.horman@corigine.com Acked-by: Jamal Hadi Salim jhs@mojatatu.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/act_ipt.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 2f3d507c24a1f..ebd403f571ea5 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -50,7 +50,7 @@ static int ipt_init_target(struct net *net, struct xt_entry_target *t, par.entryinfo = &e; par.target = target; par.targinfo = t->data; - par.hook_mask = hook; + par.hook_mask = 1 << hook; par.family = NFPROTO_IPV4;
ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false); @@ -87,7 +87,8 @@ static void tcf_ipt_release(struct tc_action *a)
static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = { [TCA_IPT_TABLE] = { .type = NLA_STRING, .len = IFNAMSIZ }, - [TCA_IPT_HOOK] = { .type = NLA_U32 }, + [TCA_IPT_HOOK] = NLA_POLICY_RANGE(NLA_U32, NF_INET_PRE_ROUTING, + NF_INET_NUMHOOKS), [TCA_IPT_INDEX] = { .type = NLA_U32 }, [TCA_IPT_TARG] = { .len = sizeof(struct xt_entry_target) }, }; @@ -160,15 +161,27 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla, return -EEXIST; } } + + err = -EINVAL; hook = nla_get_u32(tb[TCA_IPT_HOOK]); + switch (hook) { + case NF_INET_PRE_ROUTING: + break; + case NF_INET_POST_ROUTING: + break; + default: + goto err1; + } + + if (tb[TCA_IPT_TABLE]) { + /* mangle only for now */ + if (nla_strcmp(tb[TCA_IPT_TABLE], "mangle")) + goto err1; + }
- err = -ENOMEM; - tname = kmalloc(IFNAMSIZ, GFP_KERNEL); + tname = kstrdup("mangle", GFP_KERNEL); if (unlikely(!tname)) goto err1; - if (tb[TCA_IPT_TABLE] == NULL || - nla_strscpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ) - strcpy(tname, "mangle");
t = kmemdup(td, td->u.target_size, GFP_KERNEL); if (unlikely(!t))
From: Tobias Heider me@tobhe.de
[ Upstream commit 046f753da6143ee16452966915087ec8b0de3c70 ]
Fixes a bug where on the M1 mac mini initramfs-tools fails to include the necessary firmware into the initrd.
Fixes: c4dab50697ff ("tg3: Download 57766 EEE service patch firmware") Signed-off-by: Tobias Heider me@tobhe.de Reviewed-by: Michael Chan michael.chan@broadcom.com Link: https://lore.kernel.org/r/ZJt7LKzjdz8+dClx@tobhe.de Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/broadcom/tg3.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 50f86bebbc19d..70b1a855273e4 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -224,6 +224,7 @@ MODULE_AUTHOR("David S. Miller (davem@redhat.com) and Jeff Garzik (jgarzik@pobox MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver"); MODULE_LICENSE("GPL"); MODULE_FIRMWARE(FIRMWARE_TG3); +MODULE_FIRMWARE(FIRMWARE_TG357766); MODULE_FIRMWARE(FIRMWARE_TG3TSO); MODULE_FIRMWARE(FIRMWARE_TG3TSO5);
From: Nick Child nnac123@linux.ibm.com
[ Upstream commit 48538ccb825b05544ec308a509e2cc9c013402db ]
All ibmvnic resets, make a call to netdev_tx_reset_queue() when re-opening the device. netdev_tx_reset_queue() resets the num_queued and num_completed byte counters. These stats are used in Byte Queue Limit (BQL) algorithms. The difference between these two stats tracks the number of bytes currently sitting on the physical NIC. ibmvnic increases the number of queued bytes though calls to netdev_tx_sent_queue() in the drivers xmit function. When, VIOS reports that it is done transmitting bytes, the ibmvnic device increases the number of completed bytes through calls to netdev_tx_completed_queue(). It is important to note that the driver batches its transmit calls and num_queued is increased every time that an skb is added to the next batch, not necessarily when the batch is sent to VIOS for transmission.
Unlike other reset types, a NON FATAL reset will not flush the sub crq tx buffers. Therefore, it is possible for the batched skb array to be partially full. So if there is call to netdev_tx_reset_queue() when re-opening the device, the value of num_queued (0) would not account for the skb's that are currently batched. Eventually, when the batch is sent to VIOS, the call to netdev_tx_completed_queue() would increase num_completed to a value greater than the num_queued. This causes a BUG_ON crash:
ibmvnic 30000002: Firmware reports error, cause: adapter problem. Starting recovery... ibmvnic 30000002: tx error 600 ibmvnic 30000002: tx error 600 ibmvnic 30000002: tx error 600 ibmvnic 30000002: tx error 600 ------------[ cut here ]------------ kernel BUG at lib/dynamic_queue_limits.c:27! Oops: Exception in kernel mode, sig: 5 [....] NIP dql_completed+0x28/0x1c0 LR ibmvnic_complete_tx.isra.0+0x23c/0x420 [ibmvnic] Call Trace: ibmvnic_complete_tx.isra.0+0x3f8/0x420 [ibmvnic] (unreliable) ibmvnic_interrupt_tx+0x40/0x70 [ibmvnic] __handle_irq_event_percpu+0x98/0x270 ---[ end trace ]---
Therefore, do not reset the dql stats when performing a NON_FATAL reset.
Fixes: 0d973388185d ("ibmvnic: Introduce xmit_more support using batched subCRQ hcalls") Signed-off-by: Nick Child nnac123@linux.ibm.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/ibm/ibmvnic.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 8a92c6a6e764f..765dee2e4882e 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1240,7 +1240,14 @@ static int __ibmvnic_open(struct net_device *netdev) if (prev_state == VNIC_CLOSED) enable_irq(adapter->tx_scrq[i]->irq); enable_scrq_irq(adapter, adapter->tx_scrq[i]); - netdev_tx_reset_queue(netdev_get_tx_queue(netdev, i)); + /* netdev_tx_reset_queue will reset dql stats. During NON_FATAL + * resets, don't reset the stats because there could be batched + * skb's waiting to be sent. If we reset dql stats, we risk + * num_completed being greater than num_queued. This will cause + * a BUG_ON in dql_completed(). + */ + if (adapter->reset_reason != VNIC_RESET_NON_FATAL) + netdev_tx_reset_queue(netdev_get_tx_queue(netdev, i)); }
rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);
From: Pawel Dembicki paweldembicki@gmail.com
[ Upstream commit 3cf62c8177adb0db9e15c8b898c44f997acf3ebf ]
Switch in MAXLEN register stores the maximum size of a data frame. The MTU size is 18 bytes smaller than the frame size.
The current settings are causing problems with packet forwarding. This patch fixes the MTU settings to proper values.
Fixes: fb77ffc6ec86 ("net: dsa: vsc73xx: make the MTU configurable") Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Pawel Dembicki paweldembicki@gmail.com Reviewed-by: Vladimir Oltean olteanv@gmail.com Link: https://lore.kernel.org/r/20230628194327.1765644-1-paweldembicki@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/vitesse-vsc73xx-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c index a4b1447ff0557..0c0bc78b1788e 100644 --- a/drivers/net/dsa/vitesse-vsc73xx-core.c +++ b/drivers/net/dsa/vitesse-vsc73xx-core.c @@ -1025,17 +1025,17 @@ static int vsc73xx_change_mtu(struct dsa_switch *ds, int port, int new_mtu) struct vsc73xx *vsc = ds->priv;
return vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, - VSC73XX_MAXLEN, new_mtu); + VSC73XX_MAXLEN, new_mtu + ETH_HLEN + ETH_FCS_LEN); }
/* According to application not "VSC7398 Jumbo Frames" setting - * up the MTU to 9.6 KB does not affect the performance on standard + * up the frame size to 9.6 KB does not affect the performance on standard * frames. It is clear from the application note that * "9.6 kilobytes" == 9600 bytes. */ static int vsc73xx_get_max_mtu(struct dsa_switch *ds, int port) { - return 9600; + return 9600 - ETH_HLEN - ETH_FCS_LEN; }
static const struct dsa_switch_ops vsc73xx_ds_ops = {
From: Jonas Gorski jonas.gorski@gmail.com
[ Upstream commit 7c1f23ad34fcdace50275a6aa1e1969b41c6233f ]
If neither a "hif_mspi" nor "mspi" resource is present, the driver will just early exit in probe but still return success. Apart from not doing anything meaningful, this would then also lead to a null pointer access on removal, as platform_get_drvdata() would return NULL, which it would then try to dereference when trying to unregister the spi master.
Fix this by unconditionally calling devm_ioremap_resource(), as it can handle a NULL res and will then return a viable ERR_PTR() if we get one.
The "return 0;" was previously a "goto qspi_resource_err;" where then ret was returned, but since ret was still initialized to 0 at this place this was a valid conversion in 63c5395bb7a9 ("spi: bcm-qspi: Fix use-after-free on unbind"). The issue was not introduced by this commit, only made more obvious.
Fixes: fa236a7ef240 ("spi: bcm-qspi: Add Broadcom MSPI driver") Signed-off-by: Jonas Gorski jonas.gorski@gmail.com Reviewed-by: Kamal Dasu kamal.dasu@broadcom.com Link: https://lore.kernel.org/r/20230629134306.95823-1-jonas.gorski@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-bcm-qspi.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index bd7c7fc739610..c79797c06cda1 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -1370,13 +1370,9 @@ int bcm_qspi_probe(struct platform_device *pdev, res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mspi");
- if (res) { - qspi->base[MSPI] = devm_ioremap_resource(dev, res); - if (IS_ERR(qspi->base[MSPI])) - return PTR_ERR(qspi->base[MSPI]); - } else { - return 0; - } + qspi->base[MSPI] = devm_ioremap_resource(dev, res); + if (IS_ERR(qspi->base[MSPI])) + return PTR_ERR(qspi->base[MSPI]);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi"); if (res) {
From: Nishanth Menon nm@ti.com
[ Upstream commit 1b712f18c461bd75f018033a15cf381e712806b5 ]
Sec proxy/message manager data buffer is 60 bytes with the last of the registers indicating transmission completion. This however poses a bit of a challenge.
The backing memory for sec_proxy / message manager is regular memory, and all sec proxy does is to trigger a burst of all 60 bytes of data over to the target thread backing ring accelerator. It doesn't do a memory scrub when it moves data out in the burst. When we transmit multiple messages, remnants of previous message is also transmitted which results in some random data being set in TISCI fields of messages that have been expanded forward.
The entire concept of backward compatibility hinges on the fact that the unused message fields remain 0x0 allowing for 0x0 value to be specially considered when backward compatibility of message extension is done.
So, instead of just writing the completion register, we continue to fill the message buffer up with 0x0 (note: for partial message involving completion, we already do this).
This allows us to scale and introduce ABI changes back also work with other boot stages that may have left data in the internal memory.
While at this, be consistent and explicit with the data_reg pointer increment.
Fixes: aace66b170ce ("mailbox: Introduce TI message manager driver") Signed-off-by: Nishanth Menon nm@ti.com Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/ti-msgmgr.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/mailbox/ti-msgmgr.c b/drivers/mailbox/ti-msgmgr.c index efb43b0385960..fa71ae837d235 100644 --- a/drivers/mailbox/ti-msgmgr.c +++ b/drivers/mailbox/ti-msgmgr.c @@ -385,14 +385,20 @@ static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data) /* Ensure all unused data is 0 */ data_trail &= 0xFFFFFFFF >> (8 * (sizeof(u32) - trail_bytes)); writel(data_trail, data_reg); - data_reg++; + data_reg += sizeof(u32); } + /* * 'data_reg' indicates next register to write. If we did not already * write on tx complete reg(last reg), we must do so for transmit + * In addition, we also need to make sure all intermediate data + * registers(if any required), are reset to 0 for TISCI backward + * compatibility to be maintained. */ - if (data_reg <= qinst->queue_buff_end) - writel(0, qinst->queue_buff_end); + while (data_reg <= qinst->queue_buff_end) { + writel(0, data_reg); + data_reg += sizeof(u32); + }
return 0; }
From: Chao Yu chao@kernel.org
[ Upstream commit 0135c482fa97e2fd8245cb462784112a00ed1211 ]
If truncate_node() fails in truncate_dnode(), it missed to call f2fs_put_page(), fix it.
Fixes: 7735730d39d7 ("f2fs: fix to propagate error from __get_meta_page()") Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/node.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 89a7f6021c369..195658263f0a4 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -942,8 +942,10 @@ static int truncate_dnode(struct dnode_of_data *dn) dn->ofs_in_node = 0; f2fs_truncate_data_blocks(dn); err = truncate_node(dn); - if (err) + if (err) { + f2fs_put_page(page, 1); return err; + }
return 1; }
From: Hariprasad Kelam hkelam@marvell.com
[ Upstream commit 2e7bc57b976bb016c6569a54d95c1b8d88f9450a ]
Firmware configures NIX block mapping for all MAC blocks. The current implementation reads the configuration and creates the mapping between RVU PF and NIX blocks. But this configuration is only valid for silicons that support multiple blocks. For all other silicons, all MAC blocks map to NIX0.
This patch corrects the mapping by adding a check for the same.
Fixes: c5a73b632b90 ("octeontx2-af: Map NIX block from CGX connection") Signed-off-by: Hariprasad Kelam hkelam@marvell.com Signed-off-by: Sunil Goutham sgoutham@marvell.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 11 +++++++++++ drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h index fed49d6a178d0..9d517e6dac2f0 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -23,6 +23,7 @@ #define PCI_DEVID_OCTEONTX2_LBK 0xA061
/* Subsystem Device ID */ +#define PCI_SUBSYS_DEVID_98XX 0xB100 #define PCI_SUBSYS_DEVID_96XX 0xB200 #define PCI_SUBSYS_DEVID_CN10K_A 0xB900
@@ -614,6 +615,16 @@ static inline u16 rvu_nix_chan_cpt(struct rvu *rvu, u8 chan) return rvu->hw->cpt_chan_base + chan; }
+static inline bool is_rvu_supports_nix1(struct rvu *rvu) +{ + struct pci_dev *pdev = rvu->pdev; + + if (pdev->subsystem_device == PCI_SUBSYS_DEVID_98XX) + return true; + + return false; +} + /* Function Prototypes * RVU */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c index 28ff67819566c..5ca4ab5770542 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c @@ -111,7 +111,7 @@ static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf, p2x = cgx_lmac_get_p2x(cgx_id, lmac_id); /* Firmware sets P2X_SELECT as either NIX0 or NIX1 */ pfvf->nix_blkaddr = BLKADDR_NIX0; - if (p2x == CMR_P2X_SEL_NIX1) + if (is_rvu_supports_nix1(rvu) && p2x == CMR_P2X_SEL_NIX1) pfvf->nix_blkaddr = BLKADDR_NIX1; }
From: Hariprasad Kelam hkelam@marvell.com
[ Upstream commit 79ebb53772c95d3a6ae51b3c65f9985fdd430df6 ]
with the addition of new MAC blocks like CN10K RPM and CN10KB RPM_USX, LMACs are noncontiguous and CGX blocks are also noncontiguous. But during RVU driver initialization, the driver is assuming they are contiguous and trying to access cgx or lmac with their id which is resulting in kernel panic.
This patch fixes the issue by adding proper checks.
[ 23.219150] pc : cgx_lmac_read+0x38/0x70 [ 23.219154] lr : rvu_program_channels+0x3f0/0x498 [ 23.223852] sp : ffff000100d6fc80 [ 23.227158] x29: ffff000100d6fc80 x28: ffff00010009f880 x27: 000000000000005a [ 23.234288] x26: ffff000102586768 x25: 0000000000002500 x24: fffffffffff0f000
Fixes: 91c6945ea1f9 ("octeontx2-af: cn10k: Add RPM MAC support") Signed-off-by: Hariprasad Kelam hkelam@marvell.com Signed-off-by: Sunil Goutham sgoutham@marvell.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c index fd0a31bf94fea..8ac95cb7bbb74 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c @@ -167,6 +167,9 @@ void cgx_lmac_write(int cgx_id, int lmac_id, u64 offset, u64 val) { struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+ /* Software must not access disabled LMAC registers */ + if (!is_lmac_valid(cgx_dev, lmac_id)) + return; cgx_write(cgx_dev, lmac_id, offset, val); }
@@ -174,6 +177,10 @@ u64 cgx_lmac_read(int cgx_id, int lmac_id, u64 offset) { struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+ /* Software must not access disabled LMAC registers */ + if (!is_lmac_valid(cgx_dev, lmac_id)) + return 0; + return cgx_read(cgx_dev, lmac_id, offset); }
From: Zeng Heng zengheng4@huawei.com
[ Upstream commit 3c675ddffb17a8b1e32efad5c983254af18b12c2 ]
Here is a BUG report from syzbot:
BUG: KASAN: slab-out-of-bounds in ntfs_list_ea fs/ntfs3/xattr.c:191 [inline] BUG: KASAN: slab-out-of-bounds in ntfs_listxattr+0x401/0x570 fs/ntfs3/xattr.c:710 Read of size 1 at addr ffff888021acaf3d by task syz-executor128/3632
Call Trace: ntfs_list_ea fs/ntfs3/xattr.c:191 [inline] ntfs_listxattr+0x401/0x570 fs/ntfs3/xattr.c:710 vfs_listxattr fs/xattr.c:457 [inline] listxattr+0x293/0x2d0 fs/xattr.c:804
Fix the logic of ea_all iteration. When the ea->name_len is 0, return immediately, or Add2Ptr() would visit invalid memory in the next loop.
Fixes: be71b5cba2e6 ("fs/ntfs3: Add attrib operations") Reported-by: syzbot+9fcea5ef6dc4dc72d334@syzkaller.appspotmail.com Signed-off-by: Zeng Heng zengheng4@huawei.com [almaz.alexandrovich@paragon-software.com: lines of the patch have changed] Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ntfs3/xattr.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c index 8847db0159084..63250a5aae0aa 100644 --- a/fs/ntfs3/xattr.c +++ b/fs/ntfs3/xattr.c @@ -178,6 +178,9 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer, for (ret = 0, off = 0; off < size; off += unpacked_ea_size(ea)) { ea = Add2Ptr(ea_all, off);
+ if (!ea->name_len) + break; + if (buffer) { if (ret + ea->name_len + 1 > bytes_per_buffer) { err = -ERANGE;
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 39f49684036d24af800ff194c33c7b2653c591d7 ]
In a randconfig with CONFIG_SERIAL_CPM=m and CONFIG_PPC_EARLY_DEBUG_CPM=y, there is a build error: ERROR: modpost: "udbg_putc" [drivers/tty/serial/cpm_uart/cpm_uart.ko] undefined!
Prevent the build error by allowing PPC_EARLY_DEBUG_CPM only when SERIAL_CPM=y.
Fixes: c374e00e17f1 ("[POWERPC] Add early debug console for CPM serial ports.") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reviewed-by: Pali Rohár pali@kernel.org Reviewed-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230701054714.30512-1-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 192f0ed0097ff..80ce54f59fae8 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -240,7 +240,7 @@ config PPC_EARLY_DEBUG_40x
config PPC_EARLY_DEBUG_CPM bool "Early serial debugging for Freescale CPM-based serial ports" - depends on SERIAL_CPM + depends on SERIAL_CPM=y help Select this to enable early debugging for Freescale chips using a CPM-based serial port. This assumes that the bootwrapper
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 6ca3c005d0604e8d2b439366e3923ea58db99641 ]
According to the synchronization rules for .ndo_get_stats() as seen in Documentation/networking/netdevices.rst, acquiring a plain spin_lock() should not be illegal, but the bridge driver implementation makes it so.
After running these commands, I am being faced with the following lockdep splat:
$ ip link add link swp0 name macsec0 type macsec encrypt on && ip link set swp0 up $ ip link add dev br0 type bridge vlan_filtering 1 && ip link set br0 up $ ip link set macsec0 master br0 && ip link set macsec0 up
======================================================== WARNING: possible irq lock inversion dependency detected 6.4.0-04295-g31b577b4bd4a #603 Not tainted -------------------------------------------------------- swapper/1/0 just changed the state of lock: ffff6bd348724cd8 (&br->lock){+.-.}-{3:3}, at: br_forward_delay_timer_expired+0x34/0x198 but this lock took another, SOFTIRQ-unsafe lock in the past: (&ocelot->stats_lock){+.+.}-{3:3}
and interrupts could create inverse lock ordering between them.
other info that might help us debug this: Chain exists of: &br->lock --> &br->hash_lock --> &ocelot->stats_lock
Possible interrupt unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(&ocelot->stats_lock); local_irq_disable(); lock(&br->lock); lock(&br->hash_lock); <Interrupt> lock(&br->lock);
*** DEADLOCK ***
(details about the 3 locks skipped)
swp0 is instantiated by drivers/net/dsa/ocelot/felix.c, and this only matters to the extent that its .ndo_get_stats64() method calls spin_lock(&ocelot->stats_lock).
Documentation/locking/lockdep-design.rst says:
| A lock is irq-safe means it was ever used in an irq context, while a lock | is irq-unsafe means it was ever acquired with irq enabled.
(...)
| Furthermore, the following usage based lock dependencies are not allowed | between any two lock-classes:: | | <hardirq-safe> -> <hardirq-unsafe> | <softirq-safe> -> <softirq-unsafe>
Lockdep marks br->hash_lock as softirq-safe, because it is sometimes taken in softirq context (for example br_fdb_update() which runs in NET_RX softirq), and when it's not in softirq context it blocks softirqs by using spin_lock_bh().
Lockdep marks ocelot->stats_lock as softirq-unsafe, because it never blocks softirqs from running, and it is never taken from softirq context. So it can always be interrupted by softirqs.
There is a call path through which a function that holds br->hash_lock: fdb_add_hw_addr() will call a function that acquires ocelot->stats_lock: ocelot_port_get_stats64(). This can be seen below:
ocelot_port_get_stats64+0x3c/0x1e0 felix_get_stats64+0x20/0x38 dsa_slave_get_stats64+0x3c/0x60 dev_get_stats+0x74/0x2c8 rtnl_fill_stats+0x4c/0x150 rtnl_fill_ifinfo+0x5cc/0x7b8 rtmsg_ifinfo_build_skb+0xe4/0x150 rtmsg_ifinfo+0x5c/0xb0 __dev_notify_flags+0x58/0x200 __dev_set_promiscuity+0xa0/0x1f8 dev_set_promiscuity+0x30/0x70 macsec_dev_change_rx_flags+0x68/0x88 __dev_set_promiscuity+0x1a8/0x1f8 __dev_set_rx_mode+0x74/0xa8 dev_uc_add+0x74/0xa0 fdb_add_hw_addr+0x68/0xd8 fdb_add_local+0xc4/0x110 br_fdb_add_local+0x54/0x88 br_add_if+0x338/0x4a0 br_add_slave+0x20/0x38 do_setlink+0x3a4/0xcb8 rtnl_newlink+0x758/0x9d0 rtnetlink_rcv_msg+0x2f0/0x550 netlink_rcv_skb+0x128/0x148 rtnetlink_rcv+0x24/0x38
the plain English explanation for it is:
The macsec0 bridge port is created without p->flags & BR_PROMISC, because it is what br_manage_promisc() decides for a VLAN filtering bridge with a single auto port.
As part of the br_add_if() procedure, br_fdb_add_local() is called for the MAC address of the device, and this results in a call to dev_uc_add() for macsec0 while the softirq-safe br->hash_lock is taken.
Because macsec0 does not have IFF_UNICAST_FLT, dev_uc_add() ends up calling __dev_set_promiscuity() for macsec0, which is propagated by its implementation, macsec_dev_change_rx_flags(), to the lower device: swp0. This triggers the call path:
dev_set_promiscuity(swp0) -> rtmsg_ifinfo() -> dev_get_stats() -> ocelot_port_get_stats64()
with a calling context that lockdep doesn't like (br->hash_lock held).
Normally we don't see this, because even though many drivers that can be bridge ports don't support IFF_UNICAST_FLT, we need a driver that
(a) doesn't support IFF_UNICAST_FLT, *and* (b) it forwards the IFF_PROMISC flag to another driver, and (c) *that* driver implements ndo_get_stats64() using a softirq-unsafe spinlock.
Condition (b) is necessary because the first __dev_set_rx_mode() calls __dev_set_promiscuity() with "bool notify=false", and thus, the rtmsg_ifinfo() code path won't be entered.
The same criteria also hold true for DSA switches which don't report IFF_UNICAST_FLT. When the DSA master uses a spin_lock() in its ndo_get_stats64() method, the same lockdep splat can be seen.
I think the deadlock possibility is real, even though I didn't reproduce it, and I'm thinking of the following situation to support that claim:
fdb_add_hw_addr() runs on a CPU A, in a context with softirqs locally disabled and br->hash_lock held, and may end up attempting to acquire ocelot->stats_lock.
In parallel, ocelot->stats_lock is currently held by a thread B (say, ocelot_check_stats_work()), which is interrupted while holding it by a softirq which attempts to lock br->hash_lock.
Thread B cannot make progress because br->hash_lock is held by A. Whereas thread A cannot make progress because ocelot->stats_lock is held by B.
When taking the issue at face value, the bridge can avoid that problem by simply making the ports promiscuous from a code path with a saner calling context (br->hash_lock not held). A bridge port without IFF_UNICAST_FLT is going to become promiscuous as soon as we call dev_uc_add() on it (which we do unconditionally), so why not be preemptive and make it promiscuous right from the beginning, so as to not be taken by surprise.
With this, we've broken the links between code that holds br->hash_lock or br->lock and code that calls into the ndo_change_rx_flags() or ndo_get_stats64() ops of the bridge port.
Fixes: 2796d0c648c9 ("bridge: Automatically manage port promiscuous mode.") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Ido Schimmel idosch@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/bridge/br_if.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 4a02f8bb278a1..1f70441cbada8 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -157,8 +157,9 @@ void br_manage_promisc(struct net_bridge *br) * This lets us disable promiscuous mode and write * this config to hw. */ - if (br->auto_cnt == 0 || - (br->auto_cnt == 1 && br_auto_port(p))) + if ((p->dev->priv_flags & IFF_UNICAST_FLT) && + (br->auto_cnt == 0 || + (br->auto_cnt == 1 && br_auto_port(p)))) br_port_clear_promisc(p); else br_port_set_promisc(p);
From: Eric Dumazet edumazet@google.com
[ Upstream commit 998127cdb4699b9d470a9348ffe9f1154346be5f ]
request sockets are lockless, __tcp_oow_rate_limited() could be called on the same object from different cpus. This is harmless.
Add READ_ONCE()/WRITE_ONCE() annotations to avoid a KCSAN report.
Fixes: 4ce7e93cb3fe ("tcp: rate limit ACK sent by SYN_RECV request sockets") Signed-off-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp_input.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 65f5d07cd83d9..6849094e5e5e8 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3584,8 +3584,11 @@ static int tcp_ack_update_window(struct sock *sk, const struct sk_buff *skb, u32 static bool __tcp_oow_rate_limited(struct net *net, int mib_idx, u32 *last_oow_ack_time) { - if (*last_oow_ack_time) { - s32 elapsed = (s32)(tcp_jiffies32 - *last_oow_ack_time); + /* Paired with the WRITE_ONCE() in this function. */ + u32 val = READ_ONCE(*last_oow_ack_time); + + if (val) { + s32 elapsed = (s32)(tcp_jiffies32 - val);
if (0 <= elapsed && elapsed < READ_ONCE(net->ipv4.sysctl_tcp_invalid_ratelimit)) { @@ -3594,7 +3597,10 @@ static bool __tcp_oow_rate_limited(struct net *net, int mib_idx, } }
- *last_oow_ack_time = tcp_jiffies32; + /* Paired with the prior READ_ONCE() and with itself, + * as we might be lockless. + */ + WRITE_ONCE(*last_oow_ack_time, tcp_jiffies32);
return false; /* not rate-limited: go ahead, send dupack now! */ }
From: Ilya Maximets i.maximets@ovn.org
[ Upstream commit f7306acec9aae9893d15e745c8791124d42ab10a ]
Initial creation of an AF_XDP socket requires CAP_NET_RAW capability. A privileged process might create the socket and pass it to a non-privileged process for later use. However, that process will be able to bind the socket to any network interface. Even though it will not be able to receive any traffic without modification of the BPF map, the situation is not ideal.
Sockets already have a mechanism that can be used to restrict what interface they can be attached to. That is SO_BINDTODEVICE.
To change the SO_BINDTODEVICE binding the process will need CAP_NET_RAW.
Make xsk_bind() honor the SO_BINDTODEVICE in order to allow safer workflow when non-privileged process is using AF_XDP.
The intended workflow is following:
1. First process creates a bare socket with socket(AF_XDP, ...). 2. First process loads the XSK program to the interface. 3. First process adds the socket fd to a BPF map. 4. First process ties socket fd to a particular interface using SO_BINDTODEVICE. 5. First process sends socket fd to a second process. 6. Second process allocates UMEM. 7. Second process binds socket to the interface with bind(...). 8. Second process sends/receives the traffic.
All the steps above are possible today if the first process is privileged and the second one has sufficient RLIMIT_MEMLOCK and no capabilities. However, the second process will be able to bind the socket to any interface it wants on step 7 and send traffic from it. With the proposed change, the second process will be able to bind the socket only to a specific interface chosen by the first process at step 4.
Fixes: 965a99098443 ("xsk: add support for bind for Rx") Signed-off-by: Ilya Maximets i.maximets@ovn.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Magnus Karlsson magnus.karlsson@intel.com Acked-by: John Fastabend john.fastabend@gmail.com Acked-by: Jason Wang jasowang@redhat.com Link: https://lore.kernel.org/bpf/20230703175329.3259672-1-i.maximets@ovn.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/networking/af_xdp.rst | 9 +++++++++ net/xdp/xsk.c | 5 +++++ 2 files changed, 14 insertions(+)
diff --git a/Documentation/networking/af_xdp.rst b/Documentation/networking/af_xdp.rst index 60b217b436be6..5b77b9e5ac7e6 100644 --- a/Documentation/networking/af_xdp.rst +++ b/Documentation/networking/af_xdp.rst @@ -433,6 +433,15 @@ start N bytes into the buffer leaving the first N bytes for the application to use. The final option is the flags field, but it will be dealt with in separate sections for each UMEM flag.
+SO_BINDTODEVICE setsockopt +-------------------------- + +This is a generic SOL_SOCKET option that can be used to tie AF_XDP +socket to a particular network interface. It is useful when a socket +is created by a privileged process and passed to a non-privileged one. +Once the option is set, kernel will refuse attempts to bind that socket +to a different interface. Updating the value requires CAP_NET_RAW. + XDP_STATISTICS getsockopt -------------------------
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index 330dd498fc61d..e80e3fcbb8e8f 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -893,6 +893,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len) struct sock *sk = sock->sk; struct xdp_sock *xs = xdp_sk(sk); struct net_device *dev; + int bound_dev_if; u32 flags, qid; int err = 0;
@@ -906,6 +907,10 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len) XDP_USE_NEED_WAKEUP)) return -EINVAL;
+ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); + if (bound_dev_if && bound_dev_if != sxdp->sxdp_ifindex) + return -EINVAL; + rtnl_lock(); mutex_lock(&xs->mutex); if (xs->state != XSK_READY) {
From: Lin Ma linma@zju.edu.cn
[ Upstream commit 30c45b5361d39b4b793780ffac5538090b9e2eb1 ]
The attribute TCA_PEDIT_PARMS_EX is not be included in pedit_policy and one malicious user could fake a TCA_PEDIT_PARMS_EX whose length is smaller than the intended sizeof(struct tc_pedit). Hence, the dereference in tcf_pedit_init() could access dirty heap data.
static int tcf_pedit_init(...) { // ... pattr = tb[TCA_PEDIT_PARMS]; // TCA_PEDIT_PARMS is included if (!pattr) pattr = tb[TCA_PEDIT_PARMS_EX]; // but this is not
// ... parm = nla_data(pattr);
index = parm->index; // parm is able to be smaller than 4 bytes // and this dereference gets dirty skb_buff // data created in netlink_sendmsg }
This commit adds TCA_PEDIT_PARMS_EX length in pedit_policy which avoid the above case, just like the TCA_PEDIT_PARMS.
Fixes: 71d0ed7079df ("net/act_pedit: Support using offset relative to the conventional network headers") Signed-off-by: Lin Ma linma@zju.edu.cn Reviewed-by: Pedro Tammela pctammela@mojatatu.com Link: https://lore.kernel.org/r/20230703110842.590282-1-linma@zju.edu.cn Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/act_pedit.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index e77da0545b553..df9ff123a7eec 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -29,6 +29,7 @@ static struct tc_action_ops act_pedit_ops;
static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = { [TCA_PEDIT_PARMS] = { .len = sizeof(struct tc_pedit) }, + [TCA_PEDIT_PARMS_EX] = { .len = sizeof(struct tc_pedit) }, [TCA_PEDIT_KEYS_EX] = { .type = NLA_NESTED }, };
From: Woody Zhang woodylab@foxmail.com
[ Upstream commit 85fadc0d04119c2fe4a20287767ab904c6d21ba1 ]
The initial memblock metadata is accessed from kernel image mapping. The regions arrays need to "reallocated" from memblock and accessed through linear mapping to cover more memblock regions. So the resizing should not be allowed until linear mapping is ready. Note that there are memblock allocations when building linear mapping.
This patch is similar to 24cc61d8cb5a ("arm64: memblock: don't permit memblock resizing until linear mapping is up").
In following log, many memblock regions are reserved before create_linear_mapping_page_table(). And then it triggered reallocation of memblock.reserved.regions and memcpy the old array in kernel image mapping to the new array in linear mapping which caused a page fault.
[ 0.000000] memblock_reserve: [0x00000000bf01f000-0x00000000bf01ffff] early_init_fdt_scan_reserved_mem+0x28c/0x2c6 [ 0.000000] memblock_reserve: [0x00000000bf021000-0x00000000bf021fff] early_init_fdt_scan_reserved_mem+0x28c/0x2c6 [ 0.000000] memblock_reserve: [0x00000000bf023000-0x00000000bf023fff] early_init_fdt_scan_reserved_mem+0x28c/0x2c6 [ 0.000000] memblock_reserve: [0x00000000bf025000-0x00000000bf025fff] early_init_fdt_scan_reserved_mem+0x28c/0x2c6 [ 0.000000] memblock_reserve: [0x00000000bf027000-0x00000000bf027fff] early_init_fdt_scan_reserved_mem+0x28c/0x2c6 [ 0.000000] memblock_reserve: [0x00000000bf029000-0x00000000bf029fff] early_init_fdt_scan_reserved_mem+0x28c/0x2c6 [ 0.000000] memblock_reserve: [0x00000000bf02b000-0x00000000bf02bfff] early_init_fdt_scan_reserved_mem+0x28c/0x2c6 [ 0.000000] memblock_reserve: [0x00000000bf02d000-0x00000000bf02dfff] early_init_fdt_scan_reserved_mem+0x28c/0x2c6 [ 0.000000] memblock_reserve: [0x00000000bf02f000-0x00000000bf02ffff] early_init_fdt_scan_reserved_mem+0x28c/0x2c6 [ 0.000000] memblock_reserve: [0x00000000bf030000-0x00000000bf030fff] early_init_fdt_scan_reserved_mem+0x28c/0x2c6 [ 0.000000] OF: reserved mem: 0x0000000080000000..0x000000008007ffff (512 KiB) map non-reusable mmode_resv0@80000000 [ 0.000000] memblock_reserve: [0x00000000bf000000-0x00000000bf001fed] paging_init+0x19a/0x5ae [ 0.000000] memblock_phys_alloc_range: 4096 bytes align=0x1000 from=0x0000000000000000 max_addr=0x0000000000000000 alloc_pmd_fixmap+0x14/0x1c [ 0.000000] memblock_reserve: [0x000000017ffff000-0x000000017fffffff] memblock_alloc_range_nid+0xb8/0x128 [ 0.000000] memblock: reserved is doubled to 256 at [0x000000017fffd000-0x000000017fffe7ff] [ 0.000000] Unable to handle kernel paging request at virtual address ff600000ffffd000 [ 0.000000] Oops [#1] [ 0.000000] Modules linked in: [ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 6.4.0-rc1-00011-g99a670b2069c #66 [ 0.000000] Hardware name: riscv-virtio,qemu (DT) [ 0.000000] epc : __memcpy+0x60/0xf8 [ 0.000000] ra : memblock_double_array+0x192/0x248 [ 0.000000] epc : ffffffff8081d214 ra : ffffffff80a3dfc0 sp : ffffffff81403bd0 [ 0.000000] gp : ffffffff814fbb38 tp : ffffffff8140dac0 t0 : 0000000001600000 [ 0.000000] t1 : 0000000000000000 t2 : 000000008f001000 s0 : ffffffff81403c60 [ 0.000000] s1 : ffffffff80c0bc98 a0 : ff600000ffffd000 a1 : ffffffff80c0bcd8 [ 0.000000] a2 : 0000000000000c00 a3 : ffffffff80c0c8d8 a4 : 0000000080000000 [ 0.000000] a5 : 0000000000080000 a6 : 0000000000000000 a7 : 0000000080200000 [ 0.000000] s2 : ff600000ffffd000 s3 : 0000000000002000 s4 : 0000000000000c00 [ 0.000000] s5 : ffffffff80c0bc60 s6 : ffffffff80c0bcc8 s7 : 0000000000000000 [ 0.000000] s8 : ffffffff814fd0a8 s9 : 000000017fffe7ff s10: 0000000000000000 [ 0.000000] s11: 0000000000001000 t3 : 0000000000001000 t4 : 0000000000000000 [ 0.000000] t5 : 000000008f003000 t6 : ff600000ffffd000 [ 0.000000] status: 0000000200000100 badaddr: ff600000ffffd000 cause: 000000000000000f [ 0.000000] [<ffffffff8081d214>] __memcpy+0x60/0xf8 [ 0.000000] [<ffffffff80a3e1a2>] memblock_add_range.isra.14+0x12c/0x162 [ 0.000000] [<ffffffff80a3e36a>] memblock_reserve+0x6e/0x8c [ 0.000000] [<ffffffff80a123fc>] memblock_alloc_range_nid+0xb8/0x128 [ 0.000000] [<ffffffff80a1256a>] memblock_phys_alloc_range+0x5e/0x6a [ 0.000000] [<ffffffff80a04732>] alloc_pmd_fixmap+0x14/0x1c [ 0.000000] [<ffffffff80a0475a>] alloc_p4d_fixmap+0xc/0x14 [ 0.000000] [<ffffffff80a04a36>] create_pgd_mapping+0x98/0x17c [ 0.000000] [<ffffffff80a04e9e>] create_linear_mapping_range.constprop.10+0xe4/0x112 [ 0.000000] [<ffffffff80a05bb8>] paging_init+0x3ec/0x5ae [ 0.000000] [<ffffffff80a03354>] setup_arch+0xb2/0x576 [ 0.000000] [<ffffffff80a00726>] start_kernel+0x72/0x57e [ 0.000000] Code: b303 0285 b383 0305 be03 0385 be83 0405 bf03 0485 (b023) 00ef [ 0.000000] ---[ end trace 0000000000000000 ]--- [ 0.000000] Kernel panic - not syncing: Attempted to kill the idle task! [ 0.000000] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---
Fixes: 671f9a3e2e24 ("RISC-V: Setup initial page tables in two stages") Signed-off-by: Woody Zhang woodylab@foxmail.com Tested-by: Song Shuai songshuaishuai@tinylab.org Link: https://lore.kernel.org/r/tencent_FBB94CE615C5CCE7701CD39C15CCE0EE9706@qq.co... Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/mm/init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 0afcd4ae7eed1..f8bfbe983517c 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -235,7 +235,6 @@ static void __init setup_bootmem(void) dma_contiguous_reserve(dma32_phys_limit); if (IS_ENABLED(CONFIG_64BIT)) hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT); - memblock_allow_resize(); }
#ifdef CONFIG_MMU @@ -868,6 +867,9 @@ void __init paging_init(void) { setup_bootmem(); setup_vm_final(); + + /* Depend on that Linear Mapping is ready */ + memblock_allow_resize(); }
void __init misc_mem_init(void)
From: Guillaume Nault gnault@redhat.com
[ Upstream commit 84bef5b6037c15180ef88ac4216dc621d16df1a6 ]
PPTP uses pppox sockets (struct pppox_sock). These sockets don't embed an inet_sock structure, so it's invalid to call inet_sk() on them.
Therefore, the ip_route_output_ports() call in pptp_connect() has two problems:
* The tos variable is set with RT_CONN_FLAGS(sk), which calls inet_sk() on the pppox socket.
* ip_route_output_ports() tries to retrieve routing flags using inet_sk_flowi_flags(), which is also going to call inet_sk() on the pppox socket.
While PPTP doesn't use inet sockets, it's actually really layered on top of IP and therefore needs a proper way to do fib lookups. So let's define pptp_route_output() to get a struct rtable from a pptp socket. Let's also replace the ip_route_output_ports() call of pptp_xmit() for consistency.
In practice, this means that:
* pptp_connect() sets ->flowi4_tos and ->flowi4_flags to zero instead of using bits of unrelated struct pppox_sock fields.
* pptp_xmit() now respects ->sk_mark and ->sk_uid.
* pptp_xmit() now calls the security_sk_classify_flow() security hook, thus allowing to set ->flowic_secid.
* pptp_xmit() now passes the pppox socket to xfrm_lookup_route().
Found by code inspection.
Fixes: 00959ade36ac ("PPTP: PPP over IPv4 (Point-to-Point Tunneling Protocol)") Signed-off-by: Guillaume Nault gnault@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ppp/pptp.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index 0fe78826c8fa4..32183f24e63ff 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c @@ -24,6 +24,7 @@ #include <linux/in.h> #include <linux/ip.h> #include <linux/rcupdate.h> +#include <linux/security.h> #include <linux/spinlock.h>
#include <net/sock.h> @@ -128,6 +129,23 @@ static void del_chan(struct pppox_sock *sock) spin_unlock(&chan_lock); }
+static struct rtable *pptp_route_output(struct pppox_sock *po, + struct flowi4 *fl4) +{ + struct sock *sk = &po->sk; + struct net *net; + + net = sock_net(sk); + flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, 0, + RT_SCOPE_UNIVERSE, IPPROTO_GRE, 0, + po->proto.pptp.dst_addr.sin_addr.s_addr, + po->proto.pptp.src_addr.sin_addr.s_addr, + 0, 0, sock_net_uid(net, sk)); + security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4)); + + return ip_route_output_flow(net, fl4, sk); +} + static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) { struct sock *sk = (struct sock *) chan->private; @@ -151,11 +169,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) if (sk_pppox(po)->sk_state & PPPOX_DEAD) goto tx_error;
- rt = ip_route_output_ports(net, &fl4, NULL, - opt->dst_addr.sin_addr.s_addr, - opt->src_addr.sin_addr.s_addr, - 0, 0, IPPROTO_GRE, - RT_TOS(0), sk->sk_bound_dev_if); + rt = pptp_route_output(po, &fl4); if (IS_ERR(rt)) goto tx_error;
@@ -438,12 +452,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, po->chan.private = sk; po->chan.ops = &pptp_chan_ops;
- rt = ip_route_output_ports(sock_net(sk), &fl4, sk, - opt->dst_addr.sin_addr.s_addr, - opt->src_addr.sin_addr.s_addr, - 0, 0, - IPPROTO_GRE, RT_CONN_FLAGS(sk), - sk->sk_bound_dev_if); + rt = pptp_route_output(po, &fl4); if (IS_ERR(rt)) { error = -EHOSTUNREACH; goto end;
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 1dcf6efd5f0c1f4496b3ef7ec5a7db104a53b38c ]
The SJA1105 manual says that at offset 4 into the meta frame payload we have "MAC destination byte 2" and at offset 5 we have "MAC destination byte 1". These are counted from the LSB, so byte 1 is h_dest[ETH_HLEN-2] aka h_dest[4] and byte 2 is h_dest[ETH_HLEN-3] aka h_dest[3].
The sja1105_meta_unpack() function decodes these the other way around, so a frame with MAC DA 01:80:c2:11:22:33 is received by the network stack as having 01:80:c2:22:11:33.
Fixes: e53e18a6fe4d ("net: dsa: sja1105: Receive and decode meta frames") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Simon Horman simon.horman@corigine.com Reviewed-by: Florian Fainelli florian.fainelli@broadcom.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_sja1105.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c index d43feadd5fa6b..a163f535697e1 100644 --- a/net/dsa/tag_sja1105.c +++ b/net/dsa/tag_sja1105.c @@ -100,8 +100,8 @@ static void sja1105_meta_unpack(const struct sk_buff *skb, * a unified unpacking command for both device series. */ packing(buf, &meta->tstamp, 31, 0, 4, UNPACK, 0); - packing(buf + 4, &meta->dmac_byte_4, 7, 0, 1, UNPACK, 0); - packing(buf + 5, &meta->dmac_byte_3, 7, 0, 1, UNPACK, 0); + packing(buf + 4, &meta->dmac_byte_3, 7, 0, 1, UNPACK, 0); + packing(buf + 5, &meta->dmac_byte_4, 7, 0, 1, UNPACK, 0); packing(buf + 6, &meta->source_port, 7, 0, 1, UNPACK, 0); packing(buf + 7, &meta->switch_id, 7, 0, 1, UNPACK, 0); }
From: Hariprasad Kelam hkelam@marvell.com
[ Upstream commit 14bb236b29922c4f57d8c05bfdbcb82677f917c9 ]
MAC block on CN10K (RPM) supports hardware timestamp configuration. The previous patch which added timestamp configuration support has a bug. Though the netdev driver requests to disable timestamp configuration, the driver is always enabling it.
This patch fixes the same.
Fixes: d1489208681d ("octeontx2-af: cn10k: RPM hardware timestamp configuration") Signed-off-by: Hariprasad Kelam hkelam@marvell.com Signed-off-by: Sunil Goutham sgoutham@marvell.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c index 5ca4ab5770542..f4c7bb6bf053a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c @@ -724,7 +724,7 @@ static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable) cgxd = rvu_cgx_pdata(cgx_id, rvu);
mac_ops = get_mac_ops(cgxd); - mac_ops->mac_enadis_ptp_config(cgxd, lmac_id, true); + mac_ops->mac_enadis_ptp_config(cgxd, lmac_id, enable); /* If PTP is enabled then inform NPC that packets to be * parsed by this PF will have their data shifted by 8 bytes * and if PTP is disabled then no shift is required
From: Thorsten Winkler twinkler@linux.ibm.com
[ Upstream commit 80de809bd35e2a8999edf9f5aaa2d8de18921f11 ]
Change boolean parameter of function "qeth_l3_vipa_store" inside the "qeth_l3_dev_vipa_del4_store" function from "true" to "false" because "true" is used for adding a virtual ip address and "false" for deleting.
Fixes: 2390166a6b45 ("s390/qeth: clean up L3 sysfs code")
Reviewed-by: Alexandra Winter wintera@linux.ibm.com Reviewed-by: Wenjia Zhang wenjia@linux.ibm.com Signed-off-by: Thorsten Winkler twinkler@linux.ibm.com Signed-off-by: Alexandra Winter wintera@linux.ibm.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/net/qeth_l3_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 1082380b21f85..dba9b307020cb 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c @@ -652,7 +652,7 @@ static QETH_DEVICE_ATTR(vipa_add4, add4, 0644, static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - return qeth_l3_vipa_store(dev, buf, true, count, QETH_PROT_IPV4); + return qeth_l3_vipa_store(dev, buf, false, count, QETH_PROT_IPV4); }
static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
From: Artur Rojek contact@artur-rojek.eu
[ Upstream commit e82e47584847129a20b8c9f4a1dcde09374fb0e0 ]
Various SoCs of the SH3, SH4 and SH4A family, which use this driver, feature a differing number of DMA channels, which can be distributed between up to two DMAC modules. The existing implementation fails to correctly accommodate for all those variations, resulting in wrong channel offset calculations and leading to kernel panics.
Rewrite dma_base_addr() in order to properly calculate channel offsets in a DMAC module. Fix dmaor_read_reg() and dmaor_write_reg(), so that the correct DMAC module base is selected for the DMAOR register.
Fixes: 7f47c7189b3e8f19 ("sh: dma: More legacy cpu dma chainsawing.") Signed-off-by: Artur Rojek contact@artur-rojek.eu Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Link: https://lore.kernel.org/r/20230527164452.64797-2-contact@artur-rojek.eu Signed-off-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sh/drivers/dma/dma-sh.c | 37 +++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 96c626c2cd0a4..306fba1564e5e 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -18,6 +18,18 @@ #include <cpu/dma-register.h> #include <cpu/dma.h>
+/* + * Some of the SoCs feature two DMAC modules. In such a case, the channels are + * distributed equally among them. + */ +#ifdef SH_DMAC_BASE1 +#define SH_DMAC_NR_MD_CH (CONFIG_NR_ONCHIP_DMA_CHANNELS / 2) +#else +#define SH_DMAC_NR_MD_CH CONFIG_NR_ONCHIP_DMA_CHANNELS +#endif + +#define SH_DMAC_CH_SZ 0x10 + /* * Define the default configuration for dual address memory-memory transfer. * The 0x400 value represents auto-request, external->external. @@ -29,7 +41,7 @@ static unsigned long dma_find_base(unsigned int chan) unsigned long base = SH_DMAC_BASE0;
#ifdef SH_DMAC_BASE1 - if (chan >= 6) + if (chan >= SH_DMAC_NR_MD_CH) base = SH_DMAC_BASE1; #endif
@@ -40,13 +52,13 @@ static unsigned long dma_base_addr(unsigned int chan) { unsigned long base = dma_find_base(chan);
- /* Normalize offset calculation */ - if (chan >= 9) - chan -= 6; - if (chan >= 4) - base += 0x10; + chan = (chan % SH_DMAC_NR_MD_CH) * SH_DMAC_CH_SZ; + + /* DMAOR is placed inside the channel register space. Step over it. */ + if (chan >= DMAOR) + base += SH_DMAC_CH_SZ;
- return base + (chan * 0x10); + return base + chan; }
#ifdef CONFIG_SH_DMA_IRQ_MULTI @@ -250,12 +262,11 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan) #define NR_DMAOR 1 #endif
-/* - * DMAOR bases are broken out amongst channel groups. DMAOR0 manages - * channels 0 - 5, DMAOR1 6 - 11 (optional). - */ -#define dmaor_read_reg(n) __raw_readw(dma_find_base((n)*6)) -#define dmaor_write_reg(n, data) __raw_writew(data, dma_find_base(n)*6) +#define dmaor_read_reg(n) __raw_readw(dma_find_base((n) * \ + SH_DMAC_NR_MD_CH) + DMAOR) +#define dmaor_write_reg(n, data) __raw_writew(data, \ + dma_find_base((n) * \ + SH_DMAC_NR_MD_CH) + DMAOR)
static inline int dmaor_reset(int no) {
From: Danila Chernetsov listdansp@mail.ru
[ Upstream commit 000518bc5aef25d3f703592a0296d578c98b1517 ]
rhashtable_insert_fast() could return err value when memory allocation is failed. but unpack_profile() do not check values and this always returns success value. This patch just adds error check code.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: e025be0f26d5 ("apparmor: support querying extended trusted helper extra data")
Signed-off-by: Danila Chernetsov listdansp@mail.ru Signed-off-by: John Johansen john.johansen@canonical.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/apparmor/policy_unpack.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index d5b3a062d1d18..5f758b289ace3 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -909,8 +909,13 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) goto fail; }
- rhashtable_insert_fast(profile->data, &data->head, - profile->data->p); + if (rhashtable_insert_fast(profile->data, &data->head, + profile->data->p)) { + kfree_sensitive(data->key); + kfree_sensitive(data); + info = "failed to insert data to table"; + goto fail; + } }
if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
From: Marek Vasut marex@denx.de
[ Upstream commit 743e227a895923c37a333eb2ebf3e391f00c406d ]
The __xiic_start_xfer() manipulates the interrupt flags, xiic_wakeup() may result in return from xiic_xfer() early. Defer both to the end of the xiic_process() interrupt thread, so that they are executed after all the other interrupt bits handling completed and once it completely safe to perform changes to the interrupt bits in the hardware.
Signed-off-by: Marek Vasut marex@denx.de Acked-by: Michal Simek michal.simek@xilinx.com Signed-off-by: Wolfram Sang wsa@kernel.org Stable-dep-of: cb6e45c9a0ad ("i2c: xiic: Don't try to handle more interrupt events after error") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-xiic.c | 37 ++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 34b8da949462a..14926b193e0ee 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -375,6 +375,9 @@ static irqreturn_t xiic_process(int irq, void *dev_id) struct xiic_i2c *i2c = dev_id; u32 pend, isr, ier; u32 clr = 0; + int xfer_more = 0; + int wakeup_req = 0; + int wakeup_code = 0;
/* Get the interrupt Status from the IPIF. There is no clearing of * interrupts in the IPIF. Interrupts must be cleared at the source. @@ -411,10 +414,14 @@ static irqreturn_t xiic_process(int irq, void *dev_id) */ xiic_reinit(i2c);
- if (i2c->rx_msg) - xiic_wakeup(i2c, STATE_ERROR); - if (i2c->tx_msg) - xiic_wakeup(i2c, STATE_ERROR); + if (i2c->rx_msg) { + wakeup_req = 1; + wakeup_code = STATE_ERROR; + } + if (i2c->tx_msg) { + wakeup_req = 1; + wakeup_code = STATE_ERROR; + } } if (pend & XIIC_INTR_RX_FULL_MASK) { /* Receive register/FIFO is full */ @@ -448,8 +455,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) i2c->tx_msg++; dev_dbg(i2c->adap.dev.parent, "%s will start next...\n", __func__); - - __xiic_start_xfer(i2c); + xfer_more = 1; } } } @@ -463,11 +469,13 @@ static irqreturn_t xiic_process(int irq, void *dev_id) if (!i2c->tx_msg) goto out;
- if ((i2c->nmsgs == 1) && !i2c->rx_msg && - xiic_tx_space(i2c) == 0) - xiic_wakeup(i2c, STATE_DONE); + wakeup_req = 1; + + if (i2c->nmsgs == 1 && !i2c->rx_msg && + xiic_tx_space(i2c) == 0) + wakeup_code = STATE_DONE; else - xiic_wakeup(i2c, STATE_ERROR); + wakeup_code = STATE_ERROR; } if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) { /* Transmit register/FIFO is empty or ½ empty */ @@ -491,7 +499,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) if (i2c->nmsgs > 1) { i2c->nmsgs--; i2c->tx_msg++; - __xiic_start_xfer(i2c); + xfer_more = 1; } else { xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
@@ -509,6 +517,13 @@ static irqreturn_t xiic_process(int irq, void *dev_id) dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr); + if (xfer_more) + __xiic_start_xfer(i2c); + if (wakeup_req) + xiic_wakeup(i2c, wakeup_code); + + WARN_ON(xfer_more && wakeup_req); + mutex_unlock(&i2c->lock); return IRQ_HANDLED; }
From: Robert Hancock robert.hancock@calian.com
[ Upstream commit cb6e45c9a0ad9e0f8664fd06db0227d185dc76ab ]
In xiic_process, it is possible that error events such as arbitration lost or TX error can be raised in conjunction with other interrupt flags such as TX FIFO empty or bus not busy. Error events result in the controller being reset and the error returned to the calling request, but the function could potentially try to keep handling the other events, such as by writing more messages into the TX FIFO. Since the transaction has already failed, this is not helpful and will just cause issues.
This problem has been present ever since:
commit 7f9906bd7f72 ("i2c: xiic: Service all interrupts in isr")
which allowed non-error events to be handled after errors, but became more obvious after:
commit 743e227a8959 ("i2c: xiic: Defer xiic_wakeup() and __xiic_start_xfer() in xiic_process()")
which reworked the code to add a WARN_ON which triggers if both the xfer_more and wakeup_req flags were set, since this combination is not supposed to happen, but was occurring in this scenario.
Skip further interrupt handling after error flags are detected to avoid this problem.
Fixes: 7f9906bd7f72 ("i2c: xiic: Service all interrupts in isr") Signed-off-by: Robert Hancock robert.hancock@calian.com Acked-by: Andi Shyti andi.shyti@kernel.org Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-xiic.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 14926b193e0ee..9652e8bea2d0b 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -422,6 +422,8 @@ static irqreturn_t xiic_process(int irq, void *dev_id) wakeup_req = 1; wakeup_code = STATE_ERROR; } + /* don't try to handle other events */ + goto out; } if (pend & XIIC_INTR_RX_FULL_MASK) { /* Receive register/FIFO is full */
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 5313121b22fd11db0d14f305c110168b8176efdc ]
The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted.
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Chanwoo Choi cw00.choi@samsung.com Stable-dep-of: 3adbaa30d973 ("extcon: usbc-tusb320: Unregister typec port on driver removal") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/extcon/extcon-usbc-tusb320.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c index 9dfa545427ca1..b408ce989c223 100644 --- a/drivers/extcon/extcon-usbc-tusb320.c +++ b/drivers/extcon/extcon-usbc-tusb320.c @@ -428,8 +428,7 @@ static int tusb320_typec_probe(struct i2c_client *client, return 0; }
-static int tusb320_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tusb320_probe(struct i2c_client *client) { struct tusb320_priv *priv; const void *match_data; @@ -502,7 +501,7 @@ static const struct of_device_id tusb320_extcon_dt_match[] = { MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match);
static struct i2c_driver tusb320_extcon_driver = { - .probe = tusb320_probe, + .probe_new = tusb320_probe, .driver = { .name = "extcon-tusb320", .of_match_table = tusb320_extcon_dt_match,
From: Filipe Manana fdmanana@suse.com
[ Upstream commit 39020d8abc7ec62c4de9b260e3d10d4a1c2478ce ]
At balance_level(), instead of doing a BUG_ON() in case we fail to record tree mod log operations, do a transaction abort and return the error to the callers. There's really no need for the BUG_ON() as we can release all resources in this context, and we have to abort because other future tree searches that use the tree mod log (btrfs_search_old_slot()) may get inconsistent results if other operations modify the tree after that failure and before the tree mod log based search.
CC: stable@vger.kernel.org # 5.4+ Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/ctree.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 1a19354382b2b..8b57d691cfae8 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -912,7 +912,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, }
ret = btrfs_tree_mod_log_insert_root(root->node, child, true); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_tree_unlock(child); + free_extent_buffer(child); + btrfs_abort_transaction(trans, ret); + goto enospc; + } rcu_assign_pointer(root->node, child);
add_root_to_dirty_list(root); @@ -994,7 +999,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_node_key(right, &right_key, 0); ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1, BTRFS_MOD_LOG_KEY_REPLACE, GFP_NOFS); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + goto enospc; + } btrfs_set_node_key(parent, &right_key, pslot + 1); btrfs_mark_buffer_dirty(parent); } @@ -1040,7 +1048,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_node_key(mid, &mid_key, 0); ret = btrfs_tree_mod_log_insert_key(parent, pslot, BTRFS_MOD_LOG_KEY_REPLACE, GFP_NOFS); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + goto enospc; + } btrfs_set_node_key(parent, &mid_key, pslot); btrfs_mark_buffer_dirty(parent); }
From: Shuai Jiang d202180596@hust.edu.cn
commit cd9489623c29aa2f8cc07088168afb6e0d5ef06d upstream.
Smatch Warns: drivers/i2c/busses/i2c-qup.c:1784 qup_i2c_probe() warn: missing unwind goto?
The goto label "fail_runtime" and "fail" will disable qup->pclk, but here qup->pclk failed to obtain, in order to be consistent, change the direct return to goto label "fail_dma".
Fixes: 9cedf3b2f099 ("i2c: qup: Add bam dma capabilities") Signed-off-by: Shuai Jiang d202180596@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Reviewed-by: Andi Shyti andi.shyti@kernel.org Signed-off-by: Wolfram Sang wsa@kernel.org Cc: stable@vger.kernel.org # v4.6+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/i2c/busses/i2c-qup.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
--- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -1752,16 +1752,21 @@ nodma: if (!clk_freq || clk_freq > I2C_MAX_FAST_MODE_PLUS_FREQ) { dev_err(qup->dev, "clock frequency not supported %d\n", clk_freq); - return -EINVAL; + ret = -EINVAL; + goto fail_dma; }
qup->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(qup->base)) - return PTR_ERR(qup->base); + if (IS_ERR(qup->base)) { + ret = PTR_ERR(qup->base); + goto fail_dma; + }
qup->irq = platform_get_irq(pdev, 0); - if (qup->irq < 0) - return qup->irq; + if (qup->irq < 0) { + ret = qup->irq; + goto fail_dma; + }
if (has_acpi_companion(qup->dev)) { ret = device_property_read_u32(qup->dev, @@ -1775,13 +1780,15 @@ nodma: qup->clk = devm_clk_get(qup->dev, "core"); if (IS_ERR(qup->clk)) { dev_err(qup->dev, "Could not get core clock\n"); - return PTR_ERR(qup->clk); + ret = PTR_ERR(qup->clk); + goto fail_dma; }
qup->pclk = devm_clk_get(qup->dev, "iface"); if (IS_ERR(qup->pclk)) { dev_err(qup->dev, "Could not get iface clock\n"); - return PTR_ERR(qup->pclk); + ret = PTR_ERR(qup->pclk); + goto fail_dma; } qup_i2c_enable_clocks(qup); src_clk_freq = clk_get_rate(qup->clk);
From: Dai Ngo dai.ngo@oracle.com
commit 58f5d894006d82ed7335e1c37182fbc5f08c2f51 upstream.
Modified nfsd4_encode_open to encode the op_recall flag properly for OPEN result with write delegation granted.
Signed-off-by: Dai Ngo dai.ngo@oracle.com Reviewed-by: Jeff Layton jlayton@kernel.org Signed-off-by: Chuck Lever chuck.lever@oracle.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3816,7 +3816,7 @@ nfsd4_encode_open(struct nfsd4_compoundr p = xdr_reserve_space(xdr, 32); if (!p) return nfserr_resource; - *p++ = cpu_to_be32(0); + *p++ = cpu_to_be32(open->op_recall);
/* * TODO: space_limit's in delegations
From: Jens Axboe axboe@kernel.dk
commit 4826c59453b3b4677d6bf72814e7ababdea86949 upstream.
WHen the ring exits, cleanup is done and the final cancelation and waiting on completions is done by io_ring_exit_work. That function is invoked by kworker, which doesn't take any signals. Because of that, it doesn't really matter if we wait for completions in TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE state. However, it does matter to the hung task detection checker!
Normally we expect cancelations and completions to happen rather quickly. Some test cases, however, will exit the ring and park the owning task stopped (eg via SIGSTOP). If the owning task needs to run task_work to complete requests, then io_ring_exit_work won't make any progress until the task is runnable again. Hence io_ring_exit_work can trigger the hung task detection, which is particularly problematic if panic-on-hung-task is enabled.
As the ring exit doesn't take signals to begin with, have it wait interruptibly rather than uninterruptibly. io_uring has a separate stuck-exit warning that triggers independently anyway, so we're not really missing anything by making this switch.
Cc: stable@vger.kernel.org # 5.10+ Link: https://lore.kernel.org/r/b0e4aaef-7088-56ce-244c-976edeac0e66@kernel.dk Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- io_uring/io_uring.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
--- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -9714,7 +9714,18 @@ static void io_ring_exit_work(struct wor /* there is little hope left, don't run it too often */ interval = HZ * 60; } - } while (!wait_for_completion_timeout(&ctx->ref_comp, interval)); + /* + * This is really an uninterruptible wait, as it has to be + * complete. But it's also run from a kworker, which doesn't + * take signals, so it's fine to make it interruptible. This + * avoids scenarios where we knowingly can wait much longer + * on completions, for example if someone does a SIGSTOP on + * a task that needs to finish task_work to make this loop + * complete. That's a synthetic situation that should not + * cause a stuck task backtrace, and hence a potential panic + * on stuck tasks if that is enabled. + */ + } while (!wait_for_completion_interruptible_timeout(&ctx->ref_comp, interval));
init_completion(&exit.completion); init_task_work(&exit.task_work, io_tctx_exit_cb); @@ -9739,7 +9750,12 @@ static void io_ring_exit_work(struct wor wake_up_process(node->task);
mutex_unlock(&ctx->uring_lock); - wait_for_completion(&exit.completion); + /* + * See comment above for + * wait_for_completion_interruptible_timeout() on why this + * wait is marked as interruptible. + */ + wait_for_completion_interruptible(&exit.completion); mutex_lock(&ctx->uring_lock); } mutex_unlock(&ctx->uring_lock);
From: Robert Marko robimarko@gmail.com
commit f1738a1f816233e6dfc2407f24a31d596643fd90 upstream.
It seems that Kingston EMMC04G-M627 despite advertising TRIM support does not work when the core is trying to use REQ_OP_WRITE_ZEROES.
We are seeing I/O errors in OpenWrt under 6.1 on Zyxel NBG7815 that we did not previously have and tracked it down to REQ_OP_WRITE_ZEROES.
Trying to use fstrim seems to also throw errors like: [93010.835112] I/O error, dev loop0, sector 16902 op 0x3:(DISCARD) flags 0x800 phys_seg 1 prio class 2
Disabling TRIM makes the error go away, so lets add a quirk for this eMMC to disable TRIM.
Signed-off-by: Robert Marko robimarko@gmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230619193621.437358-1-robimarko@gmail.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/core/quirks.h | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -100,6 +100,13 @@ static const struct mmc_fixup __maybe_un MMC_QUIRK_TRIM_BROKEN),
/* + * Kingston EMMC04G-M627 advertises TRIM but it does not seems to + * support being used to offload WRITE_ZEROES. + */ + MMC_FIXUP("M62704", CID_MANFID_KINGSTON, 0x0100, add_quirk_mmc, + MMC_QUIRK_TRIM_BROKEN), + + /* * Some SD cards reports discard support while they don't */ MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd,
From: Robert Marko robimarko@gmail.com
commit dbfbddcddcebc9ce8a08757708d4e4a99d238e44 upstream.
It seems that Micron MTFC4GACAJCN-1M despite advertising TRIM support does not work when the core is trying to use REQ_OP_WRITE_ZEROES.
We are seeing the following errors in OpenWrt under 6.1 on Qnap Qhora 301W that we did not previously have and tracked it down to REQ_OP_WRITE_ZEROES: [ 18.085950] I/O error, dev loop0, sector 596 op 0x9:(WRITE_ZEROES) flags 0x800 phys_seg 0 prio class 2
Disabling TRIM makes the error go away, so lets add a quirk for this eMMC to disable TRIM.
Signed-off-by: Robert Marko robimarko@gmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230530213259.1776512-1-robimarko@gmail.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/core/quirks.h | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -107,6 +107,13 @@ static const struct mmc_fixup __maybe_un MMC_QUIRK_TRIM_BROKEN),
/* + * Micron MTFC4GACAJCN-1M advertises TRIM but it does not seems to + * support being used to offload WRITE_ZEROES. + */ + MMC_FIXUP("Q2J54A", CID_MANFID_MICRON, 0x014e, add_quirk_mmc, + MMC_QUIRK_TRIM_BROKEN), + + /* * Some SD cards reports discard support while they don't */ MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd,
From: Ulf Hansson ulf.hansson@linaro.org
commit 3108eb2e8aa7e955a9dd3a4c1bf19a7898961822 upstream.
All mmc host drivers should have the asynchronous probe option enabled, but it seems like we failed to set it for mmci, so let's do that now.
Fixes: 21b2cec61c04 ("mmc: Set PROBE_PREFER_ASYNCHRONOUS for drivers that existed in v4.4") Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Tested-by: Linus Walleij linus.walleij@linaro.org Tested-by: Yann Gautier yann.gautier@foss.st.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230612143730.210390-1-ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/host/mmci.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -2449,6 +2449,7 @@ static struct amba_driver mmci_driver = .drv = { .name = DRIVER_NAME, .pm = &mmci_dev_pm_ops, + .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, .probe = mmci_probe, .remove = mmci_remove,
From: Chevron Li chevron.li@bayhubtech.com
commit 20dbd07ef0a8bc29eb03d6a95258ac8934cbe52d upstream.
Bayhub SD host has hardware limitation: 1.The upper 32bit address is inhibited to be written at SD Host Register [03E][13]=0 (32bits addressing) mode, is admitted to be written only at SD Host Register [03E][13]=1 (64bits addressing) mode. 2.Because of above item#1, need to configure SD Host Register [03E][13] to 1(64bits addressing mode) before set 64bit ADMA system address's higher 32bits SD Host Register [05F~05C] if 64 bits addressing mode is used.
The hardware limitation is reasonable for below reasons: 1.Normal flow should set DMA working mode first, then do DMA-transfer-related configuration, such as system address. 2.The hardware limitation may avoid the software to configure wrong higher 32bit address at 32bits addressing mode although it is redundant.
The change that set 32bits/64bits addressing mode before set ADMA address, has no side-effect to other host IPs for below reason: The setting order is reasonable and standard: DMA Mode setting first and then DMA address setting. It meets all DMA setting sequence.
Signed-off-by: Chevron Li chevron.li@bayhubtech.com Acked-by: Adrian Hunter adrian.hunter@intel.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230523111114.18124-1-chevron_li@126.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/host/sdhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1144,6 +1144,8 @@ static void sdhci_prepare_data(struct sd } }
+ sdhci_config_dma(host); + if (host->flags & SDHCI_REQ_USE_DMA) { int sg_cnt = sdhci_pre_dma_transfer(host, data, COOKIE_MAPPED);
@@ -1163,8 +1165,6 @@ static void sdhci_prepare_data(struct sd } }
- sdhci_config_dma(host); - if (!(host->flags & SDHCI_REQ_USE_DMA)) { int flags;
From: Mingzhe Zou mingzhe.zou@easystack.cn
commit f0854489fc07d2456f7cc71a63f4faf9c716ffbe upstream.
We get a kernel crash about "list_add corruption. next->prev should be prev (ffff9c801bc01210), but was ffff9c77b688237c. (next=ffffae586d8afe68)."
crash> struct list_head 0xffff9c801bc01210 struct list_head { next = 0xffffae586d8afe68, prev = 0xffffae586d8afe68 } crash> struct list_head 0xffff9c77b688237c struct list_head { next = 0x0, prev = 0x0 } crash> struct list_head 0xffffae586d8afe68 struct list_head struct: invalid kernel virtual address: ffffae586d8afe68 type: "gdb_readmem_callback" Cannot access memory at address 0xffffae586d8afe68
[230469.019492] Call Trace: [230469.032041] prepare_to_wait+0x8a/0xb0 [230469.044363] ? bch_btree_keys_free+0x6c/0xc0 [escache] [230469.056533] mca_cannibalize_lock+0x72/0x90 [escache] [230469.068788] mca_alloc+0x2ae/0x450 [escache] [230469.080790] bch_btree_node_get+0x136/0x2d0 [escache] [230469.092681] bch_btree_check_thread+0x1e1/0x260 [escache] [230469.104382] ? finish_wait+0x80/0x80 [230469.115884] ? bch_btree_check_recurse+0x1a0/0x1a0 [escache] [230469.127259] kthread+0x112/0x130 [230469.138448] ? kthread_flush_work_fn+0x10/0x10 [230469.149477] ret_from_fork+0x35/0x40
bch_btree_check_thread() and bch_dirty_init_thread() may call mca_cannibalize() to cannibalize other cached btree nodes. Only one thread can do it at a time, so the op of other threads will be added to the btree_cache_wait list.
We must call finish_wait() to remove op from btree_cache_wait before free it's memory address. Otherwise, the list will be damaged. Also should call bch_cannibalize_unlock() to release the btree_cache_alloc_lock and wake_up other waiters.
Fixes: 8e7102273f59 ("bcache: make bch_btree_check() to be multithreaded") Fixes: b144e45fc576 ("bcache: make bch_sectors_dirty_init() to be multithreaded") Cc: stable@vger.kernel.org Signed-off-by: Mingzhe Zou mingzhe.zou@easystack.cn Signed-off-by: Coly Li colyli@suse.de Link: https://lore.kernel.org/r/20230615121223.22502-7-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/btree.c | 11 ++++++++++- drivers/md/bcache/btree.h | 1 + drivers/md/bcache/writeback.c | 10 ++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-)
--- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -885,7 +885,7 @@ static struct btree *mca_cannibalize(str * cannibalize_bucket() will take. This means every time we unlock the root of * the btree, we need to release this lock if we have it held. */ -static void bch_cannibalize_unlock(struct cache_set *c) +void bch_cannibalize_unlock(struct cache_set *c) { spin_lock(&c->btree_cannibalize_lock); if (c->btree_cache_alloc_lock == current) { @@ -1968,6 +1968,15 @@ static int bch_btree_check_thread(void * c->gc_stats.nodes++; bch_btree_op_init(&op, 0); ret = bcache_btree(check_recurse, p, c->root, &op); + /* + * The op may be added to cache_set's btree_cache_wait + * in mca_cannibalize(), must ensure it is removed from + * the list and release btree_cache_alloc_lock before + * free op memory. + * Otherwise, the btree_cache_wait will be damaged. + */ + bch_cannibalize_unlock(c); + finish_wait(&c->btree_cache_wait, &(&op)->wait); if (ret) goto out; } --- a/drivers/md/bcache/btree.h +++ b/drivers/md/bcache/btree.h @@ -282,6 +282,7 @@ void bch_initial_gc_finish(struct cache_ void bch_moving_gc(struct cache_set *c); int bch_btree_check(struct cache_set *c); void bch_initial_mark_key(struct cache_set *c, int level, struct bkey *k); +void bch_cannibalize_unlock(struct cache_set *c);
static inline void wake_up_gc(struct cache_set *c) { --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -880,6 +880,16 @@ static int bch_root_node_dirty_init(stru if (ret < 0) pr_warn("sectors dirty init failed, ret=%d!\n", ret);
+ /* + * The op may be added to cache_set's btree_cache_wait + * in mca_cannibalize(), must ensure it is removed from + * the list and release btree_cache_alloc_lock before + * free op memory. + * Otherwise, the btree_cache_wait will be damaged. + */ + bch_cannibalize_unlock(c); + finish_wait(&c->btree_cache_wait, &(&op.op)->wait); + return ret; }
From: Zheng Wang zyytlz.wz@163.com
commit 028ddcac477b691dd9205c92f991cc15259d033e upstream.
Due to the previous fix of __bch_btree_node_alloc, the return value will never be a NULL pointer. So IS_ERR is enough to handle the failure situation. Fix it by replacing IS_ERR_OR_NULL check by an IS_ERR check.
Fixes: cafe56359144 ("bcache: A block layer cache") Cc: stable@vger.kernel.org Signed-off-by: Zheng Wang zyytlz.wz@163.com Signed-off-by: Coly Li colyli@suse.de Link: https://lore.kernel.org/r/20230615121223.22502-5-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/btree.c | 10 +++++----- drivers/md/bcache/super.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-)
--- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -1138,7 +1138,7 @@ static struct btree *btree_node_alloc_re { struct btree *n = bch_btree_node_alloc(b->c, op, b->level, b->parent);
- if (!IS_ERR_OR_NULL(n)) { + if (!IS_ERR(n)) { mutex_lock(&n->write_lock); bch_btree_sort_into(&b->keys, &n->keys, &b->c->sort); bkey_copy_key(&n->key, &b->key); @@ -1340,7 +1340,7 @@ static int btree_gc_coalesce(struct btre memset(new_nodes, 0, sizeof(new_nodes)); closure_init_stack(&cl);
- while (nodes < GC_MERGE_NODES && !IS_ERR_OR_NULL(r[nodes].b)) + while (nodes < GC_MERGE_NODES && !IS_ERR(r[nodes].b)) keys += r[nodes++].keys;
blocks = btree_default_blocks(b->c) * 2 / 3; @@ -1352,7 +1352,7 @@ static int btree_gc_coalesce(struct btre
for (i = 0; i < nodes; i++) { new_nodes[i] = btree_node_alloc_replacement(r[i].b, NULL); - if (IS_ERR_OR_NULL(new_nodes[i])) + if (IS_ERR(new_nodes[i])) goto out_nocoalesce; }
@@ -1487,7 +1487,7 @@ out_nocoalesce: bch_keylist_free(&keylist);
for (i = 0; i < nodes; i++) - if (!IS_ERR_OR_NULL(new_nodes[i])) { + if (!IS_ERR(new_nodes[i])) { btree_node_free(new_nodes[i]); rw_unlock(true, new_nodes[i]); } @@ -1669,7 +1669,7 @@ static int bch_btree_gc_root(struct btre if (should_rewrite) { n = btree_node_alloc_replacement(b, NULL);
- if (!IS_ERR_OR_NULL(n)) { + if (!IS_ERR(n)) { bch_btree_node_write_sync(n);
bch_btree_set_root(n); --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1729,7 +1729,7 @@ static void cache_set_flush(struct closu if (!IS_ERR_OR_NULL(c->gc_thread)) kthread_stop(c->gc_thread);
- if (!IS_ERR_OR_NULL(c->root)) + if (!IS_ERR(c->root)) list_add(&c->root->list, &c->btree_cache);
/* @@ -2093,7 +2093,7 @@ static int run_cache_set(struct cache_se
err = "cannot allocate new btree root"; c->root = __bch_btree_node_alloc(c, NULL, 0, true, NULL); - if (IS_ERR_OR_NULL(c->root)) + if (IS_ERR(c->root)) goto err;
mutex_lock(&c->root->write_lock);
From: Zheng Wang zyytlz.wz@163.com
commit 80fca8a10b604afad6c14213fdfd816c4eda3ee4 upstream.
In some specific situations, the return value of __bch_btree_node_alloc may be NULL. This may lead to a potential NULL pointer dereference in caller function like a calling chain : btree_split->bch_btree_node_alloc->__bch_btree_node_alloc.
Fix it by initializing the return value in __bch_btree_node_alloc.
Fixes: cafe56359144 ("bcache: A block layer cache") Cc: stable@vger.kernel.org Signed-off-by: Zheng Wang zyytlz.wz@163.com Signed-off-by: Coly Li colyli@suse.de Link: https://lore.kernel.org/r/20230615121223.22502-6-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/btree.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -1090,10 +1090,12 @@ struct btree *__bch_btree_node_alloc(str struct btree *parent) { BKEY_PADDED(key) k; - struct btree *b = ERR_PTR(-EAGAIN); + struct btree *b;
mutex_lock(&c->bucket_lock); retry: + /* return ERR_PTR(-EAGAIN) when it fails */ + b = ERR_PTR(-EAGAIN); if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, wait)) goto err;
From: Kees Cook keescook@chromium.org
commit a5a319ec2c2236bb96d147c16196d2f1f3799301 upstream.
When HEADER_ARCH was introduced, the MRPROPER_FILES (then MRPROPER_DIRS) list wasn't adjusted, leaving SUBARCH as part of the path argument. This resulted in the "mrproper" target not cleaning up arch/x86/... when SUBARCH was specified. Since HOST_DIR is arch/$(HEADER_ARCH), use it instead to get the correct path.
Cc: Richard Weinberger richard@nod.at Cc: Anton Ivanov anton.ivanov@cambridgegreys.com Cc: Johannes Berg johannes@sipsolutions.net Cc: Azeem Shaikh azeemshaikh38@gmail.com Cc: linux-um@lists.infradead.org Fixes: 7bbe7204e937 ("um: merge Makefile-{i386,x86_64}") Cc: stable@vger.kernel.org Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20230606222442.never.807-kees@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/um/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -148,7 +148,7 @@ export LDFLAGS_vmlinux := $(LDFLAGS_EXEC # When cleaning we don't include .config, so we don't include # TT or skas makefiles and don't clean skas_ptregs.h. CLEAN_FILES += linux x.i gmon.out -MRPROPER_FILES += arch/$(SUBARCH)/include/generated +MRPROPER_FILES += $(HOST_DIR)/include/generated
archclean: @find . ( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
From: Tianjia Zhang tianjia.zhang@linux.alibaba.com
commit 9df6a4870dc371136e90330cfbbc51464ee66993 upstream.
When integrity_inode_get() is querying and inserting the cache, there is a conditional race in the concurrent environment.
The race condition is the result of not properly implementing "double-checked locking". In this case, it first checks to see if the iint cache record exists before taking the lock, but doesn't check again after taking the integrity_iint_lock.
Fixes: bf2276d10ce5 ("ima: allocating iint improvements") Signed-off-by: Tianjia Zhang tianjia.zhang@linux.alibaba.com Cc: Dmitry Kasatkin dmitry.kasatkin@gmail.com Cc: stable@vger.kernel.org # v3.10+ Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/integrity/iint.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
--- a/security/integrity/iint.c +++ b/security/integrity/iint.c @@ -43,12 +43,10 @@ static struct integrity_iint_cache *__in else if (inode > iint->inode) n = n->rb_right; else - break; + return iint; } - if (!n) - return NULL;
- return iint; + return NULL; }
/* @@ -121,10 +119,15 @@ struct integrity_iint_cache *integrity_i parent = *p; test_iint = rb_entry(parent, struct integrity_iint_cache, rb_node); - if (inode < test_iint->inode) + if (inode < test_iint->inode) { p = &(*p)->rb_left; - else + } else if (inode > test_iint->inode) { p = &(*p)->rb_right; + } else { + write_unlock(&integrity_iint_lock); + kmem_cache_free(iint_cache, iint); + return test_iint; + } }
iint->inode = inode;
From: Arnd Bergmann arnd@arndb.de
commit e910c8e3aa02dc456e2f4c32cb479523c326b534 upstream.
Commit df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3") introduced a warning for the autofs_dev_ioctl structure:
In function 'check_name', inlined from 'validate_dev_ioctl' at fs/autofs/dev-ioctl.c:131:9, inlined from '_autofs_dev_ioctl' at fs/autofs/dev-ioctl.c:624:8: fs/autofs/dev-ioctl.c:33:14: error: 'strchr' reading 1 or more bytes from a region of size 0 [-Werror=stringop-overread] 33 | if (!strchr(name, '/')) | ^~~~~~~~~~~~~~~~~ In file included from include/linux/auto_dev-ioctl.h:10, from fs/autofs/autofs_i.h:10, from fs/autofs/dev-ioctl.c:14: include/uapi/linux/auto_dev-ioctl.h: In function '_autofs_dev_ioctl': include/uapi/linux/auto_dev-ioctl.h:112:14: note: source object 'path' of size 0 112 | char path[0]; | ^~~~
This is easily fixed by changing the gnu 0-length array into a c99 flexible array. Since this is a uapi structure, we have to be careful about possible regressions but this one should be fine as they are equivalent here. While it would break building with ancient gcc versions that predate c99, it helps building with --std=c99 and -Wpedantic builds in user space, as well as non-gnu compilers. This means we probably also want it fixed in stable kernels.
Cc: stable@vger.kernel.org Cc: Kees Cook keescook@chromium.org Cc: "Gustavo A. R. Silva" gustavoars@kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20230523081944.581710-1-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/filesystems/autofs-mount-control.rst | 2 +- Documentation/filesystems/autofs.rst | 2 +- include/uapi/linux/auto_dev-ioctl.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
--- a/Documentation/filesystems/autofs-mount-control.rst +++ b/Documentation/filesystems/autofs-mount-control.rst @@ -196,7 +196,7 @@ information and return operation results struct args_ismountpoint ismountpoint; };
- char path[0]; + char path[]; };
The ioctlfd field is a mount point file descriptor of an autofs mount --- a/Documentation/filesystems/autofs.rst +++ b/Documentation/filesystems/autofs.rst @@ -467,7 +467,7 @@ Each ioctl is passed a pointer to an `au struct args_ismountpoint ismountpoint; };
- char path[0]; + char path[]; };
For the **OPEN_MOUNT** and **IS_MOUNTPOINT** commands, the target --- a/include/uapi/linux/auto_dev-ioctl.h +++ b/include/uapi/linux/auto_dev-ioctl.h @@ -109,7 +109,7 @@ struct autofs_dev_ioctl { struct args_ismountpoint ismountpoint; };
- char path[0]; + char path[]; };
static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
From: Roberto Sassu roberto.sassu@huawei.com
commit 36ce9d76b0a93bae799e27e4f5ac35478c676592 upstream.
As the ramfs-based tmpfs uses ramfs_init_fs_context() for the init_fs_context method, which allocates fc->s_fs_info, use ramfs_kill_sb() to free it and avoid a memory leak.
Link: https://lkml.kernel.org/r/20230607161523.2876433-1-roberto.sassu@huaweicloud... Fixes: c3b1b1cbf002 ("ramfs: add support for "mode=" mount option") Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Cc: Hugh Dickins hughd@google.com Cc: David Howells dhowells@redhat.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ramfs/inode.c | 2 +- include/linux/ramfs.h | 1 + mm/shmem.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-)
--- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -274,7 +274,7 @@ int ramfs_init_fs_context(struct fs_cont return 0; }
-static void ramfs_kill_sb(struct super_block *sb) +void ramfs_kill_sb(struct super_block *sb) { kfree(sb->s_fs_info); kill_litter_super(sb); --- a/include/linux/ramfs.h +++ b/include/linux/ramfs.h @@ -7,6 +7,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir, umode_t mode, dev_t dev); extern int ramfs_init_fs_context(struct fs_context *fc); +extern void ramfs_kill_sb(struct super_block *sb);
#ifdef CONFIG_MMU static inline int --- a/mm/shmem.c +++ b/mm/shmem.c @@ -4043,7 +4043,7 @@ static struct file_system_type shmem_fs_ .name = "tmpfs", .init_fs_context = ramfs_init_fs_context, .parameters = ramfs_fs_parameters, - .kill_sb = kill_litter_super, + .kill_sb = ramfs_kill_sb, .fs_flags = FS_USERNS_MOUNT, };
From: Jan Kara jack@suse.cz
commit 3658840cd363f2be094f5dfd2f0b174a9055dd0f upstream.
Remove locking of moved directory in ext4_rename2(). We will take care of it in VFS instead. This effectively reverts commit 0813299c586b ("ext4: Fix possible corruption when moving a directory") and followup fixes.
CC: Ted Tso tytso@mit.edu CC: stable@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Message-Id: 20230601105830.13168-1-jack@suse.cz Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/namei.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-)
--- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3848,19 +3848,10 @@ static int ext4_rename(struct user_names return retval; }
- /* - * We need to protect against old.inode directory getting converted - * from inline directory format into a normal one. - */ - if (S_ISDIR(old.inode->i_mode)) - inode_lock_nested(old.inode, I_MUTEX_NONDIR2); - old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, &old.inlined); - if (IS_ERR(old.bh)) { - retval = PTR_ERR(old.bh); - goto unlock_moved_dir; - } + if (IS_ERR(old.bh)) + return PTR_ERR(old.bh);
/* * Check for inode number is _not_ due to possible IO errors. @@ -4050,10 +4041,6 @@ release_bh: brelse(old.bh); brelse(new.bh);
-unlock_moved_dir: - if (S_ISDIR(old.inode->i_mode)) - inode_unlock(old.inode); - return retval; }
From: Jan Kara jack@suse.cz
commit cde3c9d7e2a359e337216855dcb333a19daaa436 upstream.
This reverts commit d94772154e524b329a168678836745d2773a6e02. The locking is going to be provided by VFS.
CC: Jaegeuk Kim jaegeuk@kernel.org CC: stable@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Message-Id: 20230601105830.13168-3-jack@suse.cz Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/namei.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-)
--- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -991,20 +991,12 @@ static int f2fs_rename(struct inode *old goto out; }
- /* - * Copied from ext4_rename: we need to protect against old.inode - * directory getting converted from inline directory format into - * a normal one. - */ - if (S_ISDIR(old_inode->i_mode)) - inode_lock_nested(old_inode, I_MUTEX_NONDIR2); - err = -ENOENT; old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); if (!old_entry) { if (IS_ERR(old_page)) err = PTR_ERR(old_page); - goto out_unlock_old; + goto out; }
if (S_ISDIR(old_inode->i_mode)) { @@ -1112,9 +1104,6 @@ static int f2fs_rename(struct inode *old
f2fs_unlock_op(sbi);
- if (S_ISDIR(old_inode->i_mode)) - inode_unlock(old_inode); - if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) f2fs_sync_fs(sbi->sb, 1);
@@ -1129,9 +1118,6 @@ out_dir: f2fs_put_page(old_dir_page, 0); out_old: f2fs_put_page(old_page, 0); -out_unlock_old: - if (S_ISDIR(old_inode->i_mode)) - inode_unlock(old_inode); out: if (whiteout) iput(whiteout);
From: Jan Kara jack@suse.cz
commit f23ce757185319886ca80c4864ce5f81ac6cc9e9 upstream.
Currently the locking order of inode locks for directories that are not in ancestor relationship is not defined because all operations that needed to lock two directories like this were serialized by sb->s_vfs_rename_mutex. However some filesystems need to lock two subdirectories for RENAME_EXCHANGE operations and for this we need the locking order established even for two tree-unrelated directories. Provide a helper function lock_two_inodes() that establishes lock ordering for any two inodes and use it in lock_two_directories().
CC: stable@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Message-Id: 20230601105830.13168-4-jack@suse.cz Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/inode.c | 42 ++++++++++++++++++++++++++++++++++++++++++ fs/internal.h | 2 ++ fs/namei.c | 4 ++-- 3 files changed, 46 insertions(+), 2 deletions(-)
--- a/fs/inode.c +++ b/fs/inode.c @@ -1024,6 +1024,48 @@ void discard_new_inode(struct inode *ino EXPORT_SYMBOL(discard_new_inode);
/** + * lock_two_inodes - lock two inodes (may be regular files but also dirs) + * + * Lock any non-NULL argument. The caller must make sure that if he is passing + * in two directories, one is not ancestor of the other. Zero, one or two + * objects may be locked by this function. + * + * @inode1: first inode to lock + * @inode2: second inode to lock + * @subclass1: inode lock subclass for the first lock obtained + * @subclass2: inode lock subclass for the second lock obtained + */ +void lock_two_inodes(struct inode *inode1, struct inode *inode2, + unsigned subclass1, unsigned subclass2) +{ + if (!inode1 || !inode2) { + /* + * Make sure @subclass1 will be used for the acquired lock. + * This is not strictly necessary (no current caller cares) but + * let's keep things consistent. + */ + if (!inode1) + swap(inode1, inode2); + goto lock; + } + + /* + * If one object is directory and the other is not, we must make sure + * to lock directory first as the other object may be its child. + */ + if (S_ISDIR(inode2->i_mode) == S_ISDIR(inode1->i_mode)) { + if (inode1 > inode2) + swap(inode1, inode2); + } else if (!S_ISDIR(inode1->i_mode)) + swap(inode1, inode2); +lock: + if (inode1) + inode_lock_nested(inode1, subclass1); + if (inode2 && inode2 != inode1) + inode_lock_nested(inode2, subclass2); +} + +/** * lock_two_nondirectories - take two i_mutexes on non-directory objects * * Lock any non-NULL argument that is not a directory. --- a/fs/internal.h +++ b/fs/internal.h @@ -152,6 +152,8 @@ extern void inode_add_lru(struct inode * int dentry_needs_remove_privs(struct user_namespace *, struct dentry *dentry); bool in_group_or_capable(struct user_namespace *mnt_userns, const struct inode *inode, kgid_t gid); +void lock_two_inodes(struct inode *inode1, struct inode *inode2, + unsigned subclass1, unsigned subclass2);
/* * fs-writeback.c --- a/fs/namei.c +++ b/fs/namei.c @@ -2984,8 +2984,8 @@ struct dentry *lock_rename(struct dentry return p; }
- inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); - inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2); + lock_two_inodes(p1->d_inode, p2->d_inode, + I_MUTEX_PARENT, I_MUTEX_PARENT2); return NULL; } EXPORT_SYMBOL(lock_rename);
From: Jan Kara jack@suse.cz
commit 28eceeda130f5058074dd007d9c59d2e8bc5af2e upstream.
When a directory is moved to a different directory, some filesystems (udf, ext4, ocfs2, f2fs, and likely gfs2, reiserfs, and others) need to update their pointer to the parent and this must not race with other operations on the directory. Lock the directories when they are moved. Although not all filesystems need this locking, we perform it in vfs_rename() because getting the lock ordering right is really difficult and we don't want to expose these locking details to filesystems.
CC: stable@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Message-Id: 20230601105830.13168-5-jack@suse.cz Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/filesystems/directory-locking.rst | 26 ++++++++++++------------ fs/namei.c | 22 ++++++++++++-------- 2 files changed, 28 insertions(+), 20 deletions(-)
--- a/Documentation/filesystems/directory-locking.rst +++ b/Documentation/filesystems/directory-locking.rst @@ -22,12 +22,11 @@ exclusive. 3) object removal. Locking rules: caller locks parent, finds victim, locks victim and calls the method. Locks are exclusive.
-4) rename() that is _not_ cross-directory. Locking rules: caller locks -the parent and finds source and target. In case of exchange (with -RENAME_EXCHANGE in flags argument) lock both. In any case, -if the target already exists, lock it. If the source is a non-directory, -lock it. If we need to lock both, lock them in inode pointer order. -Then call the method. All locks are exclusive. +4) rename() that is _not_ cross-directory. Locking rules: caller locks the +parent and finds source and target. We lock both (provided they exist). If we +need to lock two inodes of different type (dir vs non-dir), we lock directory +first. If we need to lock two inodes of the same type, lock them in inode +pointer order. Then call the method. All locks are exclusive. NB: we might get away with locking the source (and target in exchange case) shared.
@@ -44,15 +43,17 @@ All locks are exclusive. rules:
* lock the filesystem - * lock parents in "ancestors first" order. + * lock parents in "ancestors first" order. If one is not ancestor of + the other, lock them in inode pointer order. * find source and target. * if old parent is equal to or is a descendent of target fail with -ENOTEMPTY * if new parent is equal to or is a descendent of source fail with -ELOOP - * If it's an exchange, lock both the source and the target. - * If the target exists, lock it. If the source is a non-directory, - lock it. If we need to lock both, do so in inode pointer order. + * Lock both the source and the target provided they exist. If we + need to lock two inodes of different type (dir vs non-dir), we lock + the directory first. If we need to lock two inodes of the same type, + lock them in inode pointer order. * call the method.
All ->i_rwsem are taken exclusive. Again, we might get away with locking @@ -66,8 +67,9 @@ If no directory is its own ancestor, the
Proof:
- First of all, at any moment we have a partial ordering of the - objects - A < B iff A is an ancestor of B. + First of all, at any moment we have a linear ordering of the + objects - A < B iff (A is an ancestor of B) or (B is not an ancestor + of A and ptr(A) < ptr(B)).
That ordering can change. However, the following is true:
--- a/fs/namei.c +++ b/fs/namei.c @@ -4618,7 +4618,7 @@ SYSCALL_DEFINE2(link, const char __user * sb->s_vfs_rename_mutex. We might be more accurate, but that's another * story. * c) we have to lock _four_ objects - parents and victim (if it exists), - * and source (if it is not a directory). + * and source. * And that - after we got ->i_mutex on parents (until then we don't know * whether the target exists). Solution: try to be smart with locking * order for inodes. We rely on the fact that tree topology may change @@ -4702,10 +4702,16 @@ int vfs_rename(struct renamedata *rd)
take_dentry_name_snapshot(&old_name, old_dentry); dget(new_dentry); - if (!is_dir || (flags & RENAME_EXCHANGE)) - lock_two_nondirectories(source, target); - else if (target) - inode_lock(target); + /* + * Lock all moved children. Moved directories may need to change parent + * pointer so they need the lock to prevent against concurrent + * directory changes moving parent pointer. For regular files we've + * historically always done this. The lockdep locking subclasses are + * somewhat arbitrary but RENAME_EXCHANGE in particular can swap + * regular files and directories so it's difficult to tell which + * subclasses to use. + */ + lock_two_inodes(source, target, I_MUTEX_NORMAL, I_MUTEX_NONDIR2);
error = -EPERM; if (IS_SWAPFILE(source) || (target && IS_SWAPFILE(target))) @@ -4753,9 +4759,9 @@ int vfs_rename(struct renamedata *rd) d_exchange(old_dentry, new_dentry); } out: - if (!is_dir || (flags & RENAME_EXCHANGE)) - unlock_two_nondirectories(source, target); - else if (target) + if (source) + inode_unlock(source); + if (target) inode_unlock(target); dput(new_dentry); if (!error) {
From: Abhijeet Rastogi abhijeet.1989@gmail.com
commit 04292c695f82b6cf0d25dd5ae494f16ddbb621f6 upstream.
Current range [8, 20] is set purely due to historical reasons because at the time, ~1M (2^20) was considered sufficient. With this change, 27 is the upper limit for 64-bit, 20 otherwise.
Previous change regarding this limit is here.
Link: https://lore.kernel.org/all/86eabeb9dd62aebf1e2533926fdd13fed48bab1f.1631289...
Signed-off-by: Abhijeet Rastogi abhijeet.1989@gmail.com Acked-by: Julian Anastasov ja@ssi.bg Acked-by: Simon Horman horms@kernel.org Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Cc: Allen Pais apais@linux.microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netfilter/ipvs/Kconfig | 27 ++++++++++++++------------- net/netfilter/ipvs/ip_vs_conn.c | 4 ++-- 2 files changed, 16 insertions(+), 15 deletions(-)
--- a/net/netfilter/ipvs/Kconfig +++ b/net/netfilter/ipvs/Kconfig @@ -44,7 +44,8 @@ config IP_VS_DEBUG
config IP_VS_TAB_BITS int "IPVS connection table size (the Nth power of 2)" - range 8 20 + range 8 20 if !64BIT + range 8 27 if 64BIT default 12 help The IPVS connection hash table uses the chaining scheme to handle @@ -54,24 +55,24 @@ config IP_VS_TAB_BITS
Note the table size must be power of 2. The table size will be the value of 2 to the your input number power. The number to choose is - from 8 to 20, the default number is 12, which means the table size - is 4096. Don't input the number too small, otherwise you will lose - performance on it. You can adapt the table size yourself, according - to your virtual server application. It is good to set the table size - not far less than the number of connections per second multiplying - average lasting time of connection in the table. For example, your - virtual server gets 200 connections per second, the connection lasts - for 200 seconds in average in the connection table, the table size - should be not far less than 200x200, it is good to set the table - size 32768 (2**15). + from 8 to 27 for 64BIT(20 otherwise), the default number is 12, + which means the table size is 4096. Don't input the number too + small, otherwise you will lose performance on it. You can adapt the + table size yourself, according to your virtual server application. + It is good to set the table size not far less than the number of + connections per second multiplying average lasting time of + connection in the table. For example, your virtual server gets 200 + connections per second, the connection lasts for 200 seconds in + average in the connection table, the table size should be not far + less than 200x200, it is good to set the table size 32768 (2**15).
Another note that each connection occupies 128 bytes effectively and each hash entry uses 8 bytes, so you can estimate how much memory is needed for your box.
You can overwrite this number setting conn_tab_bits module parameter - or by appending ip_vs.conn_tab_bits=? to the kernel command line - if IP VS was compiled built-in. + or by appending ip_vs.conn_tab_bits=? to the kernel command line if + IP VS was compiled built-in.
comment "IPVS transport protocol load balancing support"
--- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -1484,8 +1484,8 @@ int __init ip_vs_conn_init(void) int idx;
/* Compute size and mask */ - if (ip_vs_conn_tab_bits < 8 || ip_vs_conn_tab_bits > 20) { - pr_info("conn_tab_bits not in [8, 20]. Using default value\n"); + if (ip_vs_conn_tab_bits < 8 || ip_vs_conn_tab_bits > 27) { + pr_info("conn_tab_bits not in [8, 27]. Using default value\n"); ip_vs_conn_tab_bits = CONFIG_IP_VS_TAB_BITS; } ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
From: Fabian Frederick fabf@skynet.be
commit 1168f095417643f663caa341211e117db552989f upstream.
Use kcalloc() for allocation/flush of 128 pointers table to reduce stack usage.
Function now returns -ENOMEM or 0 on success.
stackusage Before: ./fs/jffs2/xattr.c:775 jffs2_build_xattr_subsystem 1208 dynamic,bounded
After: ./fs/jffs2/xattr.c:775 jffs2_build_xattr_subsystem 192 dynamic,bounded
Also update definition when CONFIG_JFFS2_FS_XATTR is not enabled
Tested with an MTD mount point and some user set/getfattr.
Many current target on OpenWRT also suffer from a compilation warning (that become an error with CONFIG_WERROR) with the following output:
fs/jffs2/xattr.c: In function 'jffs2_build_xattr_subsystem': fs/jffs2/xattr.c:887:1: error: the frame size of 1088 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] 887 | } | ^
Using dynamic allocation fix this compilation warning.
Fixes: c9f700f840bd ("[JFFS2][XATTR] using 'delete marker' for xdatum/xref deletion") Reported-by: Tim Gardner tim.gardner@canonical.com Reported-by: kernel test robot lkp@intel.com Reported-by: Ron Economos re@w6rz.net Reported-by: Nathan Chancellor nathan@kernel.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Fabian Frederick fabf@skynet.be Signed-off-by: Christian Marangi ansuelsmth@gmail.com Cc: stable@vger.kernel.org Message-Id: 20230506045612.16616-1-ansuelsmth@gmail.com Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/jffs2/build.c | 5 ++++- fs/jffs2/xattr.c | 13 +++++++++---- fs/jffs2/xattr.h | 4 ++-- 3 files changed, 15 insertions(+), 7 deletions(-)
--- a/fs/jffs2/build.c +++ b/fs/jffs2/build.c @@ -211,7 +211,10 @@ static int jffs2_build_filesystem(struct ic->scan_dents = NULL; cond_resched(); } - jffs2_build_xattr_subsystem(c); + ret = jffs2_build_xattr_subsystem(c); + if (ret) + goto exit; + c->flags &= ~JFFS2_SB_FLAG_BUILDING;
dbg_fsbuild("FS build complete\n"); --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -772,10 +772,10 @@ void jffs2_clear_xattr_subsystem(struct }
#define XREF_TMPHASH_SIZE (128) -void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) +int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) { struct jffs2_xattr_ref *ref, *_ref; - struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE]; + struct jffs2_xattr_ref **xref_tmphash; struct jffs2_xattr_datum *xd, *_xd; struct jffs2_inode_cache *ic; struct jffs2_raw_node_ref *raw; @@ -784,9 +784,12 @@ void jffs2_build_xattr_subsystem(struct
BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
+ xref_tmphash = kcalloc(XREF_TMPHASH_SIZE, + sizeof(struct jffs2_xattr_ref *), GFP_KERNEL); + if (!xref_tmphash) + return -ENOMEM; + /* Phase.1 : Merge same xref */ - for (i=0; i < XREF_TMPHASH_SIZE; i++) - xref_tmphash[i] = NULL; for (ref=c->xref_temp; ref; ref=_ref) { struct jffs2_xattr_ref *tmp;
@@ -884,6 +887,8 @@ void jffs2_build_xattr_subsystem(struct "%u of xref (%u dead, %u orphan) found.\n", xdatum_count, xdatum_unchecked_count, xdatum_orphan_count, xref_count, xref_dead_count, xref_orphan_count); + kfree(xref_tmphash); + return 0; }
struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, --- a/fs/jffs2/xattr.h +++ b/fs/jffs2/xattr.h @@ -71,7 +71,7 @@ static inline int is_xattr_ref_dead(stru #ifdef CONFIG_JFFS2_FS_XATTR
extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c); -extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c); +extern int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c); extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c);
extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, @@ -103,7 +103,7 @@ extern ssize_t jffs2_listxattr(struct de #else
#define jffs2_init_xattr_subsystem(c) -#define jffs2_build_xattr_subsystem(c) +#define jffs2_build_xattr_subsystem(c) (0) #define jffs2_clear_xattr_subsystem(c)
#define jffs2_xattr_do_crccheck_inode(c, ic)
From: Thomas Weißschuh linux@weissschuh.net
commit 62176420274db5b5127cd7a0083a9aeb461756ee upstream.
As each option string fragment is always prepended with a comma it would happen that the whole string always starts with a comma. This could be interpreted by filesystem drivers as an empty option and may produce errors.
For example the NTFS driver from ntfs.ko behaves like this and fails when mounted via the new API.
Link: https://github.com/util-linux/util-linux/issues/2298 Signed-off-by: Thomas Weißschuh linux@weissschuh.net Fixes: 3e1aeb00e6d1 ("vfs: Implement a filesystem superblock creation/configuration context") Cc: stable@vger.kernel.org Message-Id: 20230607-fs-empty-option-v1-1-20c8dbf4671b@weissschuh.net Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fs_context.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/fs_context.c +++ b/fs/fs_context.c @@ -561,7 +561,8 @@ static int legacy_parse_param(struct fs_ return -ENOMEM; }
- ctx->legacy_data[size++] = ','; + if (size) + ctx->legacy_data[size++] = ','; len = strlen(param->key); memcpy(ctx->legacy_data + size, param->key, len); size += len;
From: Matt Corallo blnxfsl@bluematt.me
commit 160fe8f6fdb13da6111677be6263e5d65e875987 upstream.
Callers of `btrfs_reduce_alloc_profile` expect it to return exactly one allocation profile flag, and failing to do so may ultimately result in a WARN_ON and remount-ro when allocating new blocks, like the below transaction abort on 6.1.
`btrfs_reduce_alloc_profile` has two ways of determining the profile, first it checks if a conversion balance is currently running and uses the profile we're converting to. If no balance is currently running, it returns the max-redundancy profile which at least one block in the selected block group has.
This works by simply checking each known allocation profile bit in redundancy order. However, `btrfs_reduce_alloc_profile` has not been updated as new flags have been added - first with the `DUP` profile and later with the RAID1C34 profiles.
Because of the way it checks, if we have blocks with different profiles and at least one is known, that profile will be selected. However, if none are known we may return a flag set with multiple allocation profiles set.
This is currently only possible when a balance from one of the three unhandled profiles to another of the unhandled profiles is canceled after allocating at least one block using the new profile.
In that case, a transaction abort like the below will occur and the filesystem will need to be mounted with -o skip_balance to get it mounted rw again (but the balance cannot be resumed without a similar abort).
[770.648] ------------[ cut here ]------------ [770.648] BTRFS: Transaction aborted (error -22) [770.648] WARNING: CPU: 43 PID: 1159593 at fs/btrfs/extent-tree.c:4122 find_free_extent+0x1d94/0x1e00 [btrfs] [770.648] CPU: 43 PID: 1159593 Comm: btrfs Tainted: G W 6.1.0-0.deb11.7-powerpc64le #1 Debian 6.1.20-2~bpo11+1a~test [770.648] Hardware name: T2P9D01 REV 1.00 POWER9 0x4e1202 opal:skiboot-bc106a0 PowerNV [770.648] NIP: c00800000f6784fc LR: c00800000f6784f8 CTR: c000000000d746c0 [770.648] REGS: c000200089afe9a0 TRAP: 0700 Tainted: G W (6.1.0-0.deb11.7-powerpc64le Debian 6.1.20-2~bpo11+1a~test) [770.648] MSR: 9000000002029033 <SF,HV,VEC,EE,ME,IR,DR,RI,LE> CR: 28848282 XER: 20040000 [770.648] CFAR: c000000000135110 IRQMASK: 0 GPR00: c00800000f6784f8 c000200089afec40 c00800000f7ea800 0000000000000026 GPR04: 00000001004820c2 c000200089afea00 c000200089afe9f8 0000000000000027 GPR08: c000200ffbfe7f98 c000000002127f90 ffffffffffffffd8 0000000026d6a6e8 GPR12: 0000000028848282 c000200fff7f3800 5deadbeef0000122 c00000002269d000 GPR16: c0002008c7797c40 c000200089afef17 0000000000000000 0000000000000000 GPR20: 0000000000000000 0000000000000001 c000200008bc5a98 0000000000000001 GPR24: 0000000000000000 c0000003c73088d0 c000200089afef17 c000000016d3a800 GPR28: c0000003c7308800 c00000002269d000 ffffffffffffffea 0000000000000001 [770.648] NIP [c00800000f6784fc] find_free_extent+0x1d94/0x1e00 [btrfs] [770.648] LR [c00800000f6784f8] find_free_extent+0x1d90/0x1e00 [btrfs] [770.648] Call Trace: [770.648] [c000200089afec40] [c00800000f6784f8] find_free_extent+0x1d90/0x1e00 [btrfs] (unreliable) [770.648] [c000200089afed30] [c00800000f681398] btrfs_reserve_extent+0x1a0/0x2f0 [btrfs] [770.648] [c000200089afeea0] [c00800000f681bf0] btrfs_alloc_tree_block+0x108/0x670 [btrfs] [770.648] [c000200089afeff0] [c00800000f66bd68] __btrfs_cow_block+0x170/0x850 [btrfs] [770.648] [c000200089aff100] [c00800000f66c58c] btrfs_cow_block+0x144/0x288 [btrfs] [770.648] [c000200089aff1b0] [c00800000f67113c] btrfs_search_slot+0x6b4/0xcb0 [btrfs] [770.648] [c000200089aff2a0] [c00800000f679f60] lookup_inline_extent_backref+0x128/0x7c0 [btrfs] [770.648] [c000200089aff3b0] [c00800000f67b338] lookup_extent_backref+0x70/0x190 [btrfs] [770.648] [c000200089aff470] [c00800000f67b54c] __btrfs_free_extent+0xf4/0x1490 [btrfs] [770.648] [c000200089aff5a0] [c00800000f67d770] __btrfs_run_delayed_refs+0x328/0x1530 [btrfs] [770.648] [c000200089aff740] [c00800000f67ea2c] btrfs_run_delayed_refs+0xb4/0x3e0 [btrfs] [770.648] [c000200089aff800] [c00800000f699aa4] btrfs_commit_transaction+0x8c/0x12b0 [btrfs] [770.648] [c000200089aff8f0] [c00800000f6dc628] reset_balance_state+0x1c0/0x290 [btrfs] [770.648] [c000200089aff9a0] [c00800000f6e2f7c] btrfs_balance+0x1164/0x1500 [btrfs] [770.648] [c000200089affb40] [c00800000f6f8e4c] btrfs_ioctl+0x2b54/0x3100 [btrfs] [770.648] [c000200089affc80] [c00000000053be14] sys_ioctl+0x794/0x1310 [770.648] [c000200089affd70] [c00000000002af98] system_call_exception+0x138/0x250 [770.648] [c000200089affe10] [c00000000000c654] system_call_common+0xf4/0x258 [770.648] --- interrupt: c00 at 0x7fff94126800 [770.648] NIP: 00007fff94126800 LR: 0000000107e0b594 CTR: 0000000000000000 [770.648] REGS: c000200089affe80 TRAP: 0c00 Tainted: G W (6.1.0-0.deb11.7-powerpc64le Debian 6.1.20-2~bpo11+1a~test) [770.648] MSR: 900000000000d033 <SF,HV,EE,PR,ME,IR,DR,RI,LE> CR: 24002848 XER: 00000000 [770.648] IRQMASK: 0 GPR00: 0000000000000036 00007fffc9439da0 00007fff94217100 0000000000000003 GPR04: 00000000c4009420 00007fffc9439ee8 0000000000000000 0000000000000000 GPR08: 00000000803c7416 0000000000000000 0000000000000000 0000000000000000 GPR12: 0000000000000000 00007fff9467d120 0000000107e64c9c 0000000107e64d0a GPR16: 0000000107e64d06 0000000107e64cf1 0000000107e64cc4 0000000107e64c73 GPR20: 0000000107e64c31 0000000107e64bf1 0000000107e64be7 0000000000000000 GPR24: 0000000000000000 00007fffc9439ee0 0000000000000003 0000000000000001 GPR28: 00007fffc943f713 0000000000000000 00007fffc9439ee8 0000000000000000 [770.648] NIP [00007fff94126800] 0x7fff94126800 [770.648] LR [0000000107e0b594] 0x107e0b594 [770.648] --- interrupt: c00 [770.648] Instruction dump: [770.648] 3b00ffe4 e8898828 481175f5 60000000 4bfff4fc 3be00000 4bfff570 3d220000 [770.648] 7fc4f378 e8698830 4811cd95 e8410018 <0fe00000> f9c10060 f9e10068 fa010070 [770.648] ---[ end trace 0000000000000000 ]--- [770.648] BTRFS: error (device dm-2: state A) in find_free_extent_update_loop:4122: errno=-22 unknown [770.648] BTRFS info (device dm-2: state EA): forced readonly [770.648] BTRFS: error (device dm-2: state EA) in __btrfs_free_extent:3070: errno=-22 unknown [770.648] BTRFS error (device dm-2: state EA): failed to run delayed ref for logical 17838685708288 num_bytes 24576 type 184 action 2 ref_mod 1: -22 [770.648] BTRFS: error (device dm-2: state EA) in btrfs_run_delayed_refs:2144: errno=-22 unknown [770.648] BTRFS: error (device dm-2: state EA) in reset_balance_state:3599: errno=-22 unknown
Fixes: 47e6f7423b91 ("btrfs: add support for 3-copy replication (raid1c3)") Fixes: 8d6fac0087e5 ("btrfs: add support for 4-copy replication (raid1c4)") CC: stable@vger.kernel.org # 5.10+ Signed-off-by: Matt Corallo blnxfsl@bluematt.me Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/block-group.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -78,14 +78,21 @@ static u64 btrfs_reduce_alloc_profile(st } allowed &= flags;
- if (allowed & BTRFS_BLOCK_GROUP_RAID6) + /* Select the highest-redundancy RAID level. */ + if (allowed & BTRFS_BLOCK_GROUP_RAID1C4) + allowed = BTRFS_BLOCK_GROUP_RAID1C4; + else if (allowed & BTRFS_BLOCK_GROUP_RAID6) allowed = BTRFS_BLOCK_GROUP_RAID6; + else if (allowed & BTRFS_BLOCK_GROUP_RAID1C3) + allowed = BTRFS_BLOCK_GROUP_RAID1C3; else if (allowed & BTRFS_BLOCK_GROUP_RAID5) allowed = BTRFS_BLOCK_GROUP_RAID5; else if (allowed & BTRFS_BLOCK_GROUP_RAID10) allowed = BTRFS_BLOCK_GROUP_RAID10; else if (allowed & BTRFS_BLOCK_GROUP_RAID1) allowed = BTRFS_BLOCK_GROUP_RAID1; + else if (allowed & BTRFS_BLOCK_GROUP_DUP) + allowed = BTRFS_BLOCK_GROUP_DUP; else if (allowed & BTRFS_BLOCK_GROUP_RAID0) allowed = BTRFS_BLOCK_GROUP_RAID0;
From: Naohiro Aota naota@elisp.net
commit 3ed01616bad6c7e3de196676b542ae3df8058592 upstream.
The reclaiming process only starts after the filesystem volumes are allocated to a certain level (75% by default). Thus, the list of reclaiming target block groups can build up so huge at the time the reclaim process kicks in. On a test run, there were over 1000 BGs in the reclaim list.
As the reclaim involves rewriting the data, it takes really long time to reclaim the BGs. While the reclaim is running, btrfs_delete_unused_bgs() won't proceed because the reclaim side is holding fs_info->reclaim_bgs_lock. As a result, we will have a large number of unused BGs kept in the unused list. On my test run, I got 1057 unused BGs.
Since deleting a block group is relatively easy and fast work, we can call btrfs_delete_unused_bgs() while it reclaims BGs, to avoid building up unused BGs.
Fixes: 18bb8bbf13c1 ("btrfs: zoned: automatically reclaim zones") CC: stable@vger.kernel.org # 5.15+ Reviewed-by: Filipe Manana fdmanana@suse.com Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Signed-off-by: Naohiro Aota naohiro.aota@wdc.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/block-group.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
--- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -1574,10 +1574,24 @@ void btrfs_reclaim_bgs_work(struct work_
next: btrfs_put_block_group(bg); + + mutex_unlock(&fs_info->reclaim_bgs_lock); + /* + * Reclaiming all the block groups in the list can take really + * long. Prioritize cleaning up unused block groups. + */ + btrfs_delete_unused_bgs(fs_info); + /* + * If we are interrupted by a balance, we can just bail out. The + * cleaner thread restart again if necessary. + */ + if (!mutex_trylock(&fs_info->reclaim_bgs_lock)) + goto end; spin_lock(&fs_info->unused_bgs_lock); } spin_unlock(&fs_info->unused_bgs_lock); mutex_unlock(&fs_info->reclaim_bgs_lock); +end: btrfs_exclop_finish(fs_info); sb_end_write(fs_info->sb); }
From: Naohiro Aota naota@elisp.net
commit 93463ff7b54626f8276c0bd3d3f968fbf8d5d380 upstream.
When a filesystem is read-only, we cannot reclaim a block group as it cannot rewrite the data. Just bail out in that case.
Note that it can drop block groups in this case. As we did sb_start_write(), read-only filesystem means we got a fatal error and forced read-only. There is no chance to reclaim them again.
Fixes: 18bb8bbf13c1 ("btrfs: zoned: automatically reclaim zones") CC: stable@vger.kernel.org # 5.15+ Reviewed-by: Filipe Manana fdmanana@suse.com Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Signed-off-by: Naohiro Aota naohiro.aota@wdc.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/block-group.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
--- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -1541,8 +1541,15 @@ void btrfs_reclaim_bgs_work(struct work_ } spin_unlock(&bg->lock);
- /* Get out fast, in case we're unmounting the filesystem */ - if (btrfs_fs_closing(fs_info)) { + /* + * Get out fast, in case we're read-only or unmounting the + * filesystem. It is OK to drop block groups from the list even + * for the read-only case. As we did sb_start_write(), + * "mount -o remount,ro" won't happen and read-only filesystem + * means it is forced read-only due to a fatal error. So, it + * never gets back to read-write to let us reclaim again. + */ + if (btrfs_need_cleaner_sleep(fs_info)) { up_write(&space_info->groups_sem); goto next; }
From: Naohiro Aota naota@elisp.net
commit 7e27180994383b7c741ad87749db01e4989a02ba upstream.
The reclaim process can temporarily fail. For example, if the space is getting tight, it fails to make the block group read-only. If there are no further writes on that block group, the block group will never get back to the reclaim list, and the BG never gets reclaimed. In a certain workload, we can leave many such block groups never reclaimed.
So, let's get it back to the list and give it a chance to be reclaimed.
Fixes: 18bb8bbf13c1 ("btrfs: zoned: automatically reclaim zones") CC: stable@vger.kernel.org # 5.15+ Signed-off-by: Naohiro Aota naohiro.aota@wdc.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/block-group.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -1580,6 +1580,8 @@ void btrfs_reclaim_bgs_work(struct work_ }
next: + if (ret) + btrfs_mark_bg_to_reclaim(bg); btrfs_put_block_group(bg);
mutex_unlock(&fs_info->reclaim_bgs_lock);
From: Filipe Manana fdmanana@suse.com
commit b31cb5a6eb7a48b0a7bfdf06832b1fd5088d8c79 upstream.
When disabling quotas we are deleting the quota root from the list fs_info->dirty_cowonly_roots without taking the lock that protects it, which is struct btrfs_fs_info::trans_lock. This unsynchronized list manipulation may cause chaos if there's another concurrent manipulation of this list, such as when adding a root to it with ctree.c:add_root_to_dirty_list().
This can result in all sorts of weird failures caused by a race, such as the following crash:
[337571.278245] general protection fault, probably for non-canonical address 0xdead000000000108: 0000 [#1] PREEMPT SMP PTI [337571.278933] CPU: 1 PID: 115447 Comm: btrfs Tainted: G W 6.4.0-rc6-btrfs-next-134+ #1 [337571.279153] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 [337571.279572] RIP: 0010:commit_cowonly_roots+0x11f/0x250 [btrfs] [337571.279928] Code: 85 38 06 00 (...) [337571.280363] RSP: 0018:ffff9f63446efba0 EFLAGS: 00010206 [337571.280582] RAX: ffff942d98ec2638 RBX: ffff9430b82b4c30 RCX: 0000000449e1c000 [337571.280798] RDX: dead000000000100 RSI: ffff9430021e4900 RDI: 0000000000036070 [337571.281015] RBP: ffff942d98ec2000 R08: ffff942d98ec2000 R09: 000000000000015b [337571.281254] R10: 0000000000000009 R11: 0000000000000001 R12: ffff942fe8fbf600 [337571.281476] R13: ffff942dabe23040 R14: ffff942dabe20800 R15: ffff942d92cf3b48 [337571.281723] FS: 00007f478adb7340(0000) GS:ffff94349fa40000(0000) knlGS:0000000000000000 [337571.281950] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [337571.282184] CR2: 00007f478ab9a3d5 CR3: 000000001e02c001 CR4: 0000000000370ee0 [337571.282416] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [337571.282647] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [337571.282874] Call Trace: [337571.283101] <TASK> [337571.283327] ? __die_body+0x1b/0x60 [337571.283570] ? die_addr+0x39/0x60 [337571.283796] ? exc_general_protection+0x22e/0x430 [337571.284022] ? asm_exc_general_protection+0x22/0x30 [337571.284251] ? commit_cowonly_roots+0x11f/0x250 [btrfs] [337571.284531] btrfs_commit_transaction+0x42e/0xf90 [btrfs] [337571.284803] ? _raw_spin_unlock+0x15/0x30 [337571.285031] ? release_extent_buffer+0x103/0x130 [btrfs] [337571.285305] reset_balance_state+0x152/0x1b0 [btrfs] [337571.285578] btrfs_balance+0xa50/0x11e0 [btrfs] [337571.285864] ? __kmem_cache_alloc_node+0x14a/0x410 [337571.286086] btrfs_ioctl+0x249a/0x3320 [btrfs] [337571.286358] ? mod_objcg_state+0xd2/0x360 [337571.286577] ? refill_obj_stock+0xb0/0x160 [337571.286798] ? seq_release+0x25/0x30 [337571.287016] ? __rseq_handle_notify_resume+0x3ba/0x4b0 [337571.287235] ? percpu_counter_add_batch+0x2e/0xa0 [337571.287455] ? __x64_sys_ioctl+0x88/0xc0 [337571.287675] __x64_sys_ioctl+0x88/0xc0 [337571.287901] do_syscall_64+0x38/0x90 [337571.288126] entry_SYSCALL_64_after_hwframe+0x72/0xdc [337571.288352] RIP: 0033:0x7f478aaffe9b
So fix this by locking struct btrfs_fs_info::trans_lock before deleting the quota root from that list.
Fixes: bed92eae26cc ("Btrfs: qgroup implementation and prototypes") CC: stable@vger.kernel.org # 4.14+ Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/qgroup.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1269,7 +1269,9 @@ int btrfs_quota_disable(struct btrfs_fs_ goto out; }
+ spin_lock(&fs_info->trans_lock); list_del("a_root->dirty_list); + spin_unlock(&fs_info->trans_lock);
btrfs_tree_lock(quota_root->node); btrfs_clean_tree_block(quota_root->node);
From: Filipe Manana fdmanana@suse.com
commit ede600e497b1461d06d22a7d17703d9096868bc3 upstream.
At split_node(), if we fail to log the tree mod log copy operation, we return without unlocking the split extent buffer we just allocated and without decrementing the reference we own on it. Fix this by unlocking it and decrementing the ref count before returning.
Fixes: 5de865eebb83 ("Btrfs: fix tree mod logging") CC: stable@vger.kernel.org # 5.4+ Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/ctree.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2637,6 +2637,8 @@ static noinline int split_node(struct bt
ret = btrfs_tree_mod_log_eb_copy(split, c, 0, mid, c_nritems - mid); if (ret) { + btrfs_tree_unlock(split); + free_extent_buffer(split); btrfs_abort_transaction(trans, ret); return ret; }
From: Filipe Manana fdmanana@suse.com
commit 40b0a749388517de244643c09bdbb98f7dcb6ef1 upstream.
At __btrfs_cow_block(), instead of doing a BUG_ON() in case we fail to record a tree mod log root insertion operation, do a transaction abort instead. There's really no need for the BUG_ON(), we can properly release all resources in this context and turn the filesystem to RO mode and in an error state instead.
CC: stable@vger.kernel.org # 5.4+ Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/ctree.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -457,9 +457,14 @@ static noinline int __btrfs_cow_block(st btrfs_header_backref_rev(buf) < BTRFS_MIXED_BACKREF_REV) parent_start = buf->start;
- atomic_inc(&cow->refs); ret = btrfs_tree_mod_log_insert_root(root->node, cow, true); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_tree_unlock(cow); + free_extent_buffer(cow); + btrfs_abort_transaction(trans, ret); + return ret; + } + atomic_inc(&cow->refs); rcu_assign_pointer(root->node, cow);
btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
From: Ricardo Ribalda Delgado ribalda@chromium.org
commit f9c058d14f4fe23ef523a7ff73734d51c151683c upstream.
After reordering the irq probe, the error path was not properly done. Lets fix it.
Reported-by: Dan Carpenter dan.carpenter@linaro.org Cc: stable@kernel.org Fixes: 4cbb264d4e91 ("ASoC: mediatek: mt8173: Enable IRQ when pdata is ready") Signed-off-by: Ricardo Ribalda Delgado ribalda@chromium.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20230612-mt8173-fixup-v2-2-432aa99ce24d@chromium.o... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c +++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c @@ -1072,6 +1072,10 @@ static int mt8173_afe_pcm_dev_probe(stru
afe->dev = &pdev->dev;
+ irq_id = platform_get_irq(pdev, 0); + if (irq_id <= 0) + return irq_id < 0 ? irq_id : -ENXIO; + afe->base_addr = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(afe->base_addr)) return PTR_ERR(afe->base_addr); @@ -1177,14 +1181,11 @@ static int mt8173_afe_pcm_dev_probe(stru if (ret) goto err_cleanup_components;
- irq_id = platform_get_irq(pdev, 0); - if (irq_id <= 0) - return irq_id < 0 ? irq_id : -ENXIO; ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler, 0, "Afe_ISR_Handle", (void *)afe); if (ret) { dev_err(afe->dev, "could not request_irq\n"); - goto err_pm_disable; + goto err_cleanup_components; }
dev_info(&pdev->dev, "MT8173 AFE driver initialized.\n");
From: Ricardo Ribalda Delgado ribalda@chromium.org
commit a46d37012a5be1737393b8f82fd35665e4556eee upstream.
If the second component fails to initialize, cleanup the first on.
Reported-by: Dan Carpenter dan.carpenter@linaro.org Cc: stable@kernel.org Fixes: f1b5bf07365d ("ASoC: mt2701/mt8173: replace platform to component") Signed-off-by: Ricardo Ribalda Delgado ribalda@chromium.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20230612-mt8173-fixup-v2-1-432aa99ce24d@chromium.o... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c +++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c @@ -1162,14 +1162,14 @@ static int mt8173_afe_pcm_dev_probe(stru comp_hdmi = devm_kzalloc(&pdev->dev, sizeof(*comp_hdmi), GFP_KERNEL); if (!comp_hdmi) { ret = -ENOMEM; - goto err_pm_disable; + goto err_cleanup_components; }
ret = snd_soc_component_initialize(comp_hdmi, &mt8173_afe_hdmi_dai_component, &pdev->dev); if (ret) - goto err_pm_disable; + goto err_cleanup_components;
#ifdef CONFIG_DEBUG_FS comp_hdmi->debugfs_prefix = "hdmi";
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
commit edcbdd57de499305e2a3737d4a73fe387f71d84c upstream.
After renaming NAND controller node name from "qpic-nand" to "nand-controller", the board DTS/DTSI also have to be updated:
Warning (unit_address_vs_reg): /soc/qpic-nand@79b0000: node has a unit name, but no reg or ranges property
Cc: stable@vger.kernel.org Fixes: 9e1e00f18afc ("ARM: dts: qcom: Fix node name for NAND controller node") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Reviewed-by: Manivannan Sadhasivam mani@kernel.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230420072811.36947-1-krzysztof.kozlowski@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1-c1.dts | 8 ++++---- arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi | 10 +++++----- arch/arm/boot/dts/qcom-ipq4019-ap.dk07.1.dtsi | 12 ++++++------ 3 files changed, 15 insertions(+), 15 deletions(-)
--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1-c1.dts +++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1-c1.dts @@ -11,9 +11,9 @@ dma@7984000 { status = "okay"; }; - - qpic-nand@79b0000 { - status = "okay"; - }; }; }; + +&nand { + status = "okay"; +}; --- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi @@ -102,10 +102,10 @@ status = "okay"; perst-gpio = <&tlmm 38 0x1>; }; - - qpic-nand@79b0000 { - pinctrl-0 = <&nand_pins>; - pinctrl-names = "default"; - }; }; }; + +&nand { + pinctrl-0 = <&nand_pins>; + pinctrl-names = "default"; +}; --- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk07.1.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk07.1.dtsi @@ -65,11 +65,11 @@ dma@7984000 { status = "okay"; }; - - qpic-nand@79b0000 { - pinctrl-0 = <&nand_pins>; - pinctrl-names = "default"; - status = "okay"; - }; }; }; + +&nand { + pinctrl-0 = <&nand_pins>; + pinctrl-names = "default"; + status = "okay"; +};
From: Arnd Bergmann arnd@arndb.de
commit f8ef1233939495c405a9faa4bd1ae7d3f581bae4 upstream.
The DT version of this board has a custom file with the gpio device. However, it does nothing because the d2net_init() has no caller or prototype:
arch/arm/mach-orion5x/board-d2net.c:101:13: error: no previous prototype for 'd2net_init'
Call it from the board-dt file as intended.
Fixes: 94b0bd366e36 ("ARM: orion5x: convert d2net to Device Tree") Reviewed-by: Andrew Lunn andrew@lunn.ch Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230516153109.514251-10-arnd@kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/mach-orion5x/board-dt.c | 3 +++ arch/arm/mach-orion5x/common.h | 6 ++++++ 2 files changed, 9 insertions(+)
--- a/arch/arm/mach-orion5x/board-dt.c +++ b/arch/arm/mach-orion5x/board-dt.c @@ -63,6 +63,9 @@ static void __init orion5x_dt_init(void) if (of_machine_is_compatible("maxtor,shared-storage-2")) mss2_init();
+ if (of_machine_is_compatible("lacie,d2-network")) + d2net_init(); + of_platform_default_populate(NULL, orion5x_auxdata_lookup, NULL); }
--- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h @@ -75,6 +75,12 @@ extern void mss2_init(void); static inline void mss2_init(void) {} #endif
+#ifdef CONFIG_MACH_D2NET_DT +void d2net_init(void); +#else +static inline void d2net_init(void) {} +#endif + /***************************************************************************** * Helpers to access Orion registers ****************************************************************************/
From: Christian Marangi ansuelsmth@gmail.com
commit cee4bd16c3195a701be683f7da9e88c6e11acb73 upstream.
Dev can be renamed also while up for supported device. We currently wrongly clear the NETDEV_LED_MODE_LINKUP flag on NETDEV_CHANGENAME event.
Fix this by rechecking if the carrier is ok on NETDEV_CHANGENAME and correctly set the NETDEV_LED_MODE_LINKUP bit.
Fixes: 5f820ed52371 ("leds: trigger: netdev: fix handling on interface rename") Cc: stable@vger.kernel.org # v5.5+ Signed-off-by: Christian Marangi ansuelsmth@gmail.com Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: Lee Jones lee@kernel.org Link: https://lore.kernel.org/r/20230419210743.3594-2-ansuelsmth@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/leds/trigger/ledtrig-netdev.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -318,6 +318,9 @@ static int netdev_trig_notify(struct not clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); switch (evt) { case NETDEV_CHANGENAME: + if (netif_carrier_ok(dev)) + set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); + fallthrough; case NETDEV_REGISTER: if (trigger_data->net_dev) dev_put(trigger_data->net_dev);
From: Jan Kara jack@suse.cz
commit 66d8fc0539b0d49941f313c9509a8384e4245ac1 upstream.
The @source inode must be valid. It is even checked via IS_SWAPFILE() above making it pretty clear. So no need to check it when we unlock.
What doesn't need to exist is the @target inode. The lock_two_inodes() helper currently swaps the @inode1 and @inode2 arguments if @inode1 is NULL to have consistent lock class usage. However, we know that at least for vfs_rename() that @inode1 is @source and thus is never NULL as per above. We also know that @source is a different inode than @target as that is checked right at the beginning of vfs_rename(). So we know that @source is valid and locked and that @target is locked. So drop the check whether @source is non-NULL.
Fixes: 28eceeda130f ("fs: Lock moved directories") Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@linaro.org Closes: https://lore.kernel.org/r/202307030026.9sE2pk2x-lkp@intel.com Message-Id: 20230703-vfs-rename-source-v1-1-37eebb29b65b@kernel.org [brauner: use commit message from patch I sent concurrently] Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/namei.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/fs/namei.c +++ b/fs/namei.c @@ -4759,8 +4759,7 @@ int vfs_rename(struct renamedata *rd) d_exchange(old_dentry, new_dentry); } out: - if (source) - inode_unlock(source); + inode_unlock(source); if (target) inode_unlock(target); dput(new_dentry);
From: Zhihao Cheng chengzhihao1@huawei.com
commit f4e19e595cc2e76a8a58413eb19d3d9c51328b53 upstream.
Following process: P1 P2 path_openat link_path_walk may_lookup inode_permission(rcu) ovl_permission acl_permission_check check_acl get_cached_acl_rcu ovl_get_inode_acl realinode = ovl_inode_real(ovl_inode) drop_cache __dentry_kill(ovl_dentry) iput(ovl_inode) ovl_destroy_inode(ovl_inode) dput(oi->__upperdentry) dentry_kill(upperdentry) dentry_unlink_inode upperdentry->d_inode = NULL ovl_inode_upper upperdentry = ovl_i_dentry_upper(ovl_inode) d_inode(upperdentry) // returns NULL IS_POSIXACL(realinode) // NULL pointer dereference , will trigger an null pointer dereference at realinode: [ 205.472797] BUG: kernel NULL pointer dereference, address: 0000000000000028 [ 205.476701] CPU: 2 PID: 2713 Comm: ls Not tainted 6.3.0-12064-g2edfa098e750-dirty #1216 [ 205.478754] RIP: 0010:do_ovl_get_acl+0x5d/0x300 [ 205.489584] Call Trace: [ 205.489812] <TASK> [ 205.490014] ovl_get_inode_acl+0x26/0x30 [ 205.490466] get_cached_acl_rcu+0x61/0xa0 [ 205.490908] generic_permission+0x1bf/0x4e0 [ 205.491447] ovl_permission+0x79/0x1b0 [ 205.491917] inode_permission+0x15e/0x2c0 [ 205.492425] link_path_walk+0x115/0x550 [ 205.493311] path_lookupat.isra.0+0xb2/0x200 [ 205.493803] filename_lookup+0xda/0x240 [ 205.495747] vfs_fstatat+0x7b/0xb0
Fetch a reproducer in [Link].
Use the helper ovl_i_path_realinode() to get realinode and then do non-nullptr checking.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217404 Fixes: 332f606b32b6 ("ovl: enable RCU'd ->get_acl()") Cc: stable@vger.kernel.org # v5.15 Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com Suggested-by: Christian Brauner brauner@kernel.org Suggested-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/overlayfs/inode.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
--- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -453,7 +453,15 @@ struct posix_acl *ovl_get_acl(struct ino const struct cred *old_cred; struct posix_acl *acl;
- if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !IS_POSIXACL(realinode)) + if (!IS_ENABLED(CONFIG_FS_POSIX_ACL)) + return NULL; + + if (!realinode) { + WARN_ON(!rcu); + return ERR_PTR(-ECHILD); + } + + if (!IS_POSIXACL(realinode)) return NULL;
if (rcu)
From: Amir Goldstein amir73il@gmail.com
commit 69562eb0bd3e6bb8e522a7b254334e0fb30dff0c upstream.
Hopefully, nobody is trying to abuse mount/sb marks for watching all anonymous pipes/inodes.
I cannot think of a good reason to allow this - it looks like an oversight that dated back to the original fanotify API.
Link: https://lore.kernel.org/linux-fsdevel/20230628101132.kvchg544mczxv2pm@quack3... Fixes: 0ff21db9fcc3 ("fanotify: hooks the fanotify_mark syscall to the vfsmount code") Signed-off-by: Amir Goldstein amir73il@gmail.com Reviewed-by: Christian Brauner brauner@kernel.org Signed-off-by: Jan Kara jack@suse.cz Message-Id: 20230629042044.25723-1-amir73il@gmail.com [backport to 5.x.y] Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/notify/fanotify/fanotify_user.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
--- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1337,8 +1337,11 @@ static int fanotify_test_fid(struct path return 0; }
-static int fanotify_events_supported(struct path *path, __u64 mask) +static int fanotify_events_supported(struct path *path, __u64 mask, + unsigned int flags) { + unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS; + /* * Some filesystems such as 'proc' acquire unusual locks when opening * files. For them fanotify permission events have high chances of @@ -1350,6 +1353,21 @@ static int fanotify_events_supported(str if (mask & FANOTIFY_PERM_EVENTS && path->mnt->mnt_sb->s_type->fs_flags & FS_DISALLOW_NOTIFY_PERM) return -EINVAL; + + /* + * mount and sb marks are not allowed on kernel internal pseudo fs, + * like pipe_mnt, because that would subscribe to events on all the + * anonynous pipes in the system. + * + * SB_NOUSER covers all of the internal pseudo fs whose objects are not + * exposed to user's mount namespace, but there are other SB_KERNMOUNT + * fs, like nsfs, debugfs, for which the value of allowing sb and mount + * mark is questionable. For now we leave them alone. + */ + if (mark_type != FAN_MARK_INODE && + path->mnt->mnt_sb->s_flags & SB_NOUSER) + return -EINVAL; + return 0; }
@@ -1476,7 +1494,7 @@ static int do_fanotify_mark(int fanotify goto fput_and_out;
if (flags & FAN_MARK_ADD) { - ret = fanotify_events_supported(&path, mask); + ret = fanotify_events_supported(&path, mask, flags); if (ret) goto path_put_and_out; }
From: Pablo Neira Ayuso pablo@netfilter.org
commit 3e70489721b6c870252c9082c496703677240f53 upstream.
Otherwise a dangling reference to a rule object that is gone remains in the set binding list.
Fixes: 26b5a5712eb8 ("netfilter: nf_tables: add NFT_TRANS_PREPARE_ERROR to deal with bound set/chain") Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netfilter/nf_tables_api.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -5042,6 +5042,8 @@ void nf_tables_deactivate_set(const stru nft_set_trans_unbind(ctx, set); if (nft_set_is_anonymous(set)) nft_deactivate_next(ctx->net, set); + else + list_del_rcu(&binding->list);
set->use--; break;
From: Florent Revest revest@chromium.org
commit 6eef7a2b933885a17679eb8ed0796ddf0ee5309b upstream.
If nf_conntrack_init_start() fails (for example due to a register_nf_conntrack_bpf() failure), the nf_conntrack_helper_fini() clean-up path frees the nf_ct_helper_hash map.
When built with NF_CONNTRACK=y, further netfilter modules (e.g: netfilter_conntrack_ftp) can still be loaded and call nf_conntrack_helpers_register(), independently of whether nf_conntrack initialized correctly. This accesses the nf_ct_helper_hash dangling pointer and causes a uaf, possibly leading to random memory corruption.
This patch guards nf_conntrack_helper_register() from accessing a freed or uninitialized nf_ct_helper_hash pointer and fixes possible uses-after-free when loading a conntrack module.
Cc: stable@vger.kernel.org Fixes: 12f7a505331e ("netfilter: add user-space connection tracking helper infrastructure") Signed-off-by: Florent Revest revest@chromium.org Reviewed-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netfilter/nf_conntrack_helper.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -405,6 +405,9 @@ int nf_conntrack_helper_register(struct BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES); BUG_ON(strlen(me->name) > NF_CT_HELPER_NAME_LEN - 1);
+ if (!nf_ct_helper_hash) + return -ENOENT; + if (me->expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT) return -EINVAL;
@@ -595,4 +598,5 @@ void nf_conntrack_helper_fini(void) { nf_ct_extend_unregister(&helper_extend); kvfree(nf_ct_helper_hash); + nf_ct_helper_hash = NULL; }
From: Thadeu Lima de Souza Cascardo cascardo@canonical.com
commit 515ad530795c118f012539ed76d02bacfd426d89 upstream.
When adding a rule to a chain referring to its ID, if that chain had been deleted on the same batch, the rule might end up referring to a deleted chain.
This will lead to a WARNING like following:
[ 33.098431] ------------[ cut here ]------------ [ 33.098678] WARNING: CPU: 5 PID: 69 at net/netfilter/nf_tables_api.c:2037 nf_tables_chain_destroy+0x23d/0x260 [ 33.099217] Modules linked in: [ 33.099388] CPU: 5 PID: 69 Comm: kworker/5:1 Not tainted 6.4.0+ #409 [ 33.099726] Workqueue: events nf_tables_trans_destroy_work [ 33.100018] RIP: 0010:nf_tables_chain_destroy+0x23d/0x260 [ 33.100306] Code: 8b 7c 24 68 e8 64 9c ed fe 4c 89 e7 e8 5c 9c ed fe 48 83 c4 08 5b 41 5c 41 5d 41 5e 41 5f 5d 31 c0 89 c6 89 c7 c3 cc cc cc cc <0f> 0b 48 83 c4 08 5b 41 5c 41 5d 41 5e 41 5f 5d 31 c0 89 c6 89 c7 [ 33.101271] RSP: 0018:ffffc900004ffc48 EFLAGS: 00010202 [ 33.101546] RAX: 0000000000000001 RBX: ffff888006fc0a28 RCX: 0000000000000000 [ 33.101920] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [ 33.102649] RBP: ffffc900004ffc78 R08: 0000000000000000 R09: 0000000000000000 [ 33.103018] R10: 0000000000000000 R11: 0000000000000000 R12: ffff8880135ef500 [ 33.103385] R13: 0000000000000000 R14: dead000000000122 R15: ffff888006fc0a10 [ 33.103762] FS: 0000000000000000(0000) GS:ffff888024c80000(0000) knlGS:0000000000000000 [ 33.104184] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 33.104493] CR2: 00007fe863b56a50 CR3: 00000000124b0001 CR4: 0000000000770ee0 [ 33.104872] PKRU: 55555554 [ 33.104999] Call Trace: [ 33.105113] <TASK> [ 33.105214] ? show_regs+0x72/0x90 [ 33.105371] ? __warn+0xa5/0x210 [ 33.105520] ? nf_tables_chain_destroy+0x23d/0x260 [ 33.105732] ? report_bug+0x1f2/0x200 [ 33.105902] ? handle_bug+0x46/0x90 [ 33.106546] ? exc_invalid_op+0x19/0x50 [ 33.106762] ? asm_exc_invalid_op+0x1b/0x20 [ 33.106995] ? nf_tables_chain_destroy+0x23d/0x260 [ 33.107249] ? nf_tables_chain_destroy+0x30/0x260 [ 33.107506] nf_tables_trans_destroy_work+0x669/0x680 [ 33.107782] ? mark_held_locks+0x28/0xa0 [ 33.107996] ? __pfx_nf_tables_trans_destroy_work+0x10/0x10 [ 33.108294] ? _raw_spin_unlock_irq+0x28/0x70 [ 33.108538] process_one_work+0x68c/0xb70 [ 33.108755] ? lock_acquire+0x17f/0x420 [ 33.108977] ? __pfx_process_one_work+0x10/0x10 [ 33.109218] ? do_raw_spin_lock+0x128/0x1d0 [ 33.109435] ? _raw_spin_lock_irq+0x71/0x80 [ 33.109634] worker_thread+0x2bd/0x700 [ 33.109817] ? __pfx_worker_thread+0x10/0x10 [ 33.110254] kthread+0x18b/0x1d0 [ 33.110410] ? __pfx_kthread+0x10/0x10 [ 33.110581] ret_from_fork+0x29/0x50 [ 33.110757] </TASK> [ 33.110866] irq event stamp: 1651 [ 33.111017] hardirqs last enabled at (1659): [<ffffffffa206a209>] __up_console_sem+0x79/0xa0 [ 33.111379] hardirqs last disabled at (1666): [<ffffffffa206a1ee>] __up_console_sem+0x5e/0xa0 [ 33.111740] softirqs last enabled at (1616): [<ffffffffa1f5d40e>] __irq_exit_rcu+0x9e/0xe0 [ 33.112094] softirqs last disabled at (1367): [<ffffffffa1f5d40e>] __irq_exit_rcu+0x9e/0xe0 [ 33.112453] ---[ end trace 0000000000000000 ]---
This is due to the nft_chain_lookup_byid ignoring the genmask. After this change, adding the new rule will fail as it will not find the chain.
Fixes: 837830a4b439 ("netfilter: nf_tables: add NFTA_RULE_CHAIN_ID attribute") Cc: stable@vger.kernel.org Reported-by: Mingi Cho of Theori working with ZDI Signed-off-by: Thadeu Lima de Souza Cascardo cascardo@canonical.com Reviewed-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netfilter/nf_tables_api.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
--- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -2533,7 +2533,7 @@ err:
static struct nft_chain *nft_chain_lookup_byid(const struct net *net, const struct nft_table *table, - const struct nlattr *nla) + const struct nlattr *nla, u8 genmask) { struct nftables_pernet *nft_net = nft_pernet(net); u32 id = ntohl(nla_get_be32(nla)); @@ -2544,7 +2544,8 @@ static struct nft_chain *nft_chain_looku
if (trans->msg_type == NFT_MSG_NEWCHAIN && chain->table == table && - id == nft_trans_chain_id(trans)) + id == nft_trans_chain_id(trans) && + nft_active_genmask(chain, genmask)) return chain; } return ERR_PTR(-ENOENT); @@ -3532,7 +3533,8 @@ static int nf_tables_newrule(struct sk_b return -EOPNOTSUPP;
} else if (nla[NFTA_RULE_CHAIN_ID]) { - chain = nft_chain_lookup_byid(net, table, nla[NFTA_RULE_CHAIN_ID]); + chain = nft_chain_lookup_byid(net, table, nla[NFTA_RULE_CHAIN_ID], + genmask); if (IS_ERR(chain)) { NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN_ID]); return PTR_ERR(chain); @@ -9931,7 +9933,8 @@ static int nft_verdict_init(const struct genmask); } else if (tb[NFTA_VERDICT_CHAIN_ID]) { chain = nft_chain_lookup_byid(ctx->net, ctx->table, - tb[NFTA_VERDICT_CHAIN_ID]); + tb[NFTA_VERDICT_CHAIN_ID], + genmask); if (IS_ERR(chain)) return PTR_ERR(chain); } else {
From: Thadeu Lima de Souza Cascardo cascardo@canonical.com
commit caf3ef7468f7534771b5c44cd8dbd6f7f87c2cbd upstream.
When evaluating byteorder expressions with size 2, a union with 32-bit and 16-bit members is used. Since the 16-bit members are aligned to 32-bit, the array accesses will be out-of-bounds.
It may lead to a stack-out-of-bounds access like the one below:
[ 23.095215] ================================================================== [ 23.095625] BUG: KASAN: stack-out-of-bounds in nft_byteorder_eval+0x13c/0x320 [ 23.096020] Read of size 2 at addr ffffc90000007948 by task ping/115 [ 23.096358] [ 23.096456] CPU: 0 PID: 115 Comm: ping Not tainted 6.4.0+ #413 [ 23.096770] Call Trace: [ 23.096910] <IRQ> [ 23.097030] dump_stack_lvl+0x60/0xc0 [ 23.097218] print_report+0xcf/0x630 [ 23.097388] ? nft_byteorder_eval+0x13c/0x320 [ 23.097577] ? kasan_addr_to_slab+0xd/0xc0 [ 23.097760] ? nft_byteorder_eval+0x13c/0x320 [ 23.097949] kasan_report+0xc9/0x110 [ 23.098106] ? nft_byteorder_eval+0x13c/0x320 [ 23.098298] __asan_load2+0x83/0xd0 [ 23.098453] nft_byteorder_eval+0x13c/0x320 [ 23.098659] nft_do_chain+0x1c8/0xc50 [ 23.098852] ? __pfx_nft_do_chain+0x10/0x10 [ 23.099078] ? __kasan_check_read+0x11/0x20 [ 23.099295] ? __pfx___lock_acquire+0x10/0x10 [ 23.099535] ? __pfx___lock_acquire+0x10/0x10 [ 23.099745] ? __kasan_check_read+0x11/0x20 [ 23.099929] nft_do_chain_ipv4+0xfe/0x140 [ 23.100105] ? __pfx_nft_do_chain_ipv4+0x10/0x10 [ 23.100327] ? lock_release+0x204/0x400 [ 23.100515] ? nf_hook.constprop.0+0x340/0x550 [ 23.100779] nf_hook_slow+0x6c/0x100 [ 23.100977] ? __pfx_nft_do_chain_ipv4+0x10/0x10 [ 23.101223] nf_hook.constprop.0+0x334/0x550 [ 23.101443] ? __pfx_ip_local_deliver_finish+0x10/0x10 [ 23.101677] ? __pfx_nf_hook.constprop.0+0x10/0x10 [ 23.101882] ? __pfx_ip_rcv_finish+0x10/0x10 [ 23.102071] ? __pfx_ip_local_deliver_finish+0x10/0x10 [ 23.102291] ? rcu_read_lock_held+0x4b/0x70 [ 23.102481] ip_local_deliver+0xbb/0x110 [ 23.102665] ? __pfx_ip_rcv+0x10/0x10 [ 23.102839] ip_rcv+0x199/0x2a0 [ 23.102980] ? __pfx_ip_rcv+0x10/0x10 [ 23.103140] __netif_receive_skb_one_core+0x13e/0x150 [ 23.103362] ? __pfx___netif_receive_skb_one_core+0x10/0x10 [ 23.103647] ? mark_held_locks+0x48/0xa0 [ 23.103819] ? process_backlog+0x36c/0x380 [ 23.103999] __netif_receive_skb+0x23/0xc0 [ 23.104179] process_backlog+0x91/0x380 [ 23.104350] __napi_poll.constprop.0+0x66/0x360 [ 23.104589] ? net_rx_action+0x1cb/0x610 [ 23.104811] net_rx_action+0x33e/0x610 [ 23.105024] ? _raw_spin_unlock+0x23/0x50 [ 23.105257] ? __pfx_net_rx_action+0x10/0x10 [ 23.105485] ? mark_held_locks+0x48/0xa0 [ 23.105741] __do_softirq+0xfa/0x5ab [ 23.105956] ? __dev_queue_xmit+0x765/0x1c00 [ 23.106193] do_softirq.part.0+0x49/0xc0 [ 23.106423] </IRQ> [ 23.106547] <TASK> [ 23.106670] __local_bh_enable_ip+0xf5/0x120 [ 23.106903] __dev_queue_xmit+0x789/0x1c00 [ 23.107131] ? __pfx___dev_queue_xmit+0x10/0x10 [ 23.107381] ? find_held_lock+0x8e/0xb0 [ 23.107585] ? lock_release+0x204/0x400 [ 23.107798] ? neigh_resolve_output+0x185/0x350 [ 23.108049] ? mark_held_locks+0x48/0xa0 [ 23.108265] ? neigh_resolve_output+0x185/0x350 [ 23.108514] neigh_resolve_output+0x246/0x350 [ 23.108753] ? neigh_resolve_output+0x246/0x350 [ 23.109003] ip_finish_output2+0x3c3/0x10b0 [ 23.109250] ? __pfx_ip_finish_output2+0x10/0x10 [ 23.109510] ? __pfx_nf_hook+0x10/0x10 [ 23.109732] __ip_finish_output+0x217/0x390 [ 23.109978] ip_finish_output+0x2f/0x130 [ 23.110207] ip_output+0xc9/0x170 [ 23.110404] ip_push_pending_frames+0x1a0/0x240 [ 23.110652] raw_sendmsg+0x102e/0x19e0 [ 23.110871] ? __pfx_raw_sendmsg+0x10/0x10 [ 23.111093] ? lock_release+0x204/0x400 [ 23.111304] ? __mod_lruvec_page_state+0x148/0x330 [ 23.111567] ? find_held_lock+0x8e/0xb0 [ 23.111777] ? find_held_lock+0x8e/0xb0 [ 23.111993] ? __rcu_read_unlock+0x7c/0x2f0 [ 23.112225] ? aa_sk_perm+0x18a/0x550 [ 23.112431] ? filemap_map_pages+0x4f1/0x900 [ 23.112665] ? __pfx_aa_sk_perm+0x10/0x10 [ 23.112880] ? find_held_lock+0x8e/0xb0 [ 23.113098] inet_sendmsg+0xa0/0xb0 [ 23.113297] ? inet_sendmsg+0xa0/0xb0 [ 23.113500] ? __pfx_inet_sendmsg+0x10/0x10 [ 23.113727] sock_sendmsg+0xf4/0x100 [ 23.113924] ? move_addr_to_kernel.part.0+0x4f/0xa0 [ 23.114190] __sys_sendto+0x1d4/0x290 [ 23.114391] ? __pfx___sys_sendto+0x10/0x10 [ 23.114621] ? __pfx_mark_lock.part.0+0x10/0x10 [ 23.114869] ? lock_release+0x204/0x400 [ 23.115076] ? find_held_lock+0x8e/0xb0 [ 23.115287] ? rcu_is_watching+0x23/0x60 [ 23.115503] ? __rseq_handle_notify_resume+0x6e2/0x860 [ 23.115778] ? __kasan_check_write+0x14/0x30 [ 23.116008] ? blkcg_maybe_throttle_current+0x8d/0x770 [ 23.116285] ? mark_held_locks+0x28/0xa0 [ 23.116503] ? do_syscall_64+0x37/0x90 [ 23.116713] __x64_sys_sendto+0x7f/0xb0 [ 23.116924] do_syscall_64+0x59/0x90 [ 23.117123] ? irqentry_exit_to_user_mode+0x25/0x30 [ 23.117387] ? irqentry_exit+0x77/0xb0 [ 23.117593] ? exc_page_fault+0x92/0x140 [ 23.117806] entry_SYSCALL_64_after_hwframe+0x6e/0xd8 [ 23.118081] RIP: 0033:0x7f744aee2bba [ 23.118282] Code: d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 f3 0f 1e fa 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 15 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 7e c3 0f 1f 44 00 00 41 54 48 83 ec 30 44 89 [ 23.119237] RSP: 002b:00007ffd04a7c9f8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c [ 23.119644] RAX: ffffffffffffffda RBX: 00007ffd04a7e0a0 RCX: 00007f744aee2bba [ 23.120023] RDX: 0000000000000040 RSI: 000056488e9e6300 RDI: 0000000000000003 [ 23.120413] RBP: 000056488e9e6300 R08: 00007ffd04a80320 R09: 0000000000000010 [ 23.120809] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000040 [ 23.121219] R13: 00007ffd04a7dc38 R14: 00007ffd04a7ca00 R15: 00007ffd04a7e0a0 [ 23.121617] </TASK> [ 23.121749] [ 23.121845] The buggy address belongs to the virtual mapping at [ 23.121845] [ffffc90000000000, ffffc90000009000) created by: [ 23.121845] irq_init_percpu_irqstack+0x1cf/0x270 [ 23.122707] [ 23.122803] The buggy address belongs to the physical page: [ 23.123104] page:0000000072ac19f0 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x24a09 [ 23.123609] flags: 0xfffffc0001000(reserved|node=0|zone=1|lastcpupid=0x1fffff) [ 23.123998] page_type: 0xffffffff() [ 23.124194] raw: 000fffffc0001000 ffffea0000928248 ffffea0000928248 0000000000000000 [ 23.124610] raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000 [ 23.125023] page dumped because: kasan: bad access detected [ 23.125326] [ 23.125421] Memory state around the buggy address: [ 23.125682] ffffc90000007800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 23.126072] ffffc90000007880: 00 00 00 00 00 f1 f1 f1 f1 f1 f1 00 00 f2 f2 00 [ 23.126455] >ffffc90000007900: 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2 00 00 00 [ 23.126840] ^ [ 23.127138] ffffc90000007980: 00 00 00 00 00 00 00 00 00 00 00 00 00 f3 f3 f3 [ 23.127522] ffffc90000007a00: f3 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 [ 23.127906] ================================================================== [ 23.128324] Disabling lock debugging due to kernel taint
Using simple s16 pointers for the 16-bit accesses fixes the problem. For the 32-bit accesses, src and dst can be used directly.
Fixes: 96518518cc41 ("netfilter: add nftables") Cc: stable@vger.kernel.org Reported-by: Tanguy DUBROCA (@SidewayRE) from @Synacktiv working with ZDI Signed-off-by: Thadeu Lima de Souza Cascardo cascardo@canonical.com Reviewed-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netfilter/nft_byteorder.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
--- a/net/netfilter/nft_byteorder.c +++ b/net/netfilter/nft_byteorder.c @@ -30,11 +30,11 @@ void nft_byteorder_eval(const struct nft const struct nft_byteorder *priv = nft_expr_priv(expr); u32 *src = ®s->data[priv->sreg]; u32 *dst = ®s->data[priv->dreg]; - union { u32 u32; u16 u16; } *s, *d; + u16 *s16, *d16; unsigned int i;
- s = (void *)src; - d = (void *)dst; + s16 = (void *)src; + d16 = (void *)dst;
switch (priv->size) { case 8: { @@ -61,11 +61,11 @@ void nft_byteorder_eval(const struct nft switch (priv->op) { case NFT_BYTEORDER_NTOH: for (i = 0; i < priv->len / 4; i++) - d[i].u32 = ntohl((__force __be32)s[i].u32); + dst[i] = ntohl((__force __be32)src[i]); break; case NFT_BYTEORDER_HTON: for (i = 0; i < priv->len / 4; i++) - d[i].u32 = (__force __u32)htonl(s[i].u32); + dst[i] = (__force __u32)htonl(src[i]); break; } break; @@ -73,11 +73,11 @@ void nft_byteorder_eval(const struct nft switch (priv->op) { case NFT_BYTEORDER_NTOH: for (i = 0; i < priv->len / 2; i++) - d[i].u16 = ntohs((__force __be16)s[i].u16); + d16[i] = ntohs((__force __be16)s16[i]); break; case NFT_BYTEORDER_HTON: for (i = 0; i < priv->len / 2; i++) - d[i].u16 = (__force __u16)htons(s[i].u16); + d16[i] = (__force __u16)htons(s16[i]); break; } break;
From: Jason A. Donenfeld Jason@zx2c4.com
commit 7387943fa35516f6f8017a3b0e9ce48a3bef9faa upstream.
Using `% nr_cpumask_bits` is slow and complicated, and not totally robust toward dynamic changes to CPU topologies. Rather than storing the next CPU in the round-robin, just store the last one, and also return that value. This simplifies the loop drastically into a much more common pattern.
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel") Cc: stable@vger.kernel.org Reported-by: Linus Torvalds torvalds@linux-foundation.org Tested-by: Manuel Leiner manuel.leiner@gmx.de Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireguard/queueing.c | 1 + drivers/net/wireguard/queueing.h | 25 +++++++++++-------------- drivers/net/wireguard/receive.c | 2 +- drivers/net/wireguard/send.c | 2 +- 4 files changed, 14 insertions(+), 16 deletions(-)
--- a/drivers/net/wireguard/queueing.c +++ b/drivers/net/wireguard/queueing.c @@ -28,6 +28,7 @@ int wg_packet_queue_init(struct crypt_qu int ret;
memset(queue, 0, sizeof(*queue)); + queue->last_cpu = -1; ret = ptr_ring_init(&queue->ring, len, GFP_KERNEL); if (ret) return ret; --- a/drivers/net/wireguard/queueing.h +++ b/drivers/net/wireguard/queueing.h @@ -119,20 +119,17 @@ static inline int wg_cpumask_choose_onli return cpu; }
-/* This function is racy, in the sense that next is unlocked, so it could return - * the same CPU twice. A race-free version of this would be to instead store an - * atomic sequence number, do an increment-and-return, and then iterate through - * every possible CPU until we get to that index -- choose_cpu. However that's - * a bit slower, and it doesn't seem like this potential race actually - * introduces any performance loss, so we live with it. +/* This function is racy, in the sense that it's called while last_cpu is + * unlocked, so it could return the same CPU twice. Adding locking or using + * atomic sequence numbers is slower though, and the consequences of racing are + * harmless, so live with it. */ -static inline int wg_cpumask_next_online(int *next) +static inline int wg_cpumask_next_online(int *last_cpu) { - int cpu = *next; - - while (unlikely(!cpumask_test_cpu(cpu, cpu_online_mask))) - cpu = cpumask_next(cpu, cpu_online_mask) % nr_cpumask_bits; - *next = cpumask_next(cpu, cpu_online_mask) % nr_cpumask_bits; + int cpu = cpumask_next(*last_cpu, cpu_online_mask); + if (cpu >= nr_cpu_ids) + cpu = cpumask_first(cpu_online_mask); + *last_cpu = cpu; return cpu; }
@@ -161,7 +158,7 @@ static inline void wg_prev_queue_drop_pe
static inline int wg_queue_enqueue_per_device_and_peer( struct crypt_queue *device_queue, struct prev_queue *peer_queue, - struct sk_buff *skb, struct workqueue_struct *wq, int *next_cpu) + struct sk_buff *skb, struct workqueue_struct *wq) { int cpu;
@@ -175,7 +172,7 @@ static inline int wg_queue_enqueue_per_d /* Then we queue it up in the device queue, which consumes the * packet as soon as it can. */ - cpu = wg_cpumask_next_online(next_cpu); + cpu = wg_cpumask_next_online(&device_queue->last_cpu); if (unlikely(ptr_ring_produce_bh(&device_queue->ring, skb))) return -EPIPE; queue_work_on(cpu, wq, &per_cpu_ptr(device_queue->worker, cpu)->work); --- a/drivers/net/wireguard/receive.c +++ b/drivers/net/wireguard/receive.c @@ -531,7 +531,7 @@ static void wg_packet_consume_data(struc goto err;
ret = wg_queue_enqueue_per_device_and_peer(&wg->decrypt_queue, &peer->rx_queue, skb, - wg->packet_crypt_wq, &wg->decrypt_queue.last_cpu); + wg->packet_crypt_wq); if (unlikely(ret == -EPIPE)) wg_queue_enqueue_per_peer_rx(skb, PACKET_STATE_DEAD); if (likely(!ret || ret == -EPIPE)) { --- a/drivers/net/wireguard/send.c +++ b/drivers/net/wireguard/send.c @@ -318,7 +318,7 @@ static void wg_packet_create_data(struct goto err;
ret = wg_queue_enqueue_per_device_and_peer(&wg->encrypt_queue, &peer->tx_queue, first, - wg->packet_crypt_wq, &wg->encrypt_queue.last_cpu); + wg->packet_crypt_wq); if (unlikely(ret == -EPIPE)) wg_queue_enqueue_per_peer_tx(first, PACKET_STATE_DEAD); err:
From: Jason A. Donenfeld Jason@zx2c4.com
commit f58d0a9b4c6a7a5199c3af967e43cc8b654604d4 upstream.
Packets bound for peers can queue up prior to the device private key being set. For example, if persistent keepalive is set, a packet is queued up to be sent as soon as the device comes up. However, if the private key hasn't been set yet, the handshake message never sends, and no timer is armed to retry, since that would be pointless.
But, if a user later sets a private key, the expectation is that those queued packets, such as a persistent keepalive, are actually sent. So adjust the configuration logic to account for this edge case, and add a test case to make sure this works.
Maxim noticed this with a wg-quick(8) config to the tune of:
[Interface] PostUp = wg set %i private-key somefile
[Peer] PublicKey = ... Endpoint = ... PersistentKeepalive = 25
Here, the private key gets set after the device comes up using a PostUp script, triggering the bug.
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel") Cc: stable@vger.kernel.org Reported-by: Maxim Cournoyer maxim.cournoyer@gmail.com Tested-by: Maxim Cournoyer maxim.cournoyer@gmail.com Link: https://lore.kernel.org/wireguard/87fs7xtqrv.fsf@gmail.com/ Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireguard/netlink.c | 14 ++++++++----- tools/testing/selftests/wireguard/netns.sh | 30 +++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 9 deletions(-)
--- a/drivers/net/wireguard/netlink.c +++ b/drivers/net/wireguard/netlink.c @@ -546,6 +546,7 @@ static int wg_set_device(struct sk_buff u8 *private_key = nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]); u8 public_key[NOISE_PUBLIC_KEY_LEN]; struct wg_peer *peer, *temp; + bool send_staged_packets;
if (!crypto_memneq(wg->static_identity.static_private, private_key, NOISE_PUBLIC_KEY_LEN)) @@ -564,14 +565,17 @@ static int wg_set_device(struct sk_buff }
down_write(&wg->static_identity.lock); - wg_noise_set_static_identity_private_key(&wg->static_identity, - private_key); - list_for_each_entry_safe(peer, temp, &wg->peer_list, - peer_list) { + send_staged_packets = !wg->static_identity.has_identity && netif_running(wg->dev); + wg_noise_set_static_identity_private_key(&wg->static_identity, private_key); + send_staged_packets = send_staged_packets && wg->static_identity.has_identity; + + wg_cookie_checker_precompute_device_keys(&wg->cookie_checker); + list_for_each_entry_safe(peer, temp, &wg->peer_list, peer_list) { wg_noise_precompute_static_static(peer); wg_noise_expire_current_peer_keypairs(peer); + if (send_staged_packets) + wg_packet_send_staged_packets(peer); } - wg_cookie_checker_precompute_device_keys(&wg->cookie_checker); up_write(&wg->static_identity.lock); } skip_set_private_key: --- a/tools/testing/selftests/wireguard/netns.sh +++ b/tools/testing/selftests/wireguard/netns.sh @@ -502,10 +502,32 @@ n2 bash -c 'printf 0 > /proc/sys/net/ipv n1 ping -W 1 -c 1 192.168.241.2 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.3:1" ]]
-ip1 link del veth1 -ip1 link del veth3 -ip1 link del wg0 -ip2 link del wg0 +ip1 link del dev veth3 +ip1 link del dev wg0 +ip2 link del dev wg0 + +# Make sure persistent keep alives are sent when an adapter comes up +ip1 link add dev wg0 type wireguard +n1 wg set wg0 private-key <(echo "$key1") peer "$pub2" endpoint 10.0.0.1:1 persistent-keepalive 1 +read _ _ tx_bytes < <(n1 wg show wg0 transfer) +[[ $tx_bytes -eq 0 ]] +ip1 link set dev wg0 up +read _ _ tx_bytes < <(n1 wg show wg0 transfer) +[[ $tx_bytes -gt 0 ]] +ip1 link del dev wg0 +# This should also happen even if the private key is set later +ip1 link add dev wg0 type wireguard +n1 wg set wg0 peer "$pub2" endpoint 10.0.0.1:1 persistent-keepalive 1 +read _ _ tx_bytes < <(n1 wg show wg0 transfer) +[[ $tx_bytes -eq 0 ]] +ip1 link set dev wg0 up +read _ _ tx_bytes < <(n1 wg show wg0 transfer) +[[ $tx_bytes -eq 0 ]] +n1 wg set wg0 private-key <(echo "$key1") +read _ _ tx_bytes < <(n1 wg show wg0 transfer) +[[ $tx_bytes -gt 0 ]] +ip1 link del dev veth1 +ip1 link del dev wg0
# We test that Netlink/IPC is working properly by doing things that usually cause split responses ip0 link add dev wg0 type wireguard
From: Sherry Sun sherry.sun@nxp.com
commit e0edfdc15863ec80a1d9ac6e174dbccc00206dd0 upstream.
Add earlycon support for imx8ulp platform.
Signed-off-by: Sherry Sun sherry.sun@nxp.com Cc: stable stable@kernel.org Link: https://lore.kernel.org/r/20230619080613.16522-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/fsl_lpuart.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -2632,6 +2632,7 @@ OF_EARLYCON_DECLARE(lpuart, "fsl,vf610-l OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup); OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1028a-lpuart", ls1028a_early_console_setup); OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup); +OF_EARLYCON_DECLARE(lpuart32, "fsl,imx8ulp-lpuart", lpuart32_imx_early_console_setup); OF_EARLYCON_DECLARE(lpuart32, "fsl,imx8qxp-lpuart", lpuart32_imx_early_console_setup); EARLYCON_DECLARE(lpuart, lpuart_early_console_setup); EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup);
From: Michael Schmitz schmitzmic@gmail.com
commit 7eb1e47696aa231b1a567846bbe3a1e1befe1854 upstream.
Making 'blk' sector_t (i.e. 64 bit if LBD support is active) fails the 'blk>0' test in the partition block loop if a value of (signed int) -1 is used to mark the end of the partition block list.
Explicitly cast 'blk' to signed int to allow use of -1 to terminate the partition block linked list.
Fixes: b6f3f28f604b ("block: add overflow checks for Amiga partition support") Reported-by: Christian Zigotzky chzigotzky@xenosoft.de Link: https://lore.kernel.org/r/024ce4fa-cc6d-50a2-9aae-3701d0ebf668@xenosoft.de Signed-off-by: Michael Schmitz schmitzmic@gmail.com Reviewed-by: Martin Steigerwald martin@lichtvoll.de Tested-by: Christian Zigotzky chzigotzky@xenosoft.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/partitions/amiga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/block/partitions/amiga.c +++ b/block/partitions/amiga.c @@ -90,7 +90,7 @@ int amiga_partition(struct parsed_partit } blk = be32_to_cpu(rdb->rdb_PartitionList); put_dev_sector(sect); - for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) { + for (part = 1; (s32) blk>0 && part<=16; part++, put_dev_sector(sect)) { /* Read in terms partition table understands */ if (check_mul_overflow(blk, (sector_t) blksize, &blk)) { pr_err("Dev %s: overflow calculating partition block %llu! Skipping partitions %u and beyond\n",
From: Andres Freund andres@anarazel.de
Commit 8a796565cec3601071cbbd27d6304e202019d014 upstream.
I observed poor performance of io_uring compared to synchronous IO. That turns out to be caused by deeper CPU idle states entered with io_uring, due to io_uring using plain schedule(), whereas synchronous IO uses io_schedule().
The losses due to this are substantial. On my cascade lake workstation, t/io_uring from the fio repository e.g. yields regressions between 20% and 40% with the following command: ./t/io_uring -r 5 -X0 -d 1 -s 1 -c 1 -p 0 -S$use_sync -R 0 /mnt/t2/fio/write.0.0
This is repeatable with different filesystems, using raw block devices and using different block devices.
Use io_schedule_prepare() / io_schedule_finish() in io_cqring_wait_schedule() to address the difference.
After that using io_uring is on par or surpassing synchronous IO (using registered files etc makes it reliably win, but arguably is a less fair comparison).
There are other calls to schedule() in io_uring/, but none immediately jump out to be similarly situated, so I did not touch them. Similarly, it's possible that mutex_lock_io() should be used, but it's not clear if there are cases where that matters.
Cc: stable@vger.kernel.org # 5.10+ Cc: Pavel Begunkov asml.silence@gmail.com Cc: io-uring@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Andres Freund andres@anarazel.de Link: https://lore.kernel.org/r/20230707162007.194068-1-andres@anarazel.de [axboe: minor style fixup] Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- io_uring/io_uring.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
--- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -7796,7 +7796,7 @@ static inline int io_cqring_wait_schedul struct io_wait_queue *iowq, ktime_t *timeout) { - int ret; + int token, ret;
/* make sure we run task_work before checking for signals */ ret = io_run_task_work_sig(); @@ -7806,9 +7806,17 @@ static inline int io_cqring_wait_schedul if (test_bit(0, &ctx->check_cq_overflow)) return 1;
+ /* + * Use io_schedule_prepare/finish, so cpufreq can take into account + * that the task is waiting for IO - turns out to be important for low + * QD IO. + */ + token = io_schedule_prepare(); + ret = 1; if (!schedule_hrtimeout(timeout, HRTIMER_MODE_ABS)) - return -ETIME; - return 1; + ret = -ETIME; + io_schedule_finish(token); + return ret; }
/*
From: Jens Axboe axboe@kernel.dk
Commit f58680085478dd292435727210122960d38e8014 upstream.
If CONFIG_PREEMPT_NONE is set and the task_work chains are long, we could be running into issues blocking others for too long. Add a reschedule check in handle_tw_list(), and flush the ctx if we need to reschedule.
Cc: stable@vger.kernel.org # 5.10+ Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- io_uring/io_uring.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -2217,9 +2217,12 @@ static void tctx_task_work(struct callba } req->io_task_work.func(req, &locked); node = next; + if (unlikely(need_resched())) { + ctx_flush_and_put(ctx, &locked); + ctx = NULL; + cond_resched(); + } } while (node); - - cond_resched(); }
ctx_flush_and_put(ctx, &locked);
From: Moritz Fischer moritzf@google.com
commit 7a8227b2e76be506b2ac64d2beac950ca04892a5 upstream.
dev_set_rx_mode() grabs a spin_lock, and the lan743x implementation proceeds subsequently to go to sleep using readx_poll_timeout().
Introduce a helper wrapping the readx_poll_timeout_atomic() function and use it to replace the calls to readx_polL_timeout().
Fixes: 23f0703c125b ("lan743x: Add main source files for new lan743x driver") Cc: stable@vger.kernel.org Cc: Bryan Whitehead bryan.whitehead@microchip.com Cc: UNGLinuxDriver@microchip.com Signed-off-by: Moritz Fischer moritzf@google.com Reviewed-by: Andrew Lunn andrew@lunn.ch Link: https://lore.kernel.org/r/20230627035000.1295254-1-moritzf@google.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/microchip/lan743x_main.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/microchip/lan743x_main.c +++ b/drivers/net/ethernet/microchip/lan743x_main.c @@ -83,6 +83,18 @@ static int lan743x_csr_light_reset(struc !(data & HW_CFG_LRST_), 100000, 10000000); }
+static int lan743x_csr_wait_for_bit_atomic(struct lan743x_adapter *adapter, + int offset, u32 bit_mask, + int target_value, int udelay_min, + int udelay_max, int count) +{ + u32 data; + + return readx_poll_timeout_atomic(LAN743X_CSR_READ_OP, offset, data, + target_value == !!(data & bit_mask), + udelay_max, udelay_min * count); +} + static int lan743x_csr_wait_for_bit(struct lan743x_adapter *adapter, int offset, u32 bit_mask, int target_value, int usleep_min, @@ -671,8 +683,8 @@ static int lan743x_dp_write(struct lan74 u32 dp_sel; int i;
- if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_, - 1, 40, 100, 100)) + if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL, DP_SEL_DPRDY_, + 1, 40, 100, 100)) return -EIO; dp_sel = lan743x_csr_read(adapter, DP_SEL); dp_sel &= ~DP_SEL_MASK_; @@ -683,8 +695,9 @@ static int lan743x_dp_write(struct lan74 lan743x_csr_write(adapter, DP_ADDR, addr + i); lan743x_csr_write(adapter, DP_DATA_0, buf[i]); lan743x_csr_write(adapter, DP_CMD, DP_CMD_WRITE_); - if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_, - 1, 40, 100, 100)) + if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL, + DP_SEL_DPRDY_, + 1, 40, 100, 100)) return -EIO; }
From: Linus Torvalds torvalds@linux-foundation.org
commit afa4bb778e48d79e4a642ed41e3b4e0de7489a6c upstream.
Dave Airlie reports that gcc-13.1.1 has started complaining about some of the workqueue code in 32-bit arm builds:
kernel/workqueue.c: In function ‘get_work_pwq’: kernel/workqueue.c:713:24: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] 713 | return (void *)(data & WORK_STRUCT_WQ_DATA_MASK); | ^ [ ... a couple of other cases ... ]
and while it's not immediately clear exactly why gcc started complaining about it now, I suspect it's some C23-induced enum type handlign fixup in gcc-13 is the cause.
Whatever the reason for starting to complain, the code and data types are indeed disgusting enough that the complaint is warranted.
The wq code ends up creating various "helper constants" (like that WORK_STRUCT_WQ_DATA_MASK) using an enum type, which is all kinds of confused. The mask needs to be 'unsigned long', not some unspecified enum type.
To make matters worse, the actual "mask and cast to a pointer" is repeated a couple of times, and the cast isn't even always done to the right pointer, but - as the error case above - to a 'void *' with then the compiler finishing the job.
That's now how we roll in the kernel.
So create the masks using the proper types rather than some ambiguous enumeration, and use a nice helper that actually does the type conversion in one well-defined place.
Incidentally, this magically makes clang generate better code. That, admittedly, is really just a sign of clang having been seriously confused before, and cleaning up the typing unconfuses the compiler too.
Reported-by: Dave Airlie airlied@gmail.com Link: https://lore.kernel.org/lkml/CAPM=9twNnV4zMCvrPkw3H-ajZOH-01JVh_kDrxdPYQErz8... Cc: Arnd Bergmann arnd@arndb.de Cc: Tejun Heo tj@kernel.org Cc: Nick Desaulniers ndesaulniers@google.com Cc: Nathan Chancellor nathan@kernel.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/workqueue.h | 15 ++++++++------- kernel/workqueue.c | 13 ++++++++----- 2 files changed, 16 insertions(+), 12 deletions(-)
--- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -68,7 +68,6 @@ enum { WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT,
__WORK_OFFQ_CANCELING = WORK_OFFQ_FLAG_BASE, - WORK_OFFQ_CANCELING = (1 << __WORK_OFFQ_CANCELING),
/* * When a work item is off queue, its high bits point to the last @@ -79,12 +78,6 @@ enum { WORK_OFFQ_POOL_SHIFT = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS, WORK_OFFQ_LEFT = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT, WORK_OFFQ_POOL_BITS = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31, - WORK_OFFQ_POOL_NONE = (1LU << WORK_OFFQ_POOL_BITS) - 1, - - /* convenience constants */ - WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1, - WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK, - WORK_STRUCT_NO_POOL = (unsigned long)WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT,
/* bit mask for work_busy() return values */ WORK_BUSY_PENDING = 1 << 0, @@ -94,6 +87,14 @@ enum { WORKER_DESC_LEN = 24, };
+/* Convenience constants - of type 'unsigned long', not 'enum'! */ +#define WORK_OFFQ_CANCELING (1ul << __WORK_OFFQ_CANCELING) +#define WORK_OFFQ_POOL_NONE ((1ul << WORK_OFFQ_POOL_BITS) - 1) +#define WORK_STRUCT_NO_POOL (WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT) + +#define WORK_STRUCT_FLAG_MASK ((1ul << WORK_STRUCT_FLAG_BITS) - 1) +#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK) + struct work_struct { atomic_long_t data; struct list_head entry; --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -697,12 +697,17 @@ static void clear_work_data(struct work_ set_work_data(work, WORK_STRUCT_NO_POOL, 0); }
+static inline struct pool_workqueue *work_struct_pwq(unsigned long data) +{ + return (struct pool_workqueue *)(data & WORK_STRUCT_WQ_DATA_MASK); +} + static struct pool_workqueue *get_work_pwq(struct work_struct *work) { unsigned long data = atomic_long_read(&work->data);
if (data & WORK_STRUCT_PWQ) - return (void *)(data & WORK_STRUCT_WQ_DATA_MASK); + return work_struct_pwq(data); else return NULL; } @@ -730,8 +735,7 @@ static struct worker_pool *get_work_pool assert_rcu_or_pool_mutex();
if (data & WORK_STRUCT_PWQ) - return ((struct pool_workqueue *) - (data & WORK_STRUCT_WQ_DATA_MASK))->pool; + return work_struct_pwq(data)->pool;
pool_id = data >> WORK_OFFQ_POOL_SHIFT; if (pool_id == WORK_OFFQ_POOL_NONE) @@ -752,8 +756,7 @@ static int get_work_pool_id(struct work_ unsigned long data = atomic_long_read(&work->data);
if (data & WORK_STRUCT_PWQ) - return ((struct pool_workqueue *) - (data & WORK_STRUCT_WQ_DATA_MASK))->pool->id; + return work_struct_pwq(data)->pool->id;
return data >> WORK_OFFQ_POOL_SHIFT; }
From: Ralph Boehme slow@samba.org
commit b83b27909e74d27796de19c802fbc3b65ab4ba9a upstream.
Use ksmbd_req_buf_next() in ksmbd_smb2_check_message().
Cc: Tom Talpey tom@talpey.com Cc: Ronnie Sahlberg ronniesahlberg@gmail.com Cc: Steve French smfrench@gmail.com Cc: Hyunchul Lee hyc.lee@gmail.com Acked-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Ralph Boehme slow@samba.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ksmbd/smb2misc.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
--- a/fs/ksmbd/smb2misc.c +++ b/fs/ksmbd/smb2misc.c @@ -347,16 +347,11 @@ static int smb2_validate_credit_charge(s
int ksmbd_smb2_check_message(struct ksmbd_work *work) { - struct smb2_pdu *pdu = work->request_buf; + struct smb2_pdu *pdu = ksmbd_req_buf_next(work); struct smb2_hdr *hdr = &pdu->hdr; int command; __u32 clc_len; /* calculated length */ - __u32 len = get_rfc1002_len(pdu); - - if (work->next_smb2_rcv_hdr_off) { - pdu = ksmbd_req_buf_next(work); - hdr = &pdu->hdr; - } + __u32 len = get_rfc1002_len(work->request_buf);
if (le32_to_cpu(hdr->NextCommand) > 0) len = le32_to_cpu(hdr->NextCommand);
From: Namjae Jeon linkinjeon@kernel.org
commit 2b9b8f3b68edb3d67d79962f02e26dbb5ae3808d upstream.
->StructureSize2 indicates command payload size. ksmbd should validate this size with rfc1002 length before accessing it. This patch remove unneeded check and add the validation for this.
[ 8.912583] BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message+0x12a/0xc50 [ 8.913051] Read of size 2 at addr ffff88800ac7d92c by task kworker/0:0/7 ... [ 8.914967] Call Trace: [ 8.915126] <TASK> [ 8.915267] dump_stack_lvl+0x33/0x50 [ 8.915506] print_report+0xcc/0x620 [ 8.916558] kasan_report+0xae/0xe0 [ 8.917080] kasan_check_range+0x35/0x1b0 [ 8.917334] ksmbd_smb2_check_message+0x12a/0xc50 [ 8.917935] ksmbd_verify_smb_message+0xae/0xd0 [ 8.918223] handle_ksmbd_work+0x192/0x820 [ 8.918478] process_one_work+0x419/0x760 [ 8.918727] worker_thread+0x2a2/0x6f0 [ 8.919222] kthread+0x187/0x1d0 [ 8.919723] ret_from_fork+0x1f/0x30 [ 8.919954] </TASK>
Cc: stable@vger.kernel.org Reported-by: Chih-Yen Chang cc85nod@gmail.com Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ksmbd/smb2misc.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
--- a/fs/ksmbd/smb2misc.c +++ b/fs/ksmbd/smb2misc.c @@ -352,6 +352,7 @@ int ksmbd_smb2_check_message(struct ksmb int command; __u32 clc_len; /* calculated length */ __u32 len = get_rfc1002_len(work->request_buf); + __u32 req_struct_size;
if (le32_to_cpu(hdr->NextCommand) > 0) len = le32_to_cpu(hdr->NextCommand); @@ -374,17 +375,9 @@ int ksmbd_smb2_check_message(struct ksmb }
if (smb2_req_struct_sizes[command] != pdu->StructureSize2) { - if (command != SMB2_OPLOCK_BREAK_HE && - (hdr->Status == 0 || pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2_LE)) { - /* error packets have 9 byte structure size */ - ksmbd_debug(SMB, - "Illegal request size %u for command %d\n", - le16_to_cpu(pdu->StructureSize2), command); - return 1; - } else if (command == SMB2_OPLOCK_BREAK_HE && - hdr->Status == 0 && - le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_20 && - le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_21) { + if (command == SMB2_OPLOCK_BREAK_HE && + le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_20 && + le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_21) { /* special case for SMB2.1 lease break message */ ksmbd_debug(SMB, "Illegal request size %d for oplock break\n", @@ -393,6 +386,14 @@ int ksmbd_smb2_check_message(struct ksmb } }
+ req_struct_size = le16_to_cpu(pdu->StructureSize2) + + __SMB2_HEADER_STRUCTURE_SIZE; + if (command == SMB2_LOCK_HE) + req_struct_size -= sizeof(struct smb2_lock_element); + + if (req_struct_size > len + 1) + return 1; + if (smb2_calc_size(hdr, &clc_len)) return 1;
From: Namjae Jeon linkinjeon@kernel.org
commit 5fe7f7b78290638806211046a99f031ff26164e1 upstream.
ksmbd_smb2_check_message doesn't validate hdr->NextCommand. If ->NextCommand is bigger than Offset + Length of smb2 write, It will allow oversized smb2 write length. It will cause OOB read in smb2_write.
Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-21164 Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ksmbd/smb2misc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/fs/ksmbd/smb2misc.c +++ b/fs/ksmbd/smb2misc.c @@ -352,10 +352,16 @@ int ksmbd_smb2_check_message(struct ksmb int command; __u32 clc_len; /* calculated length */ __u32 len = get_rfc1002_len(work->request_buf); - __u32 req_struct_size; + __u32 req_struct_size, next_cmd = le32_to_cpu(hdr->NextCommand);
- if (le32_to_cpu(hdr->NextCommand) > 0) - len = le32_to_cpu(hdr->NextCommand); + if ((u64)work->next_smb2_rcv_hdr_off + next_cmd > len) { + pr_err("next command(%u) offset exceeds smb msg size\n", + next_cmd); + return 1; + } + + if (next_cmd > 0) + len = next_cmd; else if (work->next_smb2_rcv_hdr_off) len -= work->next_smb2_rcv_hdr_off;
From: Namjae Jeon linkinjeon@kernel.org
commit 5005bcb4219156f1bf7587b185080ec1da08518e upstream.
This patch validate session id and tree id in compound request. If first operation in the compound is SMB2 ECHO request, ksmbd bypass session and tree validation. So work->sess and work->tcon could be NULL. If secound request in the compound access work->sess or tcon, It cause NULL pointer dereferecing error.
Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-21165 Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ksmbd/server.c | 33 ++++++++++++++++++++------------- fs/ksmbd/smb2pdu.c | 44 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 18 deletions(-)
--- a/fs/ksmbd/server.c +++ b/fs/ksmbd/server.c @@ -184,24 +184,31 @@ static void __handle_ksmbd_work(struct k goto send; }
- if (conn->ops->check_user_session) { - rc = conn->ops->check_user_session(work); - if (rc < 0) { - command = conn->ops->get_cmd_val(work); - conn->ops->set_rsp_status(work, - STATUS_USER_SESSION_DELETED); - goto send; - } else if (rc > 0) { - rc = conn->ops->get_ksmbd_tcon(work); + do { + if (conn->ops->check_user_session) { + rc = conn->ops->check_user_session(work); if (rc < 0) { - conn->ops->set_rsp_status(work, - STATUS_NETWORK_NAME_DELETED); + if (rc == -EINVAL) + conn->ops->set_rsp_status(work, + STATUS_INVALID_PARAMETER); + else + conn->ops->set_rsp_status(work, + STATUS_USER_SESSION_DELETED); goto send; + } else if (rc > 0) { + rc = conn->ops->get_ksmbd_tcon(work); + if (rc < 0) { + if (rc == -EINVAL) + conn->ops->set_rsp_status(work, + STATUS_INVALID_PARAMETER); + else + conn->ops->set_rsp_status(work, + STATUS_NETWORK_NAME_DELETED); + goto send; + } } } - }
- do { rc = __process_request(work, conn, &command); if (rc == SERVER_HANDLER_ABORT) break; --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -97,7 +97,6 @@ int smb2_get_ksmbd_tcon(struct ksmbd_wor struct smb2_hdr *req_hdr = work->request_buf; int tree_id;
- work->tcon = NULL; if (work->conn->ops->get_cmd_val(work) == SMB2_TREE_CONNECT_HE || work->conn->ops->get_cmd_val(work) == SMB2_CANCEL_HE || work->conn->ops->get_cmd_val(work) == SMB2_LOGOFF_HE) { @@ -111,10 +110,28 @@ int smb2_get_ksmbd_tcon(struct ksmbd_wor }
tree_id = le32_to_cpu(req_hdr->Id.SyncId.TreeId); + + /* + * If request is not the first in Compound request, + * Just validate tree id in header with work->tcon->id. + */ + if (work->next_smb2_rcv_hdr_off) { + if (!work->tcon) { + pr_err("The first operation in the compound does not have tcon\n"); + return -EINVAL; + } + if (work->tcon->id != tree_id) { + pr_err("tree id(%u) is different with id(%u) in first operation\n", + tree_id, work->tcon->id); + return -EINVAL; + } + return 1; + } + work->tcon = ksmbd_tree_conn_lookup(work->sess, tree_id); if (!work->tcon) { pr_err("Invalid tid %d\n", tree_id); - return -EINVAL; + return -ENOENT; }
return 1; @@ -569,7 +586,6 @@ int smb2_check_user_session(struct ksmbd unsigned int cmd = conn->ops->get_cmd_val(work); unsigned long long sess_id;
- work->sess = NULL; /* * SMB2_ECHO, SMB2_NEGOTIATE, SMB2_SESSION_SETUP command do not * require a session id, so no need to validate user session's for @@ -580,15 +596,33 @@ int smb2_check_user_session(struct ksmbd return 0;
if (!ksmbd_conn_good(work)) - return -EINVAL; + return -EIO;
sess_id = le64_to_cpu(req_hdr->SessionId); + + /* + * If request is not the first in Compound request, + * Just validate session id in header with work->sess->id. + */ + if (work->next_smb2_rcv_hdr_off) { + if (!work->sess) { + pr_err("The first operation in the compound does not have sess\n"); + return -EINVAL; + } + if (work->sess->id != sess_id) { + pr_err("session id(%llu) is different with the first operation(%lld)\n", + sess_id, work->sess->id); + return -EINVAL; + } + return 1; + } + /* Check for validity of user session */ work->sess = ksmbd_session_lookup_all(conn, sess_id); if (work->sess) return 1; ksmbd_debug(SMB, "Invalid user session, Uid %llu\n", sess_id); - return -EINVAL; + return -ENOENT; }
static void destroy_previous_session(struct ksmbd_conn *conn,
From: Fabio Estevam festevam@denx.de
[ Upstream commit 2c56a751845ddfd3078ebe79981aaaa182629163 ]
The innolux at043tn24 display is a parallel LCD. Pass the 'connector_type' information to avoid the following warning:
panel-simple panel: Specify missing connector_type
Signed-off-by: Fabio Estevam festevam@denx.de Fixes: 41bcceb4de9c ("drm/panel: simple: Add support for Innolux AT043TN24") Reviewed-by: Sam Ravnborg sam@ravnborg.org Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20230620112202.654981-1-festev... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 2f85266cdb2e3..2b628b6be08f3 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2469,6 +2469,7 @@ static const struct panel_desc innolux_at043tn24 = { .height = 54, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .connector_type = DRM_MODE_CONNECTOR_DPI, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, };
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 7aa83fbd712a6f08ffa67890061f26d140c2a84f ]
Memory for the "struct device" for any given device isn't supposed to be released until the device's release() is called. This is important because someone might be holding a kobject reference to the "struct device" and might try to access one of its members even after any other cleanup/uninitialization has happened.
Code analysis of ti-sn65dsi86 shows that this isn't quite right. When the code was written, it was believed that we could rely on the fact that the child devices would all be freed before the parent devices and thus we didn't need to worry about a release() function. While I still believe that the parent's "struct device" is guaranteed to outlive the child's "struct device" (because the child holds a kobject reference to the parent), the parent's "devm" allocated memory is a different story. That appears to be freed much earlier.
Let's make this better for ti-sn65dsi86 by allocating each auxiliary with kzalloc and then free that memory in the release().
Fixes: bf73537f411b ("drm/bridge: ti-sn65dsi86: Break GPIO and MIPI-to-eDP bridge into sub-drivers") Suggested-by: Stephen Boyd swboyd@chromium.org Reviewed-by: Stephen Boyd swboyd@chromium.org Signed-off-by: Douglas Anderson dianders@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20230613065812.v2.1.I24b838a5b... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 33 +++++++++++++++++---------- 1 file changed, 21 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index bbedce0eeddae..22c2ff5272c60 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -147,9 +147,9 @@ * each other's read-modify-write. */ struct ti_sn65dsi86 { - struct auxiliary_device bridge_aux; - struct auxiliary_device gpio_aux; - struct auxiliary_device aux_aux; + struct auxiliary_device *bridge_aux; + struct auxiliary_device *gpio_aux; + struct auxiliary_device *aux_aux;
struct device *dev; struct regmap *regmap; @@ -412,27 +412,34 @@ static void ti_sn65dsi86_delete_aux(void *data) auxiliary_device_delete(data); }
-/* - * AUX bus docs say that a non-NULL release is mandatory, but it makes no - * sense for the model used here where all of the aux devices are allocated - * in the single shared structure. We'll use this noop as a workaround. - */ -static void ti_sn65dsi86_noop(struct device *dev) {} +static void ti_sn65dsi86_aux_device_release(struct device *dev) +{ + struct auxiliary_device *aux = container_of(dev, struct auxiliary_device, dev); + + kfree(aux); +}
static int ti_sn65dsi86_add_aux_device(struct ti_sn65dsi86 *pdata, - struct auxiliary_device *aux, + struct auxiliary_device **aux_out, const char *name) { struct device *dev = pdata->dev; + struct auxiliary_device *aux; int ret;
+ aux = kzalloc(sizeof(*aux), GFP_KERNEL); + if (!aux) + return -ENOMEM; + aux->name = name; aux->dev.parent = dev; - aux->dev.release = ti_sn65dsi86_noop; + aux->dev.release = ti_sn65dsi86_aux_device_release; device_set_of_node_from_dev(&aux->dev, dev); ret = auxiliary_device_init(aux); - if (ret) + if (ret) { + kfree(aux); return ret; + } ret = devm_add_action_or_reset(dev, ti_sn65dsi86_uninit_aux, aux); if (ret) return ret; @@ -441,6 +448,8 @@ static int ti_sn65dsi86_add_aux_device(struct ti_sn65dsi86 *pdata, if (ret) return ret; ret = devm_add_action_or_reset(dev, ti_sn65dsi86_delete_aux, aux); + if (!ret) + *aux_out = aux;
return ret; }
From: Marek Vasut marex@denx.de
[ Upstream commit 1c519980aced3da1fae37c1339cf43b24eccdee7 ]
Add missing drm_display_mode DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC flags. Those are used by various bridges in the pipeline to correctly configure its sync signals polarity.
Fixes: d69de69f2be1 ("drm/panel: simple: Add Powertip PH800480T013 panel") Signed-off-by: Marek Vasut marex@denx.de Reviewed-by: Sam Ravnborg sam@ravnborg.org Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20230615201602.565948-1-marex@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 2b628b6be08f3..391d73d2638a8 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -3651,6 +3651,7 @@ static const struct drm_display_mode powertip_ph800480t013_idf02_mode = { .vsync_start = 480 + 49, .vsync_end = 480 + 49 + 2, .vtotal = 480 + 49 + 2 + 22, + .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, };
static const struct panel_desc powertip_ph800480t013_idf02 = {
From: Muhammad Husaini Zulkifli muhammad.husaini.zulkifli@intel.com
[ Upstream commit cca28ceac7c7857bc2d313777017585aef00bcc4 ]
Remove unnecessary delay during the TX ring configuration. This will cause delay, especially during link down and link up activity.
Furthermore, old SKUs like as I225 will call the reset_adapter to reset the controller during TSN mode Gate Control List (GCL) setting. This will add more time to the configuration of the real-time use case.
It doesn't mentioned about this delay in the Software User Manual. It might have been ported from legacy code I210 in the past.
Fixes: 13b5b7fd6a4a ("igc: Add support for Tx/Rx rings") Signed-off-by: Muhammad Husaini Zulkifli muhammad.husaini.zulkifli@intel.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 Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/igc/igc_main.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index abc63ca9d28bf..e5cbf867034e3 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -708,7 +708,6 @@ static void igc_configure_tx_ring(struct igc_adapter *adapter, /* disable the queue */ wr32(IGC_TXDCTL(reg_idx), 0); wrfl(); - mdelay(10);
wr32(IGC_TDLEN(reg_idx), ring->count * sizeof(union igc_adv_tx_desc));
From: Zhengchao Shao shaozhengchao@huawei.com
[ Upstream commit 884abe45a9014d0de2e6edb0630dfd64f23f1d1b ]
In function accel_fs_tcp_create_groups(), when the ft->g memory is successfully allocated but the 'in' memory fails to be allocated, the memory pointed to by ft->g is released once. And in function accel_fs_tcp_create_table, mlx5e_destroy_flow_table is called to release the memory pointed to by ft->g again. This will cause double free problem.
Fixes: c062d52ac24c ("net/mlx5e: Receive flow steering framework for accelerated TCP flows") Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c index 4c4ee524176c7..153c16e3ff3bf 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c @@ -194,6 +194,7 @@ static int accel_fs_tcp_create_groups(struct mlx5e_flow_table *ft, in = kvzalloc(inlen, GFP_KERNEL); if (!in || !ft->g) { kfree(ft->g); + ft->g = NULL; kvfree(in); return -ENOMEM; }
From: Zhengchao Shao shaozhengchao@huawei.com
[ Upstream commit d543b649ffe58a0cb4b6948b3305069c5980a1fa ]
When kvzalloc_node or kvzalloc failed in mlx5e_ptp_open, the memory pointed by "c" or "cparams" is not freed, which can lead to a memory leak. Fix by freeing the array in the error path.
Fixes: 145e5637d941 ("net/mlx5e: Add TX PTP port object support") Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com Reviewed-by: Rahul Rameshbabu rrameshbabu@nvidia.com Reviewed-by: Gal Pressman gal@nvidia.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c index ee95cc3a03786..ce941e6091c57 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c @@ -676,8 +676,10 @@ int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
c = kvzalloc_node(sizeof(*c), GFP_KERNEL, dev_to_node(mlx5_core_dma_dev(mdev))); cparams = kvzalloc(sizeof(*cparams), GFP_KERNEL); - if (!c || !cparams) - return -ENOMEM; + if (!c || !cparams) { + err = -ENOMEM; + goto err_free; + }
c->priv = priv; c->mdev = priv->mdev;
From: Vlad Buslov vladbu@nvidia.com
[ Upstream commit 65e64640e97c0f223e77f9ea69b5a46186b93470 ]
Currently the check for NOT_READY flag is performed before obtaining the necessary lock. This opens a possibility for race condition when the flow is concurrently removed from unready_flows list by the workqueue task, which causes a double-removal from the list and a crash[0]. Fix the issue by moving the flag check inside the section protected by uplink_priv->unready_flows_lock mutex.
[0]: [44376.389654] general protection fault, probably for non-canonical address 0xdead000000000108: 0000 [#1] SMP [44376.391665] CPU: 7 PID: 59123 Comm: tc Not tainted 6.4.0-rc4+ #1 [44376.392984] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 [44376.395342] RIP: 0010:mlx5e_tc_del_fdb_flow+0xb3/0x340 [mlx5_core] [44376.396857] Code: 00 48 8b b8 68 ce 02 00 e8 8a 4d 02 00 4c 8d a8 a8 01 00 00 4c 89 ef e8 8b 79 88 e1 48 8b 83 98 06 00 00 48 8b 93 90 06 00 00 <48> 89 42 08 48 89 10 48 b8 00 01 00 00 00 00 ad de 48 89 83 90 06 [44376.399167] RSP: 0018:ffff88812cc97570 EFLAGS: 00010246 [44376.399680] RAX: dead000000000122 RBX: ffff8881088e3800 RCX: ffff8881881bac00 [44376.400337] RDX: dead000000000100 RSI: ffff88812cc97500 RDI: ffff8881242f71b0 [44376.401001] RBP: ffff88811cbb0940 R08: 0000000000000400 R09: 0000000000000001 [44376.401663] R10: 0000000000000001 R11: 0000000000000000 R12: ffff88812c944000 [44376.402342] R13: ffff8881242f71a8 R14: ffff8881222b4000 R15: 0000000000000000 [44376.402999] FS: 00007f0451104800(0000) GS:ffff88852cb80000(0000) knlGS:0000000000000000 [44376.403787] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [44376.404343] CR2: 0000000000489108 CR3: 0000000123a79003 CR4: 0000000000370ea0 [44376.405004] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [44376.405665] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [44376.406339] Call Trace: [44376.406651] <TASK> [44376.406939] ? die_addr+0x33/0x90 [44376.407311] ? exc_general_protection+0x192/0x390 [44376.407795] ? asm_exc_general_protection+0x22/0x30 [44376.408292] ? mlx5e_tc_del_fdb_flow+0xb3/0x340 [mlx5_core] [44376.408876] __mlx5e_tc_del_fdb_peer_flow+0xbc/0xe0 [mlx5_core] [44376.409482] mlx5e_tc_del_flow+0x42/0x210 [mlx5_core] [44376.410055] mlx5e_flow_put+0x25/0x50 [mlx5_core] [44376.410529] mlx5e_delete_flower+0x24b/0x350 [mlx5_core] [44376.411043] tc_setup_cb_reoffload+0x22/0x80 [44376.411462] fl_reoffload+0x261/0x2f0 [cls_flower] [44376.411907] ? mlx5e_rep_indr_setup_ft_cb+0x160/0x160 [mlx5_core] [44376.412481] ? mlx5e_rep_indr_setup_ft_cb+0x160/0x160 [mlx5_core] [44376.413044] tcf_block_playback_offloads+0x76/0x170 [44376.413497] tcf_block_unbind+0x7b/0xd0 [44376.413881] tcf_block_setup+0x17d/0x1c0 [44376.414269] tcf_block_offload_cmd.isra.0+0xf1/0x130 [44376.414725] tcf_block_offload_unbind+0x43/0x70 [44376.415153] __tcf_block_put+0x82/0x150 [44376.415532] ingress_destroy+0x22/0x30 [sch_ingress] [44376.415986] qdisc_destroy+0x3b/0xd0 [44376.416343] qdisc_graft+0x4d0/0x620 [44376.416706] tc_get_qdisc+0x1c9/0x3b0 [44376.417074] rtnetlink_rcv_msg+0x29c/0x390 [44376.419978] ? rep_movs_alternative+0x3a/0xa0 [44376.420399] ? rtnl_calcit.isra.0+0x120/0x120 [44376.420813] netlink_rcv_skb+0x54/0x100 [44376.421192] netlink_unicast+0x1f6/0x2c0 [44376.421573] netlink_sendmsg+0x232/0x4a0 [44376.421980] sock_sendmsg+0x38/0x60 [44376.422328] ____sys_sendmsg+0x1d0/0x1e0 [44376.422709] ? copy_msghdr_from_user+0x6d/0xa0 [44376.423127] ___sys_sendmsg+0x80/0xc0 [44376.423495] ? ___sys_recvmsg+0x8b/0xc0 [44376.423869] __sys_sendmsg+0x51/0x90 [44376.424226] do_syscall_64+0x3d/0x90 [44376.424587] entry_SYSCALL_64_after_hwframe+0x46/0xb0 [44376.425046] RIP: 0033:0x7f045134f887 [44376.425403] Code: 0a 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b9 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 89 54 24 1c 48 89 74 24 10 [44376.426914] RSP: 002b:00007ffd63a82b98 EFLAGS: 00000246 ORIG_RAX: 000000000000002e [44376.427592] RAX: ffffffffffffffda RBX: 000000006481955f RCX: 00007f045134f887 [44376.428195] RDX: 0000000000000000 RSI: 00007ffd63a82c00 RDI: 0000000000000003 [44376.428796] RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000 [44376.429404] R10: 00007f0451208708 R11: 0000000000000246 R12: 0000000000000001 [44376.430039] R13: 0000000000409980 R14: 000000000047e538 R15: 0000000000485400 [44376.430644] </TASK> [44376.430907] Modules linked in: mlx5_ib mlx5_core act_mirred act_tunnel_key cls_flower vxlan dummy sch_ingress openvswitch nsh rpcrdma rdma_ucm ib_iser libiscsi scsi_transport_iscsi ib_umad rdma_cm ib_ipoib iw_cm ib_cm ib_uverbs ib_core xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter rpcsec_g ss_krb5 auth_rpcgss oid_registry overlay zram zsmalloc fuse [last unloaded: mlx5_core] [44376.433936] ---[ end trace 0000000000000000 ]--- [44376.434373] RIP: 0010:mlx5e_tc_del_fdb_flow+0xb3/0x340 [mlx5_core] [44376.434951] Code: 00 48 8b b8 68 ce 02 00 e8 8a 4d 02 00 4c 8d a8 a8 01 00 00 4c 89 ef e8 8b 79 88 e1 48 8b 83 98 06 00 00 48 8b 93 90 06 00 00 <48> 89 42 08 48 89 10 48 b8 00 01 00 00 00 00 ad de 48 89 83 90 06 [44376.436452] RSP: 0018:ffff88812cc97570 EFLAGS: 00010246 [44376.436924] RAX: dead000000000122 RBX: ffff8881088e3800 RCX: ffff8881881bac00 [44376.437530] RDX: dead000000000100 RSI: ffff88812cc97500 RDI: ffff8881242f71b0 [44376.438179] RBP: ffff88811cbb0940 R08: 0000000000000400 R09: 0000000000000001 [44376.438786] R10: 0000000000000001 R11: 0000000000000000 R12: ffff88812c944000 [44376.439393] R13: ffff8881242f71a8 R14: ffff8881222b4000 R15: 0000000000000000 [44376.439998] FS: 00007f0451104800(0000) GS:ffff88852cb80000(0000) knlGS:0000000000000000 [44376.440714] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [44376.441225] CR2: 0000000000489108 CR3: 0000000123a79003 CR4: 0000000000370ea0 [44376.441843] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [44376.442471] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Fixes: ad86755b18d5 ("net/mlx5e: Protect unready flows with dedicated lock") Signed-off-by: Vlad Buslov vladbu@nvidia.com Reviewed-by: Roi Dayan roid@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 5cef556223e2c..d123d9b4adf5e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -1282,7 +1282,8 @@ static void remove_unready_flow(struct mlx5e_tc_flow *flow) uplink_priv = &rpriv->uplink_priv;
mutex_lock(&uplink_priv->unready_flows_lock); - unready_flow_del(flow); + if (flow_flag_test(flow, NOT_READY)) + unready_flow_del(flow); mutex_unlock(&uplink_priv->unready_flows_lock); }
@@ -1525,8 +1526,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, esw_attr = attr->esw_attr; mlx5e_put_flow_tunnel_id(flow);
- if (flow_flag_test(flow, NOT_READY)) - remove_unready_flow(flow); + remove_unready_flow(flow);
if (mlx5e_is_offloaded_flow(flow)) { if (flow_flag_test(flow, SLOW))
From: Prasad Koya prasad@arista.com
[ Upstream commit 9ac3fc2f42e5ffa1e927dcbffb71b15fa81459e2 ]
set TP bit in the 'supported' and 'advertising' fields. i225/226 parts only support twisted pair copper.
Fixes: 8c5ad0dae93c ("igc: Add ethtool support") Signed-off-by: Prasad Koya prasad@arista.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 Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/igc/igc_ethtool.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index e0a76ac1bbbcd..859ddc07fbbfe 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -1701,6 +1701,8 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev, /* twisted pair */ cmd->base.port = PORT_TP; cmd->base.phy_address = hw->phy.addr; + ethtool_link_ksettings_add_link_mode(cmd, supported, TP); + ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
/* advertising link modes */ if (hw->phy.autoneg_advertised & ADVERTISE_10_HALF)
From: Aravindhan Gunasekaran aravindhan.gunasekaran@intel.com
[ Upstream commit 84a192e46106355de1a314d709e657231d4b1026 ]
I225/6 hardware can be programmed to start PPS output once the time in Target Time registers is reached. The time programmed in these registers should always be into future. Only then PPS output is triggered when SYSTIM register reaches the programmed value. There are two modes in i225/6 hardware to program PPS, pulse and clock mode.
There were issues reported where PPS is not generated when start time is in past.
Example 1, "echo 0 0 0 2 0 > /sys/class/ptp/ptp0/period"
In the current implementation, a value of '0' is programmed into Target time registers and PPS output is in pulse mode. Eventually an interrupt which is triggered upon SYSTIM register reaching Target time is not fired. Thus no PPS output is generated.
Example 2, "echo 0 0 0 1 0 > /sys/class/ptp/ptp0/period"
Above case, a value of '0' is programmed into Target time registers and PPS output is in clock mode. Here, HW tries to catch-up the current time by incrementing Target Time register. This catch-up time seem to vary according to programmed PPS period time as per the HW design. In my experiments, the delay ranged between few tens of seconds to few minutes. The PPS output is only generated after the Target time register reaches current time.
In my experiments, I also observed PPS stopped working with below test and could not recover until module is removed and loaded again.
1) echo 0 <future time> 0 1 0 > /sys/class/ptp/ptp1/period 2) echo 0 0 0 1 0 > /sys/class/ptp/ptp1/period 3) echo 0 0 0 1 0 > /sys/class/ptp/ptp1/period
After this PPS did not work even if i re-program with proper values. I could only get this back working by reloading the driver.
This patch takes care of calculating and programming appropriate future time value into Target Time registers.
Fixes: 5e91c72e560c ("igc: Fix PPS delta between two synchronized end-points") Signed-off-by: Aravindhan Gunasekaran aravindhan.gunasekaran@intel.com Reviewed-by: Muhammad Husaini Zulkifli muhammad.husaini.zulkifli@intel.com Tested-by: Naama Meir naamax.meir@linux.intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/igc/igc_ptp.c | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c index 6803d91cf71cd..556750b61c98f 100644 --- a/drivers/net/ethernet/intel/igc/igc_ptp.c +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c @@ -357,16 +357,35 @@ static int igc_ptp_feature_enable_i225(struct ptp_clock_info *ptp, tsim &= ~IGC_TSICR_TT0; } if (on) { + struct timespec64 safe_start; int i = rq->perout.index;
igc_pin_perout(igc, i, pin, use_freq); - igc->perout[i].start.tv_sec = rq->perout.start.sec; + igc_ptp_read(igc, &safe_start); + + /* PPS output start time is triggered by Target time(TT) + * register. Programming any past time value into TT + * register will cause PPS to never start. Need to make + * sure we program the TT register a time ahead in + * future. There isn't a stringent need to fire PPS out + * right away. Adding +2 seconds should take care of + * corner cases. Let's say if the SYSTIML is close to + * wrap up and the timer keeps ticking as we program the + * register, adding +2seconds is safe bet. + */ + safe_start.tv_sec += 2; + + if (rq->perout.start.sec < safe_start.tv_sec) + igc->perout[i].start.tv_sec = safe_start.tv_sec; + else + igc->perout[i].start.tv_sec = rq->perout.start.sec; igc->perout[i].start.tv_nsec = rq->perout.start.nsec; igc->perout[i].period.tv_sec = ts.tv_sec; igc->perout[i].period.tv_nsec = ts.tv_nsec; - wr32(trgttimh, rq->perout.start.sec); + wr32(trgttimh, (u32)igc->perout[i].start.tv_sec); /* For now, always select timer 0 as source. */ - wr32(trgttiml, rq->perout.start.nsec | IGC_TT_IO_TIMER_SEL_SYSTIM0); + wr32(trgttiml, (u32)(igc->perout[i].start.tv_nsec | + IGC_TT_IO_TIMER_SEL_SYSTIM0)); if (use_freq) wr32(freqout, ns); tsauxc |= tsauxc_mask;
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit e579b007eff3ff8d29d59d16214cd85fb9e573f7 ]
This should be negative -EAGAIN instead of positive. The callers treat non-zero error codes the same so it doesn't really impact runtime beyond some trivial differences to debug output.
Fixes: 80676d054e5a ("scsi: qla2xxx: Fix session cleanup hang") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Link: https://lore.kernel.org/r/49866d28-4cfe-47b0-842b-78f110e61aab@moroto.mounta... Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_iocb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 4f48f098ea5a6..605e94f973189 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -3898,7 +3898,7 @@ qla2x00_start_sp(srb_t *sp)
pkt = __qla2x00_alloc_iocbs(sp->qpair, sp); if (!pkt) { - rval = EAGAIN; + rval = -EAGAIN; ql_log(ql_log_warn, vha, 0x700c, "qla2x00_alloc_iocbs failed.\n"); goto done;
From: Kumar Kartikeya Dwivedi memxor@gmail.com
[ Upstream commit 5415ccd50a8620c8cbaa32d6f18c946c453566f5 ]
The check_max_stack_depth pass happens after the verifier's symbolic execution, and attempts to walk the call graph of the BPF program, ensuring that the stack usage stays within bounds for all possible call chains. There are two cases to consider: bpf_pseudo_func and bpf_pseudo_call. In the former case, the callback pointer is loaded into a register, and is assumed that it is passed to some helper later which calls it (however there is no way to be sure), but the check remains conservative and accounts the stack usage anyway. For this particular case, asynchronous callbacks are skipped as they execute asynchronously when their corresponding event fires.
The case of bpf_pseudo_call is simpler and we know that the call is definitely made, hence the stack depth of the subprog is accounted for.
However, the current check still skips an asynchronous callback even if a bpf_pseudo_call was made for it. This is erroneous, as it will miss accounting for the stack usage of the asynchronous callback, which can be used to breach the maximum stack depth limit.
Fix this by only skipping asynchronous callbacks when the instruction is not a pseudo call to the subprog.
Fixes: 7ddc80a476c2 ("bpf: Teach stack depth check about async callbacks.") Signed-off-by: Kumar Kartikeya Dwivedi memxor@gmail.com Link: https://lore.kernel.org/r/20230705144730.235802-2-memxor@gmail.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/verifier.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 7a70595c3c15a..bd31aa6407a78 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -3765,8 +3765,9 @@ static int check_max_stack_depth(struct bpf_verifier_env *env) verbose(env, "verifier bug. subprog has tail_call and async cb\n"); return -EFAULT; } - /* async callbacks don't increase bpf prog stack size */ - continue; + /* async callbacks don't increase bpf prog stack size unless called directly */ + if (!bpf_pseudo_call(insn + i)) + continue; } i = next_insn;
From: Klaus Kudielka klaus.kudielka@gmail.com
[ Upstream commit 21327f81db6337c8843ce755b01523c7d3df715b ]
If we boot with mvneta.txq_number=1, the txq_map is set incorrectly: MVNETA_CPU_TXQ_ACCESS(1) refers to TX queue 1, but only TX queue 0 is initialized. Fix this.
Fixes: 50bf8cb6fc9c ("net: mvneta: Configure XPS support") Signed-off-by: Klaus Kudielka klaus.kudielka@gmail.com Reviewed-by: Michal Kubiak michal.kubiak@intel.com Link: https://lore.kernel.org/r/20230705053712.3914-1-klaus.kudielka@gmail.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/marvell/mvneta.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 5c431a3697622..f5b5ae58c2691 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1474,7 +1474,7 @@ static void mvneta_defaults_set(struct mvneta_port *pp) */ if (txq_number == 1) txq_map = (cpu == pp->rxq_def) ? - MVNETA_CPU_TXQ_ACCESS(1) : 0; + MVNETA_CPU_TXQ_ACCESS(0) : 0;
} else { txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK; @@ -4185,7 +4185,7 @@ static void mvneta_percpu_elect(struct mvneta_port *pp) */ if (txq_number == 1) txq_map = (cpu == elected_cpu) ? - MVNETA_CPU_TXQ_ACCESS(1) : 0; + MVNETA_CPU_TXQ_ACCESS(0) : 0; else txq_map = mvreg_read(pp, MVNETA_CPU_MAP(cpu)) & MVNETA_CPU_TXQ_ACCESS_ALL_MASK;
From: M A Ramdhan ramdhan@starlabs.sg
[ Upstream commit 0323bce598eea038714f941ce2b22541c46d488f ]
In the event of a failure in tcf_change_indev(), fw_set_parms() will immediately return an error after incrementing or decrementing reference counter in tcf_bind_filter(). If attacker can control reference counter to zero and make reference freed, leading to use after free.
In order to prevent this, move the point of possible failure above the point where the TC_FW_CLASSID is handled.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: M A Ramdhan ramdhan@starlabs.sg Signed-off-by: M A Ramdhan ramdhan@starlabs.sg Acked-by: Jamal Hadi Salim jhs@mojatatu.com Reviewed-by: Pedro Tammela pctammela@mojatatu.com Message-ID: 20230705161530.52003-1-ramdhan@starlabs.sg Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/cls_fw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 8654b0ce997c1..ea52c320f67c4 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -210,11 +210,6 @@ static int fw_set_parms(struct net *net, struct tcf_proto *tp, if (err < 0) return err;
- if (tb[TCA_FW_CLASSID]) { - f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); - tcf_bind_filter(tp, &f->res, base); - } - if (tb[TCA_FW_INDEV]) { int ret; ret = tcf_change_indev(net, tb[TCA_FW_INDEV], extack); @@ -231,6 +226,11 @@ static int fw_set_parms(struct net *net, struct tcf_proto *tp, } else if (head->mask != 0xFFFFFFFF) return err;
+ if (tb[TCA_FW_CLASSID]) { + f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); + tcf_bind_filter(tp, &f->res, base); + } + return 0; }
From: Junfeng Guo junfeng.guo@intel.com
[ Upstream commit 0503efeadbf6bb8bf24397613a73b67e665eac5f ]
Current duplex mode was unset in the driver, resulting in the default parameter being set to 0, which corresponds to half duplex. It might mislead users to have incorrect expectation about the driver's transmission capabilities. Set the default duplex configuration to full, as the driver runs in full duplex mode at this point.
Fixes: 7e074d5a76ca ("gve: Enable Link Speed Reporting in the driver.") Signed-off-by: Junfeng Guo junfeng.guo@intel.com Reviewed-by: Leon Romanovsky leonro@nvidia.com Message-ID: 20230706044128.2726747-1-junfeng.guo@intel.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/google/gve/gve_ethtool.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c index 6a0663aadd1e9..1f8cc722aae30 100644 --- a/drivers/net/ethernet/google/gve/gve_ethtool.c +++ b/drivers/net/ethernet/google/gve/gve_ethtool.c @@ -532,6 +532,9 @@ static int gve_get_link_ksettings(struct net_device *netdev, err = gve_adminq_report_link_speed(priv);
cmd->base.speed = priv->link_speed; + + cmd->base.duplex = DUPLEX_FULL; + return err; }
From: Nitya Sunkad nitya.sunkad@amd.com
[ Upstream commit abfb2a58a5377ebab717d4362d6180f901b6e5c1 ]
Remove unnecessary early code development check and the WARN_ON that it uses. The irq alloc and free paths have long been cleaned up and this check shouldn't have stuck around so long.
Fixes: 77ceb68e29cc ("ionic: Add notifyq support") Signed-off-by: Nitya Sunkad nitya.sunkad@amd.com Signed-off-by: Shannon Nelson shannon.nelson@amd.com Reviewed-by: Jacob Keller jacob.e.keller@intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 6fbd2a51d66ce..2cc126d378353 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -451,11 +451,6 @@ static void ionic_qcqs_free(struct ionic_lif *lif) static void ionic_link_qcq_interrupts(struct ionic_qcq *src_qcq, struct ionic_qcq *n_qcq) { - if (WARN_ON(n_qcq->flags & IONIC_QCQ_F_INTR)) { - ionic_intr_free(n_qcq->cq.lif->ionic, n_qcq->intr.index); - n_qcq->flags &= ~IONIC_QCQ_F_INTR; - } - n_qcq->intr.vector = src_qcq->intr.vector; n_qcq->intr.index = src_qcq->intr.index; }
From: Rafał Miłecki rafal@milecki.pl
[ Upstream commit e7731194fdf085f46d58b1adccfddbd0dfee4873 ]
Turning IRQs off is done by accessing Ethernet controller registers. That can't be done until device's clock is enabled. It results in a SoC hang otherwise.
This bug remained unnoticed for years as most bootloaders keep all Ethernet interfaces turned on. It seems to only affect a niche SoC family BCM47189. It has two Ethernet controllers but CFE bootloader uses only the first one.
Fixes: 34322615cbaa ("net: bgmac: Mask interrupts during probe") Signed-off-by: Rafał Miłecki rafal@milecki.pl Reviewed-by: Michal Kubiak michal.kubiak@intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/broadcom/bgmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index f8fd65ab663ee..54ff28c9b2148 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1492,8 +1492,6 @@ int bgmac_enet_probe(struct bgmac *bgmac)
bgmac->in_init = true;
- bgmac_chip_intrs_off(bgmac); - net_dev->irq = bgmac->irq; SET_NETDEV_DEV(net_dev, bgmac->dev); dev_set_drvdata(bgmac->dev, bgmac); @@ -1511,6 +1509,8 @@ int bgmac_enet_probe(struct bgmac *bgmac) */ bgmac_clk_enable(bgmac, 0);
+ bgmac_chip_intrs_off(bgmac); + /* This seems to be fixing IRQ by assigning OOB #6 to the core */ if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) { if (bgmac->feature_flags & BGMAC_FEAT_IRQ_ID_OOB_6)
From: Paolo Abeni pabeni@redhat.com
[ Upstream commit c329b261afe71197d9da83c1f18eb45a7e97e089 ]
Ian reported several skb corruptions triggered by rx-gro-list, collecting different oops alike:
[ 62.624003] BUG: kernel NULL pointer dereference, address: 00000000000000c0 [ 62.631083] #PF: supervisor read access in kernel mode [ 62.636312] #PF: error_code(0x0000) - not-present page [ 62.641541] PGD 0 P4D 0 [ 62.644174] Oops: 0000 [#1] PREEMPT SMP NOPTI [ 62.648629] CPU: 1 PID: 913 Comm: napi/eno2-79 Not tainted 6.4.0 #364 [ 62.655162] Hardware name: Supermicro Super Server/A2SDi-12C-HLN4F, BIOS 1.7a 10/13/2022 [ 62.663344] RIP: 0010:__udp_gso_segment (./include/linux/skbuff.h:2858 ./include/linux/udp.h:23 net/ipv4/udp_offload.c:228 net/ipv4/udp_offload.c:261 net/ipv4/udp_offload.c:277) [ 62.687193] RSP: 0018:ffffbd3a83b4f868 EFLAGS: 00010246 [ 62.692515] RAX: 00000000000000ce RBX: 0000000000000000 RCX: 0000000000000000 [ 62.699743] RDX: ffffa124def8a000 RSI: 0000000000000079 RDI: ffffa125952a14d4 [ 62.706970] RBP: ffffa124def8a000 R08: 0000000000000022 R09: 00002000001558c9 [ 62.714199] R10: 0000000000000000 R11: 00000000be554639 R12: 00000000000000e2 [ 62.721426] R13: ffffa125952a1400 R14: ffffa125952a1400 R15: 00002000001558c9 [ 62.728654] FS: 0000000000000000(0000) GS:ffffa127efa40000(0000) knlGS:0000000000000000 [ 62.736852] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 62.742702] CR2: 00000000000000c0 CR3: 00000001034b0000 CR4: 00000000003526e0 [ 62.749948] Call Trace: [ 62.752498] <TASK> [ 62.779267] inet_gso_segment (net/ipv4/af_inet.c:1398) [ 62.787605] skb_mac_gso_segment (net/core/gro.c:141) [ 62.791906] __skb_gso_segment (net/core/dev.c:3403 (discriminator 2)) [ 62.800492] validate_xmit_skb (./include/linux/netdevice.h:4862 net/core/dev.c:3659) [ 62.804695] validate_xmit_skb_list (net/core/dev.c:3710) [ 62.809158] sch_direct_xmit (net/sched/sch_generic.c:330) [ 62.813198] __dev_queue_xmit (net/core/dev.c:3805 net/core/dev.c:4210) net/netfilter/core.c:626) [ 62.821093] br_dev_queue_push_xmit (net/bridge/br_forward.c:55) [ 62.825652] maybe_deliver (net/bridge/br_forward.c:193) [ 62.829420] br_flood (net/bridge/br_forward.c:233) [ 62.832758] br_handle_frame_finish (net/bridge/br_input.c:215) [ 62.837403] br_handle_frame (net/bridge/br_input.c:298 net/bridge/br_input.c:416) [ 62.851417] __netif_receive_skb_core.constprop.0 (net/core/dev.c:5387) [ 62.866114] __netif_receive_skb_list_core (net/core/dev.c:5570) [ 62.871367] netif_receive_skb_list_internal (net/core/dev.c:5638 net/core/dev.c:5727) [ 62.876795] napi_complete_done (./include/linux/list.h:37 ./include/net/gro.h:434 ./include/net/gro.h:429 net/core/dev.c:6067) [ 62.881004] ixgbe_poll (drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:3191) [ 62.893534] __napi_poll (net/core/dev.c:6498) [ 62.897133] napi_threaded_poll (./include/linux/netpoll.h:89 net/core/dev.c:6640) [ 62.905276] kthread (kernel/kthread.c:379) [ 62.913435] ret_from_fork (arch/x86/entry/entry_64.S:314) [ 62.917119] </TASK>
In the critical scenario, rx-gro-list GRO-ed packets are fed, via a bridge, both to the local input path and to an egress device (tun).
The segmentation of such packets unsafely writes to the cloned skbs with shared heads.
This change addresses the issue by uncloning as needed the to-be-segmented skbs.
Reported-by: Ian Kumlien ian.kumlien@gmail.com Tested-by: Ian Kumlien ian.kumlien@gmail.com Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.") Signed-off-by: Paolo Abeni pabeni@redhat.com Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/skbuff.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index f3850c88cdda2..e01dd4cad0fc0 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3882,6 +3882,11 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
skb_push(skb, -skb_network_offset(skb) + offset);
+ /* Ensure the head is writeable before touching the shared info */ + err = skb_unclone(skb, GFP_ATOMIC); + if (err) + goto err_linearize; + skb_shinfo(skb)->frag_list = NULL;
while (list_skb) {
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit 2aaa8a15de73874847d62eb595c6683bface80fd ]
With some IPv6 Ext Hdr (RPL, SRv6, etc.), we can send a packet that has the link-local address as src and dst IP and will be forwarded to an external IP in the IPv6 Ext Hdr.
For example, the script below generates a packet whose src IP is the link-local address and dst is updated to 11::.
# for f in $(find /proc/sys/net/ -name *seg6_enabled*); do echo 1 > $f; done # python3
from socket import * from scapy.all import *
SRC_ADDR = DST_ADDR = "fe80::5054:ff:fe12:3456"
pkt = IPv6(src=SRC_ADDR, dst=DST_ADDR) pkt /= IPv6ExtHdrSegmentRouting(type=4, addresses=["11::", "22::"], segleft=1)
sk = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW) sk.sendto(bytes(pkt), (DST_ADDR, 0))
For such a packet, we call ip6_route_input() to look up a route for the next destination in these three functions depending on the header type.
* ipv6_rthdr_rcv() * ipv6_rpl_srh_rcv() * ipv6_srh_rcv()
If no route is found, ip6_null_entry is set to skb, and the following dst_input(skb) calls ip6_pkt_drop().
Finally, in icmp6_dev(), we dereference skb_rt6_info(skb)->rt6i_idev->dev as the input device is the loopback interface. Then, we have to check if skb_rt6_info(skb)->rt6i_idev is NULL or not to avoid NULL pointer deref for ip6_null_entry.
BUG: kernel NULL pointer dereference, address: 0000000000000000 PF: supervisor read access in kernel mode PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 0 PID: 157 Comm: python3 Not tainted 6.4.0-11996-gb121d614371c #35 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 RIP: 0010:icmp6_send (net/ipv6/icmp.c:436 net/ipv6/icmp.c:503) Code: fe ff ff 48 c7 40 30 c0 86 5d 83 e8 c6 44 1c 00 e9 c8 fc ff ff 49 8b 46 58 48 83 e0 fe 0f 84 4a fb ff ff 48 8b 80 d0 00 00 00 <48> 8b 00 44 8b 88 e0 00 00 00 e9 34 fb ff ff 4d 85 ed 0f 85 69 01 RSP: 0018:ffffc90000003c70 EFLAGS: 00000286 RAX: 0000000000000000 RBX: 0000000000000001 RCX: 00000000000000e0 RDX: 0000000000000021 RSI: 0000000000000000 RDI: ffff888006d72a18 RBP: ffffc90000003d80 R08: 0000000000000000 R09: 0000000000000001 R10: ffffc90000003d98 R11: 0000000000000040 R12: ffff888006d72a10 R13: 0000000000000000 R14: ffff8880057fb800 R15: ffffffff835d86c0 FS: 00007f9dc72ee740(0000) GS:ffff88807dc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000000057b2000 CR4: 00000000007506f0 PKRU: 55555554 Call Trace: <IRQ> ip6_pkt_drop (net/ipv6/route.c:4513) ipv6_rthdr_rcv (net/ipv6/exthdrs.c:640 net/ipv6/exthdrs.c:686) ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:437 (discriminator 5)) ip6_input_finish (./include/linux/rcupdate.h:781 net/ipv6/ip6_input.c:483) __netif_receive_skb_one_core (net/core/dev.c:5455) process_backlog (./include/linux/rcupdate.h:781 net/core/dev.c:5895) __napi_poll (net/core/dev.c:6460) net_rx_action (net/core/dev.c:6529 net/core/dev.c:6660) __do_softirq (./arch/x86/include/asm/jump_label.h:27 ./include/linux/jump_label.h:207 ./include/trace/events/irq.h:142 kernel/softirq.c:554) do_softirq (kernel/softirq.c:454 kernel/softirq.c:441) </IRQ> <TASK> __local_bh_enable_ip (kernel/softirq.c:381) __dev_queue_xmit (net/core/dev.c:4231) ip6_finish_output2 (./include/net/neighbour.h:544 net/ipv6/ip6_output.c:135) rawv6_sendmsg (./include/net/dst.h:458 ./include/linux/netfilter.h:303 net/ipv6/raw.c:656 net/ipv6/raw.c:914) sock_sendmsg (net/socket.c:725 net/socket.c:748) __sys_sendto (net/socket.c:2134) __x64_sys_sendto (net/socket.c:2146 net/socket.c:2142 net/socket.c:2142) do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120) RIP: 0033:0x7f9dc751baea Code: d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 f3 0f 1e fa 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 15 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 7e c3 0f 1f 44 00 00 41 54 48 83 ec 30 44 89 RSP: 002b:00007ffe98712c38 EFLAGS: 00000246 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 00007ffe98712cf8 RCX: 00007f9dc751baea RDX: 0000000000000060 RSI: 00007f9dc6460b90 RDI: 0000000000000003 RBP: 00007f9dc56e8be0 R08: 00007ffe98712d70 R09: 000000000000001c R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: ffffffffc4653600 R14: 0000000000000001 R15: 00007f9dc6af5d1b </TASK> Modules linked in: CR2: 0000000000000000 ---[ end trace 0000000000000000 ]--- RIP: 0010:icmp6_send (net/ipv6/icmp.c:436 net/ipv6/icmp.c:503) Code: fe ff ff 48 c7 40 30 c0 86 5d 83 e8 c6 44 1c 00 e9 c8 fc ff ff 49 8b 46 58 48 83 e0 fe 0f 84 4a fb ff ff 48 8b 80 d0 00 00 00 <48> 8b 00 44 8b 88 e0 00 00 00 e9 34 fb ff ff 4d 85 ed 0f 85 69 01 RSP: 0018:ffffc90000003c70 EFLAGS: 00000286 RAX: 0000000000000000 RBX: 0000000000000001 RCX: 00000000000000e0 RDX: 0000000000000021 RSI: 0000000000000000 RDI: ffff888006d72a18 RBP: ffffc90000003d80 R08: 0000000000000000 R09: 0000000000000001 R10: ffffc90000003d98 R11: 0000000000000040 R12: ffff888006d72a10 R13: 0000000000000000 R14: ffff8880057fb800 R15: ffffffff835d86c0 FS: 00007f9dc72ee740(0000) GS:ffff88807dc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000000057b2000 CR4: 00000000007506f0 PKRU: 55555554 Kernel panic - not syncing: Fatal exception in interrupt Kernel Offset: disabled
Fixes: 4832c30d5458 ("net: ipv6: put host and anycast routes on device with address") Reported-by: Wang Yufen wangyufen@huawei.com Closes: https://lore.kernel.org/netdev/c41403a9-c2f6-3b7e-0c96-e1901e605cd0@huawei.c... Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: David Ahern dsahern@kernel.org Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv6/icmp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 716e7717fe8fe..71a69166a6bd2 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -430,7 +430,10 @@ static struct net_device *icmp6_dev(const struct sk_buff *skb) if (unlikely(dev->ifindex == LOOPBACK_IFINDEX || netif_is_l3_master(skb->dev))) { const struct rt6_info *rt6 = skb_rt6_info(skb);
- if (rt6) + /* The destination could be an external IP in Ext Hdr (SRv6, RPL, etc.), + * and ip6_null_entry could be set to skb if no route is found. + */ + if (rt6 && rt6->rt6i_idev) dev = rt6->rt6i_idev->dev; }
From: Eric Dumazet edumazet@google.com
[ Upstream commit 51d03e2f2203e76ed02d33fb5ffbb5fc85ffaf54 ]
Amit Klein reported that udp6_ehash_secret was initialized but never used.
Fixes: 1bbdceef1e53 ("inet: convert inet_ehash_secret and ipv6_hash_secret to net_get_random_once") Reported-by: Amit Klein aksecurity@gmail.com Signed-off-by: Eric Dumazet edumazet@google.com Cc: Willy Tarreau w@1wt.eu Cc: Willem de Bruijn willemdebruijn.kernel@gmail.com Cc: David Ahern dsahern@kernel.org Cc: Hannes Frederic Sowa hannes@stressinduktion.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv6/udp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 5161e98f6fcfd..a746abbe81b5f 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -88,7 +88,7 @@ static u32 udp6_ehashfn(const struct net *net, fhash = __ipv6_addr_jhash(faddr, udp_ipv6_hash_secret);
return __inet6_ehashfn(lhash, lport, fhash, fport, - udp_ipv6_hash_secret + net_hash_mix(net)); + udp6_ehash_secret + net_hash_mix(net)); }
int udp_v6_get_port(struct sock *sk, unsigned short snum)
From: Yuan Can yuancan@huawei.com
[ Upstream commit c012968259b451dc4db407f2310fe131eaefd800 ]
A problem about ntb_hw_idt create debugfs failed is triggered with the following log given:
[ 1236.637636] IDT PCI-E Non-Transparent Bridge Driver 2.0 [ 1236.639292] debugfs: Directory 'ntb_hw_idt' with parent '/' already present!
The reason is that idt_pci_driver_init() returns pci_register_driver() directly without checking its return value, if pci_register_driver() failed, it returns without destroy the newly created debugfs, resulting the debugfs of ntb_hw_idt can never be created later.
idt_pci_driver_init() debugfs_create_dir() # create debugfs directory pci_register_driver() driver_register() bus_add_driver() priv = kzalloc(...) # OOM happened # return without destroy debugfs directory
Fix by removing debugfs when pci_register_driver() returns error.
Fixes: bf2a952d31d2 ("NTB: Add IDT 89HPESxNTx PCIe-switches support") Signed-off-by: Yuan Can yuancan@huawei.com Signed-off-by: Jon Mason jdmason@kudzu.us Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ntb/hw/idt/ntb_hw_idt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.c b/drivers/ntb/hw/idt/ntb_hw_idt.c index 733557231ed0b..72060acb9cafc 100644 --- a/drivers/ntb/hw/idt/ntb_hw_idt.c +++ b/drivers/ntb/hw/idt/ntb_hw_idt.c @@ -2891,6 +2891,7 @@ static struct pci_driver idt_pci_driver = {
static int __init idt_pci_driver_init(void) { + int ret; pr_info("%s %s\n", NTB_DESC, NTB_VER);
/* Create the top DebugFS directory if the FS is initialized */ @@ -2898,7 +2899,11 @@ static int __init idt_pci_driver_init(void) dbgfs_topdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
/* Register the NTB hardware driver to handle the PCI device */ - return pci_register_driver(&idt_pci_driver); + ret = pci_register_driver(&idt_pci_driver); + if (ret) + debugfs_remove_recursive(dbgfs_topdir); + + return ret; } module_init(idt_pci_driver_init);
From: Yuan Can yuancan@huawei.com
[ Upstream commit 98af0a33c1101c29b3ce4f0cf4715fd927c717f9 ]
A problem about ntb_hw_amd create debugfs failed is triggered with the following log given:
[ 618.431232] AMD(R) PCI-E Non-Transparent Bridge Driver 1.0 [ 618.433284] debugfs: Directory 'ntb_hw_amd' with parent '/' already present!
The reason is that amd_ntb_pci_driver_init() returns pci_register_driver() directly without checking its return value, if pci_register_driver() failed, it returns without destroy the newly created debugfs, resulting the debugfs of ntb_hw_amd can never be created later.
amd_ntb_pci_driver_init() debugfs_create_dir() # create debugfs directory pci_register_driver() driver_register() bus_add_driver() priv = kzalloc(...) # OOM happened # return without destroy debugfs directory
Fix by removing debugfs when pci_register_driver() returns error.
Fixes: a1b3695820aa ("NTB: Add support for AMD PCI-Express Non-Transparent Bridge") Signed-off-by: Yuan Can yuancan@huawei.com Signed-off-by: Jon Mason jdmason@kudzu.us Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ntb/hw/amd/ntb_hw_amd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/ntb/hw/amd/ntb_hw_amd.c b/drivers/ntb/hw/amd/ntb_hw_amd.c index 87847c3800516..1c03a78c125b0 100644 --- a/drivers/ntb/hw/amd/ntb_hw_amd.c +++ b/drivers/ntb/hw/amd/ntb_hw_amd.c @@ -1336,12 +1336,17 @@ static struct pci_driver amd_ntb_pci_driver = {
static int __init amd_ntb_pci_driver_init(void) { + int ret; pr_info("%s %s\n", NTB_DESC, NTB_VER);
if (debugfs_initialized()) debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
- return pci_register_driver(&amd_ntb_pci_driver); + ret = pci_register_driver(&amd_ntb_pci_driver); + if (ret) + debugfs_remove_recursive(debugfs_dir); + + return ret; } module_init(amd_ntb_pci_driver_init);
From: Yuan Can yuancan@huawei.com
[ Upstream commit 4c3c796aca02883ad35bb117468938cc4022ca41 ]
A problem about ntb_hw_intel create debugfs failed is triggered with the following log given:
[ 273.112733] Intel(R) PCI-E Non-Transparent Bridge Driver 2.0 [ 273.115342] debugfs: Directory 'ntb_hw_intel' with parent '/' already present!
The reason is that intel_ntb_pci_driver_init() returns pci_register_driver() directly without checking its return value, if pci_register_driver() failed, it returns without destroy the newly created debugfs, resulting the debugfs of ntb_hw_intel can never be created later.
intel_ntb_pci_driver_init() debugfs_create_dir() # create debugfs directory pci_register_driver() driver_register() bus_add_driver() priv = kzalloc(...) # OOM happened # return without destroy debugfs directory
Fix by removing debugfs when pci_register_driver() returns error.
Fixes: e26a5843f7f5 ("NTB: Split ntb_hw_intel and ntb_transport drivers") Signed-off-by: Yuan Can yuancan@huawei.com Acked-by: Dave Jiang dave.jiang@intel.com Signed-off-by: Jon Mason jdmason@kudzu.us Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ntb/hw/intel/ntb_hw_gen1.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/ntb/hw/intel/ntb_hw_gen1.c b/drivers/ntb/hw/intel/ntb_hw_gen1.c index e5f14e20a9ff7..41897167abc71 100644 --- a/drivers/ntb/hw/intel/ntb_hw_gen1.c +++ b/drivers/ntb/hw/intel/ntb_hw_gen1.c @@ -2060,12 +2060,17 @@ static struct pci_driver intel_ntb_pci_driver = {
static int __init intel_ntb_pci_driver_init(void) { + int ret; pr_info("%s %s\n", NTB_DESC, NTB_VER);
if (debugfs_initialized()) debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
- return pci_register_driver(&intel_ntb_pci_driver); + ret = pci_register_driver(&intel_ntb_pci_driver); + if (ret) + debugfs_remove_recursive(debugfs_dir); + + return ret; } module_init(intel_ntb_pci_driver_init);
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 8623ccbfc55d962e19a3537652803676ad7acb90 ]
If device_register() returns error, the name allocated by dev_set_name() need be freed. As comment of device_register() says, it should use put_device() to give up the reference in the error path. So fix this by calling put_device(), then the name can be freed in kobject_cleanup(), and client_dev is freed in ntb_transport_client_release().
Fixes: fce8a7bb5b4b ("PCI-Express Non-Transparent Bridge Support") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Dave Jiang dave.jiang@intel.com Signed-off-by: Jon Mason jdmason@kudzu.us Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ntb/ntb_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index a9b97ebc71ac5..2abd2235bbcab 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c @@ -410,7 +410,7 @@ int ntb_transport_register_client_dev(char *device_name)
rc = device_register(dev); if (rc) { - kfree(client_dev); + put_device(dev); goto err; }
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit 2790143f09938776a3b4f69685b380bae8fd06c7 ]
As the devm_kcalloc may return NULL pointer, it should be better to add check for the return value, as same as the others.
Fixes: 7f46c8b3a552 ("NTB: ntb_tool: Add full multi-port NTB API support") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Reviewed-by: Serge Semin fancer.lancer@gmail.com Reviewed-by: Dave Jiang dave.jiang@intel.com Signed-off-by: Jon Mason jdmason@kudzu.us Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ntb/test/ntb_tool.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/ntb/test/ntb_tool.c b/drivers/ntb/test/ntb_tool.c index 5ee0afa621a95..eeeb4b1c97d2c 100644 --- a/drivers/ntb/test/ntb_tool.c +++ b/drivers/ntb/test/ntb_tool.c @@ -998,6 +998,8 @@ static int tool_init_mws(struct tool_ctx *tc) tc->peers[pidx].outmws = devm_kcalloc(&tc->ntb->dev, tc->peers[pidx].outmw_cnt, sizeof(*tc->peers[pidx].outmws), GFP_KERNEL); + if (tc->peers[pidx].outmws == NULL) + return -ENOMEM;
for (widx = 0; widx < tc->peers[pidx].outmw_cnt; widx++) { tc->peers[pidx].outmws[widx].pidx = pidx;
From: Ziyang Xuan william.xuanziyang@huawei.com
[ Upstream commit 06a0716949c22e2aefb648526580671197151acc ]
Now in addrconf_mod_rs_timer(), reference idev depends on whether rs_timer is not pending. Then modify rs_timer timeout.
There is a time gap in [1], during which if the pending rs_timer becomes not pending. It will miss to hold idev, but the rs_timer is activated. Thus rs_timer callback function addrconf_rs_timer() will be executed and put idev later without holding idev. A refcount underflow issue for idev can be caused by this.
if (!timer_pending(&idev->rs_timer)) in6_dev_hold(idev); <--------------[1] mod_timer(&idev->rs_timer, jiffies + when);
To fix the issue, hold idev if mod_timer() return 0.
Fixes: b7b1bfce0bb6 ("ipv6: split duplicate address detection and router solicitation timer") Suggested-by: Eric Dumazet edumazet@google.com Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv6/addrconf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 6ba34f51c411f..e0d3909172a84 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -323,9 +323,8 @@ static void addrconf_del_dad_work(struct inet6_ifaddr *ifp) static void addrconf_mod_rs_timer(struct inet6_dev *idev, unsigned long when) { - if (!timer_pending(&idev->rs_timer)) + if (!mod_timer(&idev->rs_timer, jiffies + when)) in6_dev_hold(idev); - mod_timer(&idev->rs_timer, jiffies + when); }
static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,
From: Barnabás Pőcze pobrn@protonmail.com
[ Upstream commit 84eacf7e6413d5e2d2f4f9dddf9216c18a3631cf ]
The GUID block is available for `wmi_create_device()` through `wblock->gblock`. Use that consistently in the function instead of using a mix of `gblock` and `wblock->gblock`.
Signed-off-by: Barnabás Pőcze pobrn@protonmail.com Link: https://lore.kernel.org/r/20210904175450.156801-8-pobrn@protonmail.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Stable-dep-of: 028e6e204ace ("platform/x86: wmi: Break possible infinite loop when parsing GUID") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/wmi.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index c4f917d45b51d..529f725271e99 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -1046,7 +1046,6 @@ static const struct device_type wmi_type_data = { };
static int wmi_create_device(struct device *wmi_bus_dev, - const struct guid_block *gblock, struct wmi_block *wblock, struct acpi_device *device) { @@ -1054,12 +1053,12 @@ static int wmi_create_device(struct device *wmi_bus_dev, char method[5]; int result;
- if (gblock->flags & ACPI_WMI_EVENT) { + if (wblock->gblock.flags & ACPI_WMI_EVENT) { wblock->dev.dev.type = &wmi_type_event; goto out_init; }
- if (gblock->flags & ACPI_WMI_METHOD) { + if (wblock->gblock.flags & ACPI_WMI_METHOD) { wblock->dev.dev.type = &wmi_type_method; mutex_init(&wblock->char_mutex); goto out_init; @@ -1109,7 +1108,7 @@ static int wmi_create_device(struct device *wmi_bus_dev, wblock->dev.dev.bus = &wmi_bus_type; wblock->dev.dev.parent = wmi_bus_dev;
- dev_set_name(&wblock->dev.dev, "%pUL", gblock->guid); + dev_set_name(&wblock->dev.dev, "%pUL", wblock->gblock.guid);
device_initialize(&wblock->dev.dev);
@@ -1201,7 +1200,7 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) wblock->acpi_device = device; wblock->gblock = gblock[i];
- retval = wmi_create_device(wmi_bus_dev, &gblock[i], wblock, device); + retval = wmi_create_device(wmi_bus_dev, wblock, device); if (retval) { kfree(wblock); continue;
From: Barnabás Pőcze pobrn@protonmail.com
[ Upstream commit 67f472fdacf4a691b1c3c20c27800b23ce31e2de ]
Instead of hard-coding a 16 long byte array, use the available `guid_t` type and related methods.
Signed-off-by: Barnabás Pőcze pobrn@protonmail.com Link: https://lore.kernel.org/r/20210904175450.156801-15-pobrn@protonmail.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Stable-dep-of: 028e6e204ace ("platform/x86: wmi: Break possible infinite loop when parsing GUID") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/wmi.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 529f725271e99..d55770711a831 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -39,7 +39,7 @@ MODULE_LICENSE("GPL"); static LIST_HEAD(wmi_block_list);
struct guid_block { - char guid[16]; + guid_t guid; union { char object_id[2]; struct { @@ -124,7 +124,7 @@ static bool find_guid(const char *guid_string, struct wmi_block **out) list_for_each_entry(wblock, &wmi_block_list, list) { block = &wblock->gblock;
- if (memcmp(block->guid, &guid_input, 16) == 0) { + if (guid_equal(&block->guid, &guid_input)) { if (out) *out = wblock; return true; @@ -148,7 +148,7 @@ static const void *find_guid_context(struct wmi_block *wblock, while (*id->guid_string) { if (guid_parse(id->guid_string, &guid_input)) continue; - if (!memcmp(wblock->gblock.guid, &guid_input, 16)) + if (guid_equal(&wblock->gblock.guid, &guid_input)) return id->context; id++; } @@ -460,7 +460,7 @@ EXPORT_SYMBOL_GPL(wmi_set_block);
static void wmi_dump_wdg(const struct guid_block *g) { - pr_info("%pUL:\n", g->guid); + pr_info("%pUL:\n", &g->guid); if (g->flags & ACPI_WMI_EVENT) pr_info("\tnotify_id: 0x%02X\n", g->notify_id); else @@ -542,7 +542,7 @@ wmi_notify_handler handler, void *data) list_for_each_entry(block, &wmi_block_list, list) { acpi_status wmi_status;
- if (memcmp(block->gblock.guid, &guid_input, 16) == 0) { + if (guid_equal(&block->gblock.guid, &guid_input)) { if (block->handler && block->handler != wmi_notify_debug) return AE_ALREADY_ACQUIRED; @@ -582,7 +582,7 @@ acpi_status wmi_remove_notify_handler(const char *guid) list_for_each_entry(block, &wmi_block_list, list) { acpi_status wmi_status;
- if (memcmp(block->gblock.guid, &guid_input, 16) == 0) { + if (guid_equal(&block->gblock.guid, &guid_input)) { if (!block->handler || block->handler == wmi_notify_debug) return AE_NULL_ENTRY; @@ -693,7 +693,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, { struct wmi_block *wblock = dev_to_wblock(dev);
- return sprintf(buf, "wmi:%pUL\n", wblock->gblock.guid); + return sprintf(buf, "wmi:%pUL\n", &wblock->gblock.guid); } static DEVICE_ATTR_RO(modalias);
@@ -702,7 +702,7 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, { struct wmi_block *wblock = dev_to_wblock(dev);
- return sprintf(buf, "%pUL\n", wblock->gblock.guid); + return sprintf(buf, "%pUL\n", &wblock->gblock.guid); } static DEVICE_ATTR_RO(guid);
@@ -785,10 +785,10 @@ static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env) { struct wmi_block *wblock = dev_to_wblock(dev);
- if (add_uevent_var(env, "MODALIAS=wmi:%pUL", wblock->gblock.guid)) + if (add_uevent_var(env, "MODALIAS=wmi:%pUL", &wblock->gblock.guid)) return -ENOMEM;
- if (add_uevent_var(env, "WMI_GUID=%pUL", wblock->gblock.guid)) + if (add_uevent_var(env, "WMI_GUID=%pUL", &wblock->gblock.guid)) return -ENOMEM;
return 0; @@ -815,7 +815,7 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver)
if (WARN_ON(guid_parse(id->guid_string, &driver_guid))) continue; - if (!memcmp(&driver_guid, wblock->gblock.guid, 16)) + if (guid_equal(&driver_guid, &wblock->gblock.guid)) return 1;
id++; @@ -1108,7 +1108,7 @@ static int wmi_create_device(struct device *wmi_bus_dev, wblock->dev.dev.bus = &wmi_bus_type; wblock->dev.dev.parent = wmi_bus_dev;
- dev_set_name(&wblock->dev.dev, "%pUL", wblock->gblock.guid); + dev_set_name(&wblock->dev.dev, "%pUL", &wblock->gblock.guid);
device_initialize(&wblock->dev.dev);
@@ -1128,12 +1128,12 @@ static void wmi_free_devices(struct acpi_device *device) } }
-static bool guid_already_parsed(struct acpi_device *device, const u8 *guid) +static bool guid_already_parsed(struct acpi_device *device, const guid_t *guid) { struct wmi_block *wblock;
list_for_each_entry(wblock, &wmi_block_list, list) { - if (memcmp(wblock->gblock.guid, guid, 16) == 0) { + if (guid_equal(&wblock->gblock.guid, guid)) { /* * Because we historically didn't track the relationship * between GUIDs and ACPI nodes, we don't know whether @@ -1188,7 +1188,7 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) * case yet, so for now, we'll just ignore the duplicate * for device creation. */ - if (guid_already_parsed(device, gblock[i].guid)) + if (guid_already_parsed(device, &gblock[i].guid)) continue;
wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); @@ -1225,7 +1225,7 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) retval = device_add(&wblock->dev.dev); if (retval) { dev_err(wmi_bus_dev, "failed to register %pUL\n", - wblock->gblock.guid); + &wblock->gblock.guid); if (debug_event) wmi_method_enable(wblock, 0); list_del(&wblock->list); @@ -1333,7 +1333,7 @@ static void acpi_wmi_notify_handler(acpi_handle handle, u32 event, }
if (debug_event) - pr_info("DEBUG Event GUID: %pUL\n", wblock->gblock.guid); + pr_info("DEBUG Event GUID: %pUL\n", &wblock->gblock.guid);
acpi_bus_generate_netlink_event( wblock->acpi_device->pnp.device_class,
From: Barnabás Pőcze pobrn@protonmail.com
[ Upstream commit f5431bf1e6781e876bdc8ae10fb1e7da6f1aa9b5 ]
Move some variables in order to keep them in the narrowest possible scope.
Signed-off-by: Barnabás Pőcze pobrn@protonmail.com Link: https://lore.kernel.org/r/20210904175450.156801-22-pobrn@protonmail.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Stable-dep-of: 028e6e204ace ("platform/x86: wmi: Break possible infinite loop when parsing GUID") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/wmi.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index d55770711a831..6a51220c37a2b 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -137,7 +137,6 @@ static const void *find_guid_context(struct wmi_block *wblock, struct wmi_driver *wdriver) { const struct wmi_device_id *id; - guid_t guid_input;
if (wblock == NULL || wdriver == NULL) return NULL; @@ -146,6 +145,8 @@ static const void *find_guid_context(struct wmi_block *wblock,
id = wdriver->id_table; while (*id->guid_string) { + guid_t guid_input; + if (guid_parse(id->guid_string, &guid_input)) continue; if (guid_equal(&wblock->gblock.guid, &guid_input)) @@ -618,7 +619,6 @@ acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out) { struct acpi_object_list input; union acpi_object params[1]; - struct guid_block *gblock; struct wmi_block *wblock;
input.count = 1; @@ -627,7 +627,7 @@ acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out) params[0].integer.value = event;
list_for_each_entry(wblock, &wmi_block_list, list) { - gblock = &wblock->gblock; + struct guid_block *gblock = &wblock->gblock;
if ((gblock->flags & ACPI_WMI_EVENT) && (gblock->notify_id == event)) @@ -1282,12 +1282,11 @@ acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address, static void acpi_wmi_notify_handler(acpi_handle handle, u32 event, void *context) { - struct guid_block *block; struct wmi_block *wblock; bool found_it = false;
list_for_each_entry(wblock, &wmi_block_list, list) { - block = &wblock->gblock; + struct guid_block *block = &wblock->gblock;
if (wblock->acpi_device->handle == handle && (block->flags & ACPI_WMI_EVENT) &&
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 028e6e204ace1f080cfeacd72c50397eb8ae8883 ]
The while-loop may break on one of the two conditions, either ID string is empty or GUID matches. The second one, may never be reached if the parsed string is not correct GUID. In such a case the loop will never advance to check the next ID.
Break possible infinite loop by factoring out guid_parse_and_compare() helper which may be moved to the generic header for everyone later on and preventing from similar mistake in the future.
Interestingly that firstly it appeared when WMI was turned into a bus driver, but later when duplicated GUIDs were checked, the while-loop has been replaced by for-loop and hence no mistake made again.
Fixes: a48e23385fcf ("platform/x86: wmi: add context pointer field to struct wmi_device_id") Fixes: 844af950da94 ("platform/x86: wmi: Turn WMI into a bus driver") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20230621151155.78279-1-andriy.shevchenko@linux.int... Tested-by: Armin Wolf W_Armin@gmx.de 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/wmi.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 6a51220c37a2b..7ce0408d3bfdd 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -133,6 +133,16 @@ static bool find_guid(const char *guid_string, struct wmi_block **out) return false; }
+static bool guid_parse_and_compare(const char *string, const guid_t *guid) +{ + guid_t guid_input; + + if (guid_parse(string, &guid_input)) + return false; + + return guid_equal(&guid_input, guid); +} + static const void *find_guid_context(struct wmi_block *wblock, struct wmi_driver *wdriver) { @@ -145,11 +155,7 @@ static const void *find_guid_context(struct wmi_block *wblock,
id = wdriver->id_table; while (*id->guid_string) { - guid_t guid_input; - - if (guid_parse(id->guid_string, &guid_input)) - continue; - if (guid_equal(&wblock->gblock.guid, &guid_input)) + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) return id->context; id++; } @@ -811,11 +817,7 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) return 0;
while (*id->guid_string) { - guid_t driver_guid; - - if (WARN_ON(guid_parse(id->guid_string, &driver_guid))) - continue; - if (guid_equal(&driver_guid, &wblock->gblock.guid)) + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) return 1;
id++;
From: Tzvetomir Stoyanov (VMware) tz.stoyanov@gmail.com
[ Upstream commit cf0a624dc706c306294c14e6b3e7694702f25191 ]
The enable_trace_eprobe() function enables all event probes, attached to given trace probe. If an error occurs in enabling one of the event probes, all others should be roll backed. There is a bug in that roll back logic - instead of all event probes, only the failed one is disabled.
Link: https://lore.kernel.org/all/20230703042853.1427493-1-tz.stoyanov@gmail.com/
Reported-by: Dan Carpenter dan.carpenter@linaro.org Fixes: 7491e2c44278 ("tracing: Add a probe that attaches to trace events") Signed-off-by: Tzvetomir Stoyanov (VMware) tz.stoyanov@gmail.com Acked-by: Masami Hiramatsu (Google) mhiramat@kernel.org Reviewed-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Masami Hiramatsu (Google) mhiramat@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/trace/trace_eprobe.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c index 9806316af1279..085f056e66f19 100644 --- a/kernel/trace/trace_eprobe.c +++ b/kernel/trace/trace_eprobe.c @@ -725,6 +725,7 @@ static int enable_trace_eprobe(struct trace_event_call *call, struct trace_eprobe *ep; bool enabled; int ret = 0; + int cnt = 0;
tp = trace_probe_primary_from_call(call); if (WARN_ON_ONCE(!tp)) @@ -748,12 +749,25 @@ static int enable_trace_eprobe(struct trace_event_call *call, if (ret) break; enabled = true; + cnt++; }
if (ret) { /* Failed to enable one of them. Roll back all */ - if (enabled) - disable_eprobe(ep, file->tr); + if (enabled) { + /* + * It's a bug if one failed for something other than memory + * not being available but another eprobe succeeded. + */ + WARN_ON_ONCE(ret != -ENOMEM); + + list_for_each_entry(pos, trace_probe_probe_list(tp), list) { + ep = container_of(pos, struct trace_eprobe, tp); + disable_eprobe(ep, file->tr); + if (!--cnt) + break; + } + } if (file) trace_probe_remove_file(tp, file); else
From: Florian Kauer florian.kauer@linutronix.de
[ Upstream commit c1bca9ac0bcb355be11354c2e68bc7bf31f5ac5a ]
It is possible (verified on a running system) that frames are processed by igc_tx_launchtime with a txtime before the start of the cycle (baset_est).
However, the result of txtime - baset_est is written into a u32, leading to a wrap around to a positive number. The following launchtime > 0 check will only branch to executing launchtime = 0 if launchtime is already 0.
Fix it by using a s32 before checking launchtime > 0.
Fixes: db0b124f02ba ("igc: Enhance Qbv scheduling by using first flag bit") Signed-off-by: Florian Kauer florian.kauer@linutronix.de Reviewed-by: Kurt Kanzenbach kurt@linutronix.de Tested-by: Naama Meir naamax.meir@linux.intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/igc/igc_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index e5cbf867034e3..491b80407df49 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -1013,7 +1013,7 @@ static __le32 igc_tx_launchtime(struct igc_ring *ring, ktime_t txtime, ktime_t base_time = adapter->base_time; ktime_t now = ktime_get_clocktai(); ktime_t baset_est, end_of_cycle; - u32 launchtime; + s32 launchtime; s64 n;
n = div64_s64(ktime_sub_ns(now, base_time), cycle_time);
From: Florian Kauer florian.kauer@linutronix.de
[ Upstream commit 0bcc62858d6ba62cbade957d69745e6adeed5f3d ]
The insertion of an empty frame was introduced with commit db0b124f02ba ("igc: Enhance Qbv scheduling by using first flag bit") in order to ensure that the current cycle has at least one packet if there is some packet to be scheduled for the next cycle.
However, the current implementation does not properly check if a packet is already scheduled for the current cycle. Currently, an empty packet is always inserted if and only if txtime >= end_of_cycle && txtime > last_tx_cycle but since last_tx_cycle is always either the end of the current cycle (end_of_cycle) or the end of a previous cycle, the second part (txtime > last_tx_cycle) is always true unless txtime == last_tx_cycle.
What actually needs to be checked here is if the last_tx_cycle was already written within the current cycle, so an empty frame should only be inserted if and only if txtime >= end_of_cycle && end_of_cycle > last_tx_cycle.
This patch does not only avoid an unnecessary insertion, but it can actually be harmful to insert an empty packet if packets are already scheduled in the current cycle, because it can lead to a situation where the empty packet is actually processed as the first packet in the upcoming cycle shifting the packet with the first_flag even one cycle into the future, finally leading to a TX hang.
The TX hang can be reproduced on a i225 with:
sudo tc qdisc replace dev enp1s0 parent root handle 100 taprio \ num_tc 1 \ map 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \ queues 1@0 \ base-time 0 \ sched-entry S 01 300000 \ flags 0x1 \ txtime-delay 500000 \ clockid CLOCK_TAI sudo tc qdisc replace dev enp1s0 parent 100:1 etf \ clockid CLOCK_TAI \ delta 500000 \ offload \ skip_sock_check
and traffic generator
sudo trafgen -i traffic.cfg -o enp1s0 --cpp -n0 -q -t1400ns
with traffic.cfg
#define ETH_P_IP 0x0800
{ /* Ethernet Header */ 0x30, 0x1f, 0x9a, 0xd0, 0xf0, 0x0e, # MAC Dest - adapt as needed 0x24, 0x5e, 0xbe, 0x57, 0x2e, 0x36, # MAC Src - adapt as needed const16(ETH_P_IP),
/* IPv4 Header */ 0b01000101, 0, # IPv4 version, IHL, TOS const16(1028), # IPv4 total length (UDP length + 20 bytes (IP header)) const16(2), # IPv4 ident 0b01000000, 0, # IPv4 flags, fragmentation off 64, # IPv4 TTL 17, # Protocol UDP csumip(14, 33), # IPv4 checksum
/* UDP Header */ 10, 0, 48, 1, # IP Src - adapt as needed 10, 0, 48, 10, # IP Dest - adapt as needed const16(5555), # UDP Src Port const16(6666), # UDP Dest Port const16(1008), # UDP length (UDP header 8 bytes + payload length) csumudp(14, 34), # UDP checksum
/* Payload */ fill('W', 1000), }
and the observed message with that is for example
igc 0000:01:00.0 enp1s0: Detected Tx Unit Hang Tx Queue <0> TDH <32> TDT <3c> next_to_use <3c> next_to_clean <32> buffer_info[next_to_clean] time_stamp <ffff26a8> next_to_watch <00000000632a1828> jiffies <ffff27f8> desc.status <1048000>
Fixes: db0b124f02ba ("igc: Enhance Qbv scheduling by using first flag bit") Signed-off-by: Florian Kauer florian.kauer@linutronix.de Reviewed-by: Kurt Kanzenbach kurt@linutronix.de Tested-by: Naama Meir naamax.meir@linux.intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/igc/igc_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 491b80407df49..db48979cdecbc 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -1026,7 +1026,7 @@ static __le32 igc_tx_launchtime(struct igc_ring *ring, ktime_t txtime, *first_flag = true; ring->last_ff_cycle = baset_est;
- if (ktime_compare(txtime, ring->last_tx_cycle) > 0) + if (ktime_compare(end_of_cycle, ring->last_tx_cycle) > 0) *insert_empty = true; } }
From: Pu Lehui pulehui@huawei.com
[ Upstream commit 3cb70413041fdf028fa1ba3986fd0c6aec9e3dcb ]
Add support for riscv jit to provide bpf_line_info. We need to consider the prologue offset in ctx->offset, but unlike x86 and arm64, ctx->offset of riscv does not provide an extra slot for the prologue, so here we just calculate the len of prologue and add it to ctx->offset at the end. Both RV64 and RV32 have been tested.
Signed-off-by: Pu Lehui pulehui@huawei.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20220530092815.1112406-3-pulehui@huawei.com Stable-dep-of: c56fb2aab235 ("riscv, bpf: Fix inconsistent JIT image generation") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/net/bpf_jit.h | 1 + arch/riscv/net/bpf_jit_core.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h index 75c1e99968675..ab0cd6d10ccf3 100644 --- a/arch/riscv/net/bpf_jit.h +++ b/arch/riscv/net/bpf_jit.h @@ -69,6 +69,7 @@ struct rv_jit_context { struct bpf_prog *prog; u16 *insns; /* RV insns */ int ninsns; + int body_len; int epilogue_offset; int *offset; /* BPF to RV */ unsigned long flags; diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c index 753d85bdfad07..ff644452b88db 100644 --- a/arch/riscv/net/bpf_jit_core.c +++ b/arch/riscv/net/bpf_jit_core.c @@ -43,7 +43,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) { bool tmp_blinded = false, extra_pass = false; struct bpf_prog *tmp, *orig_prog = prog; - int pass = 0, prev_ninsns = 0, i; + int pass = 0, prev_ninsns = 0, prologue_len, i; struct rv_jit_data *jit_data; struct rv_jit_context *ctx; unsigned int image_size = 0; @@ -95,6 +95,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) prog = orig_prog; goto out_offset; } + ctx->body_len = ctx->ninsns; bpf_jit_build_prologue(ctx); ctx->epilogue_offset = ctx->ninsns; bpf_jit_build_epilogue(ctx); @@ -154,6 +155,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
if (!prog->is_func || extra_pass) { bpf_jit_binary_lock_ro(jit_data->header); + prologue_len = ctx->epilogue_offset - ctx->body_len; + for (i = 0; i < prog->len; i++) + ctx->offset[i] = ninsns_rvoff(prologue_len + + ctx->offset[i]); + bpf_prog_fill_jited_linfo(prog, ctx->offset); out_offset: kfree(ctx->offset); kfree(jit_data);
From: Björn Töpel bjorn@rivosinc.com
[ Upstream commit c56fb2aab23505bb7160d06097c8de100b82b851 ]
In order to generate the prologue and epilogue, the BPF JIT needs to know which registers that are clobbered. Therefore, the during pre-final passes, the prologue is generated after the body of the program body-prologue-epilogue. Then, in the final pass, a proper prologue-body-epilogue JITted image is generated.
This scheme has worked most of the time. However, for some large programs with many jumps, e.g. the test_kmod.sh BPF selftest with hardening enabled (blinding constants), this has shown to be incorrect. For the final pass, when the proper prologue-body-epilogue is generated, the image has not converged. This will lead to that the final image will have incorrect jump offsets. The following is an excerpt from an incorrect image:
| ... | 3b8: 00c50663 beq a0,a2,3c4 <.text+0x3c4> | 3bc: 0020e317 auipc t1,0x20e | 3c0: 49630067 jalr zero,1174(t1) # 20e852 <.text+0x20e852> | ... | 20e84c: 8796 c.mv a5,t0 | 20e84e: 6422 c.ldsp s0,8(sp) # Epilogue start | 20e850: 6141 c.addi16sp sp,16 | 20e852: 853e c.mv a0,a5 # Incorrect jump target | 20e854: 8082 c.jr ra
The image has shrunk, and the epilogue offset is incorrect in the final pass.
Correct the problem by always generating proper prologue-body-epilogue outputs, which means that the first pass will only generate the body to track what registers that are touched.
Fixes: 2353ecc6f91f ("bpf, riscv: add BPF JIT for RV64G") Signed-off-by: Björn Töpel bjorn@rivosinc.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20230710074131.19596-1-bjorn@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/net/bpf_jit.h | 6 +++--- arch/riscv/net/bpf_jit_core.c | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h index ab0cd6d10ccf3..ef336fe160044 100644 --- a/arch/riscv/net/bpf_jit.h +++ b/arch/riscv/net/bpf_jit.h @@ -69,7 +69,7 @@ struct rv_jit_context { struct bpf_prog *prog; u16 *insns; /* RV insns */ int ninsns; - int body_len; + int prologue_len; int epilogue_offset; int *offset; /* BPF to RV */ unsigned long flags; @@ -215,8 +215,8 @@ static inline int rv_offset(int insn, int off, struct rv_jit_context *ctx) int from, to;
off++; /* BPF branch is from PC+1, RV is from PC */ - from = (insn > 0) ? ctx->offset[insn - 1] : 0; - to = (insn + off > 0) ? ctx->offset[insn + off - 1] : 0; + from = (insn > 0) ? ctx->offset[insn - 1] : ctx->prologue_len; + to = (insn + off > 0) ? ctx->offset[insn + off - 1] : ctx->prologue_len; return ninsns_rvoff(to - from); }
diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c index ff644452b88db..b95c60f663d44 100644 --- a/arch/riscv/net/bpf_jit_core.c +++ b/arch/riscv/net/bpf_jit_core.c @@ -43,7 +43,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) { bool tmp_blinded = false, extra_pass = false; struct bpf_prog *tmp, *orig_prog = prog; - int pass = 0, prev_ninsns = 0, prologue_len, i; + int pass = 0, prev_ninsns = 0, i; struct rv_jit_data *jit_data; struct rv_jit_context *ctx; unsigned int image_size = 0; @@ -83,6 +83,12 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) prog = orig_prog; goto out_offset; } + + if (build_body(ctx, extra_pass, NULL)) { + prog = orig_prog; + goto out_offset; + } + for (i = 0; i < prog->len; i++) { prev_ninsns += 32; ctx->offset[i] = prev_ninsns; @@ -91,12 +97,15 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) for (i = 0; i < NR_JIT_ITERATIONS; i++) { pass++; ctx->ninsns = 0; + + bpf_jit_build_prologue(ctx); + ctx->prologue_len = ctx->ninsns; + if (build_body(ctx, extra_pass, ctx->offset)) { prog = orig_prog; goto out_offset; } - ctx->body_len = ctx->ninsns; - bpf_jit_build_prologue(ctx); + ctx->epilogue_offset = ctx->ninsns; bpf_jit_build_epilogue(ctx);
@@ -155,10 +164,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
if (!prog->is_func || extra_pass) { bpf_jit_binary_lock_ro(jit_data->header); - prologue_len = ctx->epilogue_offset - ctx->body_len; for (i = 0; i < prog->len; i++) - ctx->offset[i] = ninsns_rvoff(prologue_len + - ctx->offset[i]); + ctx->offset[i] = ninsns_rvoff(ctx->offset[i]); bpf_prog_fill_jited_linfo(prog, ctx->offset); out_offset: kfree(ctx->offset);
From: Tvrtko Ursulin tvrtko.ursulin@intel.com
[ Upstream commit 113899c2669dff148b2a5bea4780123811aecc13 ]
Commit a4d86249c773 ("drm/i915/gt: Provide a utility to create a scratch buffer") mistakenly passed in uapi I915_CACHING_CACHED as argument to i915_gem_object_set_cache_coherency(), which actually takes internal enum i915_cache_level.
No functional issue since the value matches I915_CACHE_LLC (1 == 1), which is the intended caching mode, but lets clean it up nevertheless.
Signed-off-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Fixes: a4d86249c773 ("drm/i915/gt: Provide a utility to create a scratch buffer") Cc: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Reviewed-by: Tejas Upadhyay tejas.upadhyay@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230707125503.3965817-1-tvrtk... (cherry picked from commit 49c60b2f0867ac36fd54d513882a48431aeccae7) Signed-off-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/gt/intel_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c index 2d3a979736cc1..f9d4094916e3d 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.c +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c @@ -547,7 +547,7 @@ __vm_create_scratch_for_read(struct i915_address_space *vm, unsigned long size) if (IS_ERR(obj)) return ERR_CAST(obj);
- i915_gem_object_set_cache_coherency(obj, I915_CACHING_CACHED); + i915_gem_object_set_cache_coherency(obj, I915_CACHE_LLC);
vma = i915_vma_instance(obj, vm, NULL); if (IS_ERR(vma)) {
From: Suman Ghosh sumang@marvell.com
[ Upstream commit 8278ee2a2646b9acf747317895e47a640ba933c9 ]
Due to hardware limitation, MCAM drop rule with ether_type == 802.1Q and vlan_id == 0 is not supported. Hence rejecting such rules.
Fixes: dce677da57c0 ("octeontx2-pf: Add vlan-etype to ntuple filters") Signed-off-by: Suman Ghosh sumang@marvell.com Link: https://lore.kernel.org/r/20230710103027.2244139-1-sumang@marvell.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../ethernet/marvell/octeontx2/nic/otx2_flows.c | 8 ++++++++ .../net/ethernet/marvell/octeontx2/nic/otx2_tc.c | 15 +++++++++++++++ 2 files changed, 23 insertions(+)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c index 63889449b8f61..483f660cebc40 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c @@ -827,6 +827,14 @@ static int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp, return -EINVAL;
vlan_etype = be16_to_cpu(fsp->h_ext.vlan_etype); + + /* Drop rule with vlan_etype == 802.1Q + * and vlan_id == 0 is not supported + */ + if (vlan_etype == ETH_P_8021Q && !fsp->m_ext.vlan_tci && + fsp->ring_cookie == RX_CLS_FLOW_DISC) + return -EINVAL; + /* Only ETH_P_8021Q and ETH_P_802AD types supported */ if (vlan_etype != ETH_P_8021Q && vlan_etype != ETH_P_8021AD) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c index a42373e6f2593..26231c59b0241 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c @@ -536,6 +536,21 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node, return -EOPNOTSUPP; }
+ if (!match.mask->vlan_id) { + struct flow_action_entry *act; + int i; + + flow_action_for_each(i, act, &rule->action) { + if (act->id == FLOW_ACTION_DROP) { + netdev_err(nic->netdev, + "vlan tpid 0x%x with vlan_id %d is not supported for DROP rule.\n", + ntohs(match.key->vlan_tpid), + match.key->vlan_id); + return -EOPNOTSUPP; + } + } + } + if (match.mask->vlan_id || match.mask->vlan_dei || match.mask->vlan_priority) {
From: Chunhai Guo guochunhai@vivo.com
[ Upstream commit 8191213a5835b0317c5e4d0d337ae1ae00c75253 ]
z_erofs_do_read_page() may loop infinitely due to the inappropriate truncation in the below statement. Since the offset is 64 bits and min_t() truncates the result to 32 bits. The solution is to replace unsigned int with a 64-bit type, such as erofs_off_t. cur = end - min_t(unsigned int, offset + end - map->m_la, end);
- For example: - offset = 0x400160000 - end = 0x370 - map->m_la = 0x160370 - offset + end - map->m_la = 0x400000000 - offset + end - map->m_la = 0x00000000 (truncated as unsigned int) - Expected result: - cur = 0 - Actual result: - cur = 0x370
Signed-off-by: Chunhai Guo guochunhai@vivo.com Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support") Reviewed-by: Gao Xiang hsiangkao@linux.alibaba.com Reviewed-by: Chao Yu chao@kernel.org Link: https://lore.kernel.org/r/20230710093410.44071-1-guochunhai@vivo.com Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/erofs/zdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index eb51df4a9f770..3fd91a0efdbb7 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -713,7 +713,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe, tight &= (clt->mode >= COLLECT_PRIMARY_HOOKED && clt->mode != COLLECT_PRIMARY_FOLLOWED_NOINPLACE);
- cur = end - min_t(unsigned int, offset + end - map->m_la, end); + cur = end - min_t(erofs_off_t, offset + end - map->m_la, end); if (!(map->m_flags & EROFS_MAP_MAPPED)) { zero_user_segment(page, cur, end); goto next_part;
From: Gao Xiang hsiangkao@linux.alibaba.com
[ Upstream commit e62424651f43cb37e17ca26a7ee9ee42675f24bd ]
Previously, EROFS mount options are all in the basic types, so erofs_fs_context can be directly copied with assignment. However, when the multiple device feature is introduced, it's hard to handle multiple device information like the other basic mount options.
Let's separate basic mount option usage from fs_context, thus multiple device information can be handled gracefully then.
No logic changes.
Link: https://lore.kernel.org/r/20211007070224.12833-1-hsiangkao@linux.alibaba.com Reviewed-by: Chao Yu chao@kernel.org Reviewed-by: Liu Bo bo.liu@linux.alibaba.com Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Stable-dep-of: 18bddc5b6703 ("erofs: fix fsdax unavailability for chunk-based regular files") Signed-off-by: Sasha Levin sashal@kernel.org --- fs/erofs/inode.c | 2 +- fs/erofs/internal.h | 16 ++++++++----- fs/erofs/super.c | 58 ++++++++++++++++++++++----------------------- fs/erofs/xattr.c | 4 ++-- fs/erofs/zdata.c | 8 +++---- 5 files changed, 45 insertions(+), 43 deletions(-)
diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c index 0c293ff6697b5..3ff36514cff25 100644 --- a/fs/erofs/inode.c +++ b/fs/erofs/inode.c @@ -192,7 +192,7 @@ static struct page *erofs_read_inode(struct inode *inode, inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec;
inode->i_flags &= ~S_DAX; - if (test_opt(&sbi->ctx, DAX_ALWAYS) && S_ISREG(inode->i_mode) && + if (test_opt(&sbi->opt, DAX_ALWAYS) && S_ISREG(inode->i_mode) && vi->datalayout == EROFS_INODE_FLAT_PLAIN) inode->i_flags |= S_DAX; if (!nblks) diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index beadb06d8feb9..323e46d800e9e 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -47,7 +47,7 @@ typedef u64 erofs_off_t; /* data type for filesystem-wide blocks number */ typedef u32 erofs_blk_t;
-struct erofs_fs_context { +struct erofs_mount_opts { #ifdef CONFIG_EROFS_FS_ZIP /* current strategy of how to use managed cache */ unsigned char cache_strategy; @@ -60,6 +60,10 @@ struct erofs_fs_context { unsigned int mount_opt; };
+struct erofs_fs_context { + struct erofs_mount_opts opt; +}; + /* all filesystem-wide lz4 configurations */ struct erofs_sb_lz4_info { /* # of pages needed for EROFS lz4 rolling decompression */ @@ -69,6 +73,8 @@ struct erofs_sb_lz4_info { };
struct erofs_sb_info { + struct erofs_mount_opts opt; /* options */ + #ifdef CONFIG_EROFS_FS_ZIP /* list for all registered superblocks, mainly for shrinker */ struct list_head list; @@ -108,8 +114,6 @@ struct erofs_sb_info { u8 volume_name[16]; /* volume name */ u32 feature_compat; u32 feature_incompat; - - struct erofs_fs_context ctx; /* options */ };
#define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info) @@ -121,9 +125,9 @@ struct erofs_sb_info { #define EROFS_MOUNT_DAX_ALWAYS 0x00000040 #define EROFS_MOUNT_DAX_NEVER 0x00000080
-#define clear_opt(ctx, option) ((ctx)->mount_opt &= ~EROFS_MOUNT_##option) -#define set_opt(ctx, option) ((ctx)->mount_opt |= EROFS_MOUNT_##option) -#define test_opt(ctx, option) ((ctx)->mount_opt & EROFS_MOUNT_##option) +#define clear_opt(opt, option) ((opt)->mount_opt &= ~EROFS_MOUNT_##option) +#define set_opt(opt, option) ((opt)->mount_opt |= EROFS_MOUNT_##option) +#define test_opt(opt, option) ((opt)->mount_opt & EROFS_MOUNT_##option)
enum { EROFS_ZIP_CACHE_DISABLED, diff --git a/fs/erofs/super.c b/fs/erofs/super.c index 11b88559f8bfa..25f6b8b37f287 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -340,15 +340,15 @@ static int erofs_read_superblock(struct super_block *sb) static void erofs_default_options(struct erofs_fs_context *ctx) { #ifdef CONFIG_EROFS_FS_ZIP - ctx->cache_strategy = EROFS_ZIP_CACHE_READAROUND; - ctx->max_sync_decompress_pages = 3; - ctx->readahead_sync_decompress = false; + ctx->opt.cache_strategy = EROFS_ZIP_CACHE_READAROUND; + ctx->opt.max_sync_decompress_pages = 3; + ctx->opt.readahead_sync_decompress = false; #endif #ifdef CONFIG_EROFS_FS_XATTR - set_opt(ctx, XATTR_USER); + set_opt(&ctx->opt, XATTR_USER); #endif #ifdef CONFIG_EROFS_FS_POSIX_ACL - set_opt(ctx, POSIX_ACL); + set_opt(&ctx->opt, POSIX_ACL); #endif }
@@ -392,12 +392,12 @@ static bool erofs_fc_set_dax_mode(struct fs_context *fc, unsigned int mode) switch (mode) { case EROFS_MOUNT_DAX_ALWAYS: warnfc(fc, "DAX enabled. Warning: EXPERIMENTAL, use at your own risk"); - set_opt(ctx, DAX_ALWAYS); - clear_opt(ctx, DAX_NEVER); + set_opt(&ctx->opt, DAX_ALWAYS); + clear_opt(&ctx->opt, DAX_NEVER); return true; case EROFS_MOUNT_DAX_NEVER: - set_opt(ctx, DAX_NEVER); - clear_opt(ctx, DAX_ALWAYS); + set_opt(&ctx->opt, DAX_NEVER); + clear_opt(&ctx->opt, DAX_ALWAYS); return true; default: DBG_BUGON(1); @@ -424,9 +424,9 @@ static int erofs_fc_parse_param(struct fs_context *fc, case Opt_user_xattr: #ifdef CONFIG_EROFS_FS_XATTR if (result.boolean) - set_opt(ctx, XATTR_USER); + set_opt(&ctx->opt, XATTR_USER); else - clear_opt(ctx, XATTR_USER); + clear_opt(&ctx->opt, XATTR_USER); #else errorfc(fc, "{,no}user_xattr options not supported"); #endif @@ -434,16 +434,16 @@ static int erofs_fc_parse_param(struct fs_context *fc, case Opt_acl: #ifdef CONFIG_EROFS_FS_POSIX_ACL if (result.boolean) - set_opt(ctx, POSIX_ACL); + set_opt(&ctx->opt, POSIX_ACL); else - clear_opt(ctx, POSIX_ACL); + clear_opt(&ctx->opt, POSIX_ACL); #else errorfc(fc, "{,no}acl options not supported"); #endif break; case Opt_cache_strategy: #ifdef CONFIG_EROFS_FS_ZIP - ctx->cache_strategy = result.uint_32; + ctx->opt.cache_strategy = result.uint_32; #else errorfc(fc, "compression not supported, cache_strategy ignored"); #endif @@ -540,15 +540,16 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) return -ENOMEM;
sb->s_fs_info = sbi; + sbi->opt = ctx->opt; sbi->dax_dev = fs_dax_get_by_bdev(sb->s_bdev); err = erofs_read_superblock(sb); if (err) return err;
- if (test_opt(ctx, DAX_ALWAYS) && + if (test_opt(&sbi->opt, DAX_ALWAYS) && !dax_supported(sbi->dax_dev, sb->s_bdev, EROFS_BLKSIZ, 0, bdev_nr_sectors(sb->s_bdev))) { errorfc(fc, "DAX unsupported by block device. Turning off DAX."); - clear_opt(ctx, DAX_ALWAYS); + clear_opt(&sbi->opt, DAX_ALWAYS); } sb->s_flags |= SB_RDONLY | SB_NOATIME; sb->s_maxbytes = MAX_LFS_FILESIZE; @@ -557,13 +558,11 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) sb->s_op = &erofs_sops; sb->s_xattr = erofs_xattr_handlers;
- if (test_opt(ctx, POSIX_ACL)) + if (test_opt(&sbi->opt, POSIX_ACL)) sb->s_flags |= SB_POSIXACL; else sb->s_flags &= ~SB_POSIXACL;
- sbi->ctx = *ctx; - #ifdef CONFIG_EROFS_FS_ZIP xa_init(&sbi->managed_pslots); #endif @@ -607,12 +606,12 @@ static int erofs_fc_reconfigure(struct fs_context *fc)
DBG_BUGON(!sb_rdonly(sb));
- if (test_opt(ctx, POSIX_ACL)) + if (test_opt(&ctx->opt, POSIX_ACL)) fc->sb_flags |= SB_POSIXACL; else fc->sb_flags &= ~SB_POSIXACL;
- sbi->ctx = *ctx; + sbi->opt = ctx->opt;
fc->sb_flags |= SB_RDONLY; return 0; @@ -640,7 +639,6 @@ static int erofs_init_fs_context(struct fs_context *fc) erofs_default_options(fc->fs_private);
fc->ops = &erofs_context_ops; - return 0; }
@@ -763,31 +761,31 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf) static int erofs_show_options(struct seq_file *seq, struct dentry *root) { struct erofs_sb_info *sbi = EROFS_SB(root->d_sb); - struct erofs_fs_context *ctx = &sbi->ctx; + struct erofs_mount_opts *opt = &sbi->opt;
#ifdef CONFIG_EROFS_FS_XATTR - if (test_opt(ctx, XATTR_USER)) + if (test_opt(opt, XATTR_USER)) seq_puts(seq, ",user_xattr"); else seq_puts(seq, ",nouser_xattr"); #endif #ifdef CONFIG_EROFS_FS_POSIX_ACL - if (test_opt(ctx, POSIX_ACL)) + if (test_opt(opt, POSIX_ACL)) seq_puts(seq, ",acl"); else seq_puts(seq, ",noacl"); #endif #ifdef CONFIG_EROFS_FS_ZIP - if (ctx->cache_strategy == EROFS_ZIP_CACHE_DISABLED) + if (opt->cache_strategy == EROFS_ZIP_CACHE_DISABLED) seq_puts(seq, ",cache_strategy=disabled"); - else if (ctx->cache_strategy == EROFS_ZIP_CACHE_READAHEAD) + else if (opt->cache_strategy == EROFS_ZIP_CACHE_READAHEAD) seq_puts(seq, ",cache_strategy=readahead"); - else if (ctx->cache_strategy == EROFS_ZIP_CACHE_READAROUND) + else if (opt->cache_strategy == EROFS_ZIP_CACHE_READAROUND) seq_puts(seq, ",cache_strategy=readaround"); #endif - if (test_opt(ctx, DAX_ALWAYS)) + if (test_opt(opt, DAX_ALWAYS)) seq_puts(seq, ",dax=always"); - if (test_opt(ctx, DAX_NEVER)) + if (test_opt(opt, DAX_NEVER)) seq_puts(seq, ",dax=never"); return 0; } diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c index 778f2c52295d1..01c581e93c5f8 100644 --- a/fs/erofs/xattr.c +++ b/fs/erofs/xattr.c @@ -429,7 +429,7 @@ static int shared_getxattr(struct inode *inode, struct getxattr_iter *it)
static bool erofs_xattr_user_list(struct dentry *dentry) { - return test_opt(&EROFS_SB(dentry->d_sb)->ctx, XATTR_USER); + return test_opt(&EROFS_SB(dentry->d_sb)->opt, XATTR_USER); }
static bool erofs_xattr_trusted_list(struct dentry *dentry) @@ -476,7 +476,7 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler,
switch (handler->flags) { case EROFS_XATTR_INDEX_USER: - if (!test_opt(&sbi->ctx, XATTR_USER)) + if (!test_opt(&sbi->opt, XATTR_USER)) return -EOPNOTSUPP; break; case EROFS_XATTR_INDEX_TRUSTED: diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index 3fd91a0efdbb7..c247b1bf57cc8 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -695,7 +695,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe, goto err_out;
/* preload all compressed pages (maybe downgrade role if necessary) */ - if (should_alloc_managed_pages(fe, sbi->ctx.cache_strategy, map->m_la)) + if (should_alloc_managed_pages(fe, sbi->opt.cache_strategy, map->m_la)) cache_strategy = TRYALLOC; else cache_strategy = DONTALLOC; @@ -797,7 +797,7 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io, /* Use workqueue and sync decompression for atomic contexts only */ if (in_atomic() || irqs_disabled()) { queue_work(z_erofs_workqueue, &io->u.work); - sbi->ctx.readahead_sync_decompress = true; + sbi->opt.readahead_sync_decompress = true; return; } z_erofs_decompressqueue_work(&io->u.work); @@ -1412,8 +1412,8 @@ static void z_erofs_readahead(struct readahead_control *rac) struct erofs_sb_info *const sbi = EROFS_I_SB(inode);
unsigned int nr_pages = readahead_count(rac); - bool sync = (sbi->ctx.readahead_sync_decompress && - nr_pages <= sbi->ctx.max_sync_decompress_pages); + bool sync = (sbi->opt.readahead_sync_decompress && + nr_pages <= sbi->opt.max_sync_decompress_pages); struct z_erofs_decompress_frontend f = DECOMPRESS_FRONTEND_INIT(inode); struct page *page, *head = NULL; LIST_HEAD(pagepool);
From: Xin Yin yinxin.x@bytedance.com
[ Upstream commit 18bddc5b67038722cb88fcf51fbf41a0277092cb ]
DAX can be used to share page cache between VMs, reducing guest memory overhead. And chunk based data format is widely used for VM and container image. So enable dax support for it, make erofs better used for VM scenarios.
Fixes: c5aa903a59db ("erofs: support reading chunk-based uncompressed files") Signed-off-by: Xin Yin yinxin.x@bytedance.com Reviewed-by: Gao Xiang hsiangkao@linux.alibaba.com Reviewed-by: Chao Yu chao@kernel.org Link: https://lore.kernel.org/r/20230711062130.7860-1-yinxin.x@bytedance.com Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/erofs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c index 3ff36514cff25..638bb70d0d65b 100644 --- a/fs/erofs/inode.c +++ b/fs/erofs/inode.c @@ -193,7 +193,8 @@ static struct page *erofs_read_inode(struct inode *inode,
inode->i_flags &= ~S_DAX; if (test_opt(&sbi->opt, DAX_ALWAYS) && S_ISREG(inode->i_mode) && - vi->datalayout == EROFS_INODE_FLAT_PLAIN) + (vi->datalayout == EROFS_INODE_FLAT_PLAIN || + vi->datalayout == EROFS_INODE_CHUNK_BASED)) inode->i_flags |= S_DAX; if (!nblks) /* measure inode.i_blocks as generic filesystems */
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 9373771aaed17f5c2c38485f785568abe3a9f8c1 ]
Quieten a gcc (11.3.0) build error or warning by checking the function call status and returning -EBUSY if the function call failed. This is similar to what several other wireless drivers do for the SIOCGIWRATE ioctl call when there is a locking problem.
drivers/net/wireless/cisco/airo.c: error: 'status_rid.currentXmitRate' is used uninitialized [-Werror=uninitialized]
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: Geert Uytterhoeven geert@linux-m68k.org Link: https://lore.kernel.org/r/39abf2c7-24a-f167-91da-ed4c5435d1c4@linux-m68k.org Link: https://lore.kernel.org/r/20230709133154.26206-1-rdunlap@infradead.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/cisco/airo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c index fc19ecbc4c088..bcbf197fa9372 100644 --- a/drivers/net/wireless/cisco/airo.c +++ b/drivers/net/wireless/cisco/airo.c @@ -6147,8 +6147,11 @@ static int airo_get_rate(struct net_device *dev, { struct airo_info *local = dev->ml_priv; StatusRid status_rid; /* Card status info */ + int ret;
- readStatusRid(local, &status_rid, 1); + ret = readStatusRid(local, &status_rid, 1); + if (ret) + return -EBUSY;
vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000; /* If more than one rate, set auto */
From: Pu Lehui pulehui@huawei.com
[ Upstream commit 4369016497319a9635702da010d02af1ebb1849d ]
Syzkaller reported a memory leak as follows:
BUG: memory leak unreferenced object 0xff110001198ef748 (size 192): comm "syz-executor.3", pid 17672, jiffies 4298118891 (age 9.906s) hex dump (first 32 bytes): 00 00 00 00 4a 19 00 00 80 ad e3 e4 fe ff c0 00 ....J........... 00 b2 d3 0c 01 00 11 ff 28 f5 8e 19 01 00 11 ff ........(....... backtrace: [<ffffffffadd28087>] __cpu_map_entry_alloc+0xf7/0xb00 [<ffffffffadd28d8e>] cpu_map_update_elem+0x2fe/0x3d0 [<ffffffffadc6d0fd>] bpf_map_update_value.isra.0+0x2bd/0x520 [<ffffffffadc7349b>] map_update_elem+0x4cb/0x720 [<ffffffffadc7d983>] __se_sys_bpf+0x8c3/0xb90 [<ffffffffb029cc80>] do_syscall_64+0x30/0x40 [<ffffffffb0400099>] entry_SYSCALL_64_after_hwframe+0x61/0xc6
BUG: memory leak unreferenced object 0xff110001198ef528 (size 192): comm "syz-executor.3", pid 17672, jiffies 4298118891 (age 9.906s) 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: [<ffffffffadd281f0>] __cpu_map_entry_alloc+0x260/0xb00 [<ffffffffadd28d8e>] cpu_map_update_elem+0x2fe/0x3d0 [<ffffffffadc6d0fd>] bpf_map_update_value.isra.0+0x2bd/0x520 [<ffffffffadc7349b>] map_update_elem+0x4cb/0x720 [<ffffffffadc7d983>] __se_sys_bpf+0x8c3/0xb90 [<ffffffffb029cc80>] do_syscall_64+0x30/0x40 [<ffffffffb0400099>] entry_SYSCALL_64_after_hwframe+0x61/0xc6
BUG: memory leak unreferenced object 0xff1100010fd93d68 (size 8): comm "syz-executor.3", pid 17672, jiffies 4298118891 (age 9.906s) hex dump (first 8 bytes): 00 00 00 00 00 00 00 00 ........ backtrace: [<ffffffffade5db3e>] kvmalloc_node+0x11e/0x170 [<ffffffffadd28280>] __cpu_map_entry_alloc+0x2f0/0xb00 [<ffffffffadd28d8e>] cpu_map_update_elem+0x2fe/0x3d0 [<ffffffffadc6d0fd>] bpf_map_update_value.isra.0+0x2bd/0x520 [<ffffffffadc7349b>] map_update_elem+0x4cb/0x720 [<ffffffffadc7d983>] __se_sys_bpf+0x8c3/0xb90 [<ffffffffb029cc80>] do_syscall_64+0x30/0x40 [<ffffffffb0400099>] entry_SYSCALL_64_after_hwframe+0x61/0xc6
In the cpu_map_update_elem flow, when kthread_stop is called before calling the threadfn of rcpu->kthread, since the KTHREAD_SHOULD_STOP bit of kthread has been set by kthread_stop, the threadfn of rcpu->kthread will never be executed, and rcpu->refcnt will never be 0, which will lead to the allocated rcpu, rcpu->queue and rcpu->queue->queue cannot be released.
Calling kthread_stop before executing kthread's threadfn will return -EINTR. We can complete the release of memory resources in this state.
Fixes: 6710e1126934 ("bpf: introduce new bpf cpu map type BPF_MAP_TYPE_CPUMAP") Signed-off-by: Pu Lehui pulehui@huawei.com Acked-by: Jesper Dangaard Brouer hawk@kernel.org Acked-by: Hou Tao houtao1@huawei.com Link: https://lore.kernel.org/r/20230711115848.2701559-1-pulehui@huaweicloud.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/cpumap.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-)
diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c index 585b2b77ccc4f..db6221773e43f 100644 --- a/kernel/bpf/cpumap.c +++ b/kernel/bpf/cpumap.c @@ -126,22 +126,6 @@ static void get_cpu_map_entry(struct bpf_cpu_map_entry *rcpu) atomic_inc(&rcpu->refcnt); }
-/* called from workqueue, to workaround syscall using preempt_disable */ -static void cpu_map_kthread_stop(struct work_struct *work) -{ - struct bpf_cpu_map_entry *rcpu; - - rcpu = container_of(work, struct bpf_cpu_map_entry, kthread_stop_wq); - - /* Wait for flush in __cpu_map_entry_free(), via full RCU barrier, - * as it waits until all in-flight call_rcu() callbacks complete. - */ - rcu_barrier(); - - /* kthread_stop will wake_up_process and wait for it to complete */ - kthread_stop(rcpu->kthread); -} - static void __cpu_map_ring_cleanup(struct ptr_ring *ring) { /* The tear-down procedure should have made sure that queue is @@ -169,6 +153,30 @@ static void put_cpu_map_entry(struct bpf_cpu_map_entry *rcpu) } }
+/* called from workqueue, to workaround syscall using preempt_disable */ +static void cpu_map_kthread_stop(struct work_struct *work) +{ + struct bpf_cpu_map_entry *rcpu; + int err; + + rcpu = container_of(work, struct bpf_cpu_map_entry, kthread_stop_wq); + + /* Wait for flush in __cpu_map_entry_free(), via full RCU barrier, + * as it waits until all in-flight call_rcu() callbacks complete. + */ + rcu_barrier(); + + /* kthread_stop will wake_up_process and wait for it to complete */ + err = kthread_stop(rcpu->kthread); + if (err) { + /* kthread_stop may be called before cpu_map_kthread_run + * is executed, so we need to release the memory related + * to rcpu. + */ + put_cpu_map_entry(rcpu); + } +} + static void cpu_map_bpf_prog_run_skb(struct bpf_cpu_map_entry *rcpu, struct list_head *listp, struct xdp_cpumap_stats *stats)
From: Ido Schimmel idosch@nvidia.com
[ Upstream commit d3f87278bcb80bd7f9519669d928b43320363d4f ]
The kernel does not currently validate that both the minimum and maximum ports of a port range are specified. This can lead user space to think that a filter matching on a port range was successfully added, when in fact it was not. For example, with a patched (buggy) iproute2 that only sends the minimum port, the following commands do not return an error:
# tc filter add dev swp1 ingress pref 1 proto ip flower ip_proto udp src_port 100-200 action pass
# tc filter add dev swp1 ingress pref 1 proto ip flower ip_proto udp dst_port 100-200 action pass
# tc filter show dev swp1 ingress filter protocol ip pref 1 flower chain 0 filter protocol ip pref 1 flower chain 0 handle 0x1 eth_type ipv4 ip_proto udp not_in_hw action order 1: gact action pass random type none pass val 0 index 1 ref 1 bind 1
filter protocol ip pref 1 flower chain 0 handle 0x2 eth_type ipv4 ip_proto udp not_in_hw action order 1: gact action pass random type none pass val 0 index 2 ref 1 bind 1
Fix by returning an error unless both ports are specified:
# tc filter add dev swp1 ingress pref 1 proto ip flower ip_proto udp src_port 100-200 action pass Error: Both min and max source ports must be specified. We have an error talking to the kernel
# tc filter add dev swp1 ingress pref 1 proto ip flower ip_proto udp dst_port 100-200 action pass Error: Both min and max destination ports must be specified. We have an error talking to the kernel
Fixes: 5c72299fba9d ("net: sched: cls_flower: Classify packets using port ranges") Signed-off-by: Ido Schimmel idosch@nvidia.com Reviewed-by: Petr Machata petrm@nvidia.com Acked-by: Jamal Hadi Salim jhs@mojatatu.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/cls_flower.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index ee137d5c20a4f..bff0a5f24aca8 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -784,6 +784,16 @@ static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key, TCA_FLOWER_KEY_PORT_SRC_MAX, &mask->tp_range.tp_max.src, TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_max.src));
+ if (mask->tp_range.tp_min.dst != mask->tp_range.tp_max.dst) { + NL_SET_ERR_MSG(extack, + "Both min and max destination ports must be specified"); + return -EINVAL; + } + if (mask->tp_range.tp_min.src != mask->tp_range.tp_max.src) { + NL_SET_ERR_MSG(extack, + "Both min and max source ports must be specified"); + return -EINVAL; + } if (mask->tp_range.tp_min.dst && mask->tp_range.tp_max.dst && ntohs(key->tp_range.tp_max.dst) <= ntohs(key->tp_range.tp_min.dst)) {
From: Jisheng Zhang jszhang@kernel.org
[ Upstream commit b690e266dae2f85f4dfea21fa6a05e3500a51054 ]
lkp reports below sparse warning when building for RV32: arch/riscv/mm/init.c:1204:48: sparse: warning: cast truncates bits from constant value (100000000 becomes 0)
IMO, the reason we didn't see this truncates bug in real world is "0" means MEMBLOCK_ALLOC_ACCESSIBLE in memblock and there's no RV32 HW with more than 4GB memory.
Fix it anyway to make sparse happy.
Fixes: decf89f86ecd ("riscv: try to allocate crashkern region from 32bit addressible memory") Signed-off-by: Jisheng Zhang jszhang@kernel.org Reported-by: kernel test robot lkp@intel.com Closes: https://lore.kernel.org/oe-kbuild-all/202306080034.SLiCiOMn-lkp@intel.com/ Link: https://lore.kernel.org/r/20230709171036.1906-1-jszhang@kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index f8bfbe983517c..d7115acab3501 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -843,7 +843,7 @@ static void __init reserve_crashkernel(void) */ crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE, search_start, - min(search_end, (unsigned long) SZ_4G)); + min(search_end, (unsigned long)(SZ_4G - 1))); if (crash_base == 0) { /* Try again without restricting region to 32bit addressible memory */ crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE,
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit f72207a5c0dbaaf6921cf9a6c0d2fd0bc249ea78 ]
The simple_write_to_buffer() function is designed to handle partial writes. It returns negatives on error, otherwise it returns the number of bytes that were able to be copied. This code doesn't check the return properly. We only know that the first byte is written, the rest of the buffer might be uninitialized.
There is no need to use the simple_write_to_buffer() function. Partial writes are prohibited by the "if (*ppos != 0)" check at the start of the function. Just use memdup_user() and copy the whole buffer.
Fixes: d3cbb907ae57 ("netdevsim: add ACL trap reporting cookie as a metadata") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Reviewed-by: Pavan Chebbi pavan.chebbi@broadcom.com Reviewed-by: Ido Schimmel idosch@nvidia.com Link: https://lore.kernel.org/r/7c1f950b-3a7d-4252-82a6-876e53078ef7@moroto.mounta... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/netdevsim/dev.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c index 94490dfae6568..a7279356299af 100644 --- a/drivers/net/netdevsim/dev.c +++ b/drivers/net/netdevsim/dev.c @@ -168,13 +168,10 @@ static ssize_t nsim_dev_trap_fa_cookie_write(struct file *file, cookie_len = (count - 1) / 2; if ((count - 1) % 2) return -EINVAL; - buf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN); - if (!buf) - return -ENOMEM;
- ret = simple_write_to_buffer(buf, count, ppos, data, count); - if (ret < 0) - goto free_buf; + buf = memdup_user(data, count); + if (IS_ERR(buf)) + return PTR_ERR(buf);
fa_cookie = kmalloc(sizeof(*fa_cookie) + cookie_len, GFP_KERNEL | __GFP_NOWARN);
From: Pedro Tammela pctammela@mojatatu.com
[ Upstream commit 150e33e62c1fa4af5aaab02776b6c3812711d478 ]
Eric Dumazet says[1]: ------- Speaking of psched_mtu(), I see that net/sched/sch_pie.c is using it without holding RTNL, so dev->mtu can be changed underneath. KCSAN could issue a warning. -------
Annotate dev->mtu with READ_ONCE() so KCSAN don't issue a warning.
[1] https://lore.kernel.org/all/CANn89iJoJO5VtaJ-2=_d2aOQhb0Xw8iBT_Cxqp2HyuS-zj6...
v1 -> v2: Fix commit message
Fixes: d4b36210c2e6 ("net: pkt_sched: PIE AQM scheme") Suggested-by: Eric Dumazet edumazet@google.com Signed-off-by: Pedro Tammela pctammela@mojatatu.com Reviewed-by: Simon Horman simon.horman@corigine.com Link: https://lore.kernel.org/r/20230711021634.561598-1-pctammela@mojatatu.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/pkt_sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 9cd2d4e84913f..d0d9dd2483dd3 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -141,7 +141,7 @@ extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1]; */ static inline unsigned int psched_mtu(const struct net_device *dev) { - return dev->mtu + dev->hard_header_len; + return READ_ONCE(dev->mtu) + dev->hard_header_len; }
static inline struct net *qdisc_net(struct Qdisc *q)
From: Pedro Tammela pctammela@mojatatu.com
[ Upstream commit 25369891fcef373540f8b4e0b3bccf77a04490d5 ]
Two parameters can be transformed into netlink policies and validated while parsing the netlink message.
Reviewed-by: Simon Horman simon.horman@corigine.com Acked-by: Jamal Hadi Salim jhs@mojatatu.com Signed-off-by: Pedro Tammela pctammela@mojatatu.com Signed-off-by: David S. Miller davem@davemloft.net Stable-dep-of: 3e337087c3b5 ("net/sched: sch_qfq: account for stab overhead in qfq_enqueue") Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/sch_qfq.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index 4c51aeb78f141..8fb30b20425f8 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -113,6 +113,7 @@
#define QFQ_MTU_SHIFT 16 /* to support TSO/GSO */ #define QFQ_MIN_LMAX 512 /* see qfq_slot_insert */ +#define QFQ_MAX_LMAX (1UL << QFQ_MTU_SHIFT)
#define QFQ_MAX_AGG_CLASSES 8 /* max num classes per aggregate allowed */
@@ -214,9 +215,14 @@ static struct qfq_class *qfq_find_class(struct Qdisc *sch, u32 classid) return container_of(clc, struct qfq_class, common); }
+static struct netlink_range_validation lmax_range = { + .min = QFQ_MIN_LMAX, + .max = QFQ_MAX_LMAX, +}; + static const struct nla_policy qfq_policy[TCA_QFQ_MAX + 1] = { - [TCA_QFQ_WEIGHT] = { .type = NLA_U32 }, - [TCA_QFQ_LMAX] = { .type = NLA_U32 }, + [TCA_QFQ_WEIGHT] = NLA_POLICY_RANGE(NLA_U32, 1, QFQ_MAX_WEIGHT), + [TCA_QFQ_LMAX] = NLA_POLICY_FULL_RANGE(NLA_U32, &lmax_range), };
/* @@ -408,17 +414,13 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, }
err = nla_parse_nested_deprecated(tb, TCA_QFQ_MAX, tca[TCA_OPTIONS], - qfq_policy, NULL); + qfq_policy, extack); if (err < 0) return err;
- if (tb[TCA_QFQ_WEIGHT]) { + if (tb[TCA_QFQ_WEIGHT]) weight = nla_get_u32(tb[TCA_QFQ_WEIGHT]); - if (!weight || weight > (1UL << QFQ_MAX_WSHIFT)) { - pr_notice("qfq: invalid weight %u\n", weight); - return -EINVAL; - } - } else + else weight = 1;
if (tb[TCA_QFQ_LMAX]) @@ -426,11 +428,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, else lmax = psched_mtu(qdisc_dev(sch));
- if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) { - pr_notice("qfq: invalid max length %u\n", lmax); - return -EINVAL; - } - inv_w = ONE_FP / weight; weight = ONE_FP / inv_w;
From: Pedro Tammela pctammela@mojatatu.com
[ Upstream commit 3e337087c3b5805fe0b8a46ba622a962880b5d64 ]
Lion says: ------- In the QFQ scheduler a similar issue to CVE-2023-31436 persists.
Consider the following code in net/sched/sch_qfq.c:
static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) { unsigned int len = qdisc_pkt_len(skb), gso_segs;
// ...
if (unlikely(cl->agg->lmax < len)) { pr_debug("qfq: increasing maxpkt from %u to %u for class %u", cl->agg->lmax, len, cl->common.classid); err = qfq_change_agg(sch, cl, cl->agg->class_weight, len); if (err) { cl->qstats.drops++; return qdisc_drop(skb, sch, to_free); }
// ...
}
Similarly to CVE-2023-31436, "lmax" is increased without any bounds checks according to the packet length "len". Usually this would not impose a problem because packet sizes are naturally limited.
This is however not the actual packet length, rather the "qdisc_pkt_len(skb)" which might apply size transformations according to "struct qdisc_size_table" as created by "qdisc_get_stab()" in net/sched/sch_api.c if the TCA_STAB option was set when modifying the qdisc.
A user may choose virtually any size using such a table.
As a result the same issue as in CVE-2023-31436 can occur, allowing heap out-of-bounds read / writes in the kmalloc-8192 cache. -------
We can create the issue with the following commands:
tc qdisc add dev $DEV root handle 1: stab mtu 2048 tsize 512 mpu 0 \ overhead 999999999 linklayer ethernet qfq tc class add dev $DEV parent 1: classid 1:1 htb rate 6mbit burst 15k tc filter add dev $DEV parent 1: matchall classid 1:1 ping -I $DEV 1.1.1.2
This is caused by incorrectly assuming that qdisc_pkt_len() returns a length within the QFQ_MIN_LMAX < len < QFQ_MAX_LMAX.
Fixes: 462dbc9101ac ("pkt_sched: QFQ Plus: fair-queueing service at DRR cost") Reported-by: Lion nnamrec@gmail.com Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: Jamal Hadi Salim jhs@mojatatu.com Signed-off-by: Pedro Tammela pctammela@mojatatu.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/sch_qfq.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index 8fb30b20425f8..3ba6a766601cf 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -381,8 +381,13 @@ static int qfq_change_agg(struct Qdisc *sch, struct qfq_class *cl, u32 weight, u32 lmax) { struct qfq_sched *q = qdisc_priv(sch); - struct qfq_aggregate *new_agg = qfq_find_agg(q, lmax, weight); + struct qfq_aggregate *new_agg;
+ /* 'lmax' can range from [QFQ_MIN_LMAX, pktlen + stab overhead] */ + if (lmax > QFQ_MAX_LMAX) + return -EINVAL; + + new_agg = qfq_find_agg(q, lmax, weight); if (new_agg == NULL) { /* create new aggregate */ new_agg = kzalloc(sizeof(*new_agg), GFP_ATOMIC); if (new_agg == NULL)
From: Keith Busch kbusch@kernel.org
[ Upstream commit a53232cb3abef51524f06ee9d8fbc3364ad95794 ]
We can get the nvme_queue from the req just as easily, so remove the duplicate path to the same structure to save some space.
Signed-off-by: Keith Busch kbusch@kernel.org Signed-off-by: Christoph Hellwig hch@lst.de Stable-dep-of: b8f6446b6853 ("nvme-pci: fix DMA direction of unmapping integrity data") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/pci.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index a646757f76b34..26b315c5025ad 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -224,7 +224,6 @@ struct nvme_queue { struct nvme_iod { struct nvme_request req; struct nvme_command cmd; - struct nvme_queue *nvmeq; bool use_sgl; int aborted; int npages; /* In the PRP list. 0 means small pool in use */ @@ -422,11 +421,6 @@ static int nvme_init_request(struct blk_mq_tag_set *set, struct request *req, { struct nvme_dev *dev = set->driver_data; struct nvme_iod *iod = blk_mq_rq_to_pdu(req); - int queue_idx = (set == &dev->tagset) ? hctx_idx + 1 : 0; - struct nvme_queue *nvmeq = &dev->queues[queue_idx]; - - BUG_ON(!nvmeq); - iod->nvmeq = nvmeq;
nvme_req(req)->ctrl = &dev->ctrl; nvme_req(req)->cmd = &iod->cmd; @@ -529,7 +523,7 @@ static void **nvme_pci_iod_list(struct request *req)
static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req) { - struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + struct nvme_queue *nvmeq = req->mq_hctx->driver_data; int nseg = blk_rq_nr_phys_segments(req); unsigned int avg_seg_size;
@@ -537,7 +531,7 @@ static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req)
if (!nvme_ctrl_sgl_supported(&dev->ctrl)) return false; - if (!iod->nvmeq->qid) + if (!nvmeq->qid) return false; if (!sgl_threshold || avg_seg_size < sgl_threshold) return false; @@ -846,6 +840,7 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, int nr_mapped;
if (blk_rq_nr_phys_segments(req) == 1) { + struct nvme_queue *nvmeq = req->mq_hctx->driver_data; struct bio_vec bv = req_bvec(req);
if (!is_pci_p2pdma_page(bv.bv_page)) { @@ -853,7 +848,7 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, return nvme_setup_prp_simple(dev, req, &cmnd->rw, &bv);
- if (iod->nvmeq->qid && sgl_threshold && + if (nvmeq->qid && sgl_threshold && nvme_ctrl_sgl_supported(&dev->ctrl)) return nvme_setup_sgl_simple(dev, req, &cmnd->rw, &bv); @@ -963,12 +958,16 @@ static blk_status_t nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
static void nvme_pci_complete_rq(struct request *req) { - struct nvme_iod *iod = blk_mq_rq_to_pdu(req); - struct nvme_dev *dev = iod->nvmeq->dev; + struct nvme_queue *nvmeq = req->mq_hctx->driver_data; + struct nvme_dev *dev = nvmeq->dev; + + if (blk_integrity_rq(req)) { + struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
- if (blk_integrity_rq(req)) dma_unmap_page(dev->dev, iod->meta_dma, rq_integrity_vec(req)->bv_len, rq_data_dir(req)); + } + if (blk_rq_nr_phys_segments(req)) nvme_unmap_data(dev, req); nvme_complete_rq(req); @@ -1194,8 +1193,7 @@ static int adapter_delete_sq(struct nvme_dev *dev, u16 sqid)
static void abort_endio(struct request *req, blk_status_t error) { - struct nvme_iod *iod = blk_mq_rq_to_pdu(req); - struct nvme_queue *nvmeq = iod->nvmeq; + struct nvme_queue *nvmeq = req->mq_hctx->driver_data;
dev_warn(nvmeq->dev->ctrl.device, "Abort status: 0x%x", nvme_req(req)->status); @@ -1249,7 +1247,7 @@ static void nvme_warn_reset(struct nvme_dev *dev, u32 csts) static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) { struct nvme_iod *iod = blk_mq_rq_to_pdu(req); - struct nvme_queue *nvmeq = iod->nvmeq; + struct nvme_queue *nvmeq = req->mq_hctx->driver_data; struct nvme_dev *dev = nvmeq->dev; struct request *abort_req; struct nvme_command cmd = { };
From: Ming Lei ming.lei@redhat.com
[ Upstream commit b8f6446b6853768cb99e7c201bddce69ca60c15e ]
DMA direction should be taken in dma_unmap_page() for unmapping integrity data.
Fix this DMA direction, and reported in Guangwu's test.
Reported-by: Guangwu Zhang guazhang@redhat.com Fixes: 4aedb705437f ("nvme-pci: split metadata handling from nvme_map_data / nvme_unmap_data") Signed-off-by: Ming Lei ming.lei@redhat.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Keith Busch kbusch@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 26b315c5025ad..bb3813e8474f4 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -965,7 +965,7 @@ static void nvme_pci_complete_rq(struct request *req) struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
dma_unmap_page(dev->dev, iod->meta_dma, - rq_integrity_vec(req)->bv_len, rq_data_dir(req)); + rq_integrity_vec(req)->bv_len, rq_dma_dir(req)); }
if (blk_rq_nr_phys_segments(req))
From: Konstantin Komarov almaz.alexandrovich@paragon-software.com
commit 0e8235d28f3a0e9eda9f02ff67ee566d5f42b66b upstream.
Added new functions index_hdr_check and index_buf_check. Now we check all stuff for correctness while reading from disk. Also fixed bug with stale nfs data.
Reported-by: van fantasy g1042620637@gmail.com Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Fixes: 82cae269cfa95 ("fs/ntfs3: Add initialization of super block") Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/index.c | 84 ++++++++++++++++++++++++++++++++++++---- fs/ntfs3/inode.c | 18 ++++---- fs/ntfs3/ntfs_fs.h | 4 - fs/ntfs3/run.c | 7 ++- fs/ntfs3/xattr.c | 109 ++++++++++++++++++++++++++++++++++------------------- 5 files changed, 164 insertions(+), 58 deletions(-)
--- a/fs/ntfs3/index.c +++ b/fs/ntfs3/index.c @@ -605,11 +605,58 @@ static const struct NTFS_DE *hdr_insert_ return e; }
+/* + * index_hdr_check + * + * return true if INDEX_HDR is valid + */ +static bool index_hdr_check(const struct INDEX_HDR *hdr, u32 bytes) +{ + u32 end = le32_to_cpu(hdr->used); + u32 tot = le32_to_cpu(hdr->total); + u32 off = le32_to_cpu(hdr->de_off); + + if (!IS_ALIGNED(off, 8) || tot > bytes || end > tot || + off + sizeof(struct NTFS_DE) > end) { + /* incorrect index buffer. */ + return false; + } + + return true; +} + +/* + * index_buf_check + * + * return true if INDEX_BUFFER seems is valid + */ +static bool index_buf_check(const struct INDEX_BUFFER *ib, u32 bytes, + const CLST *vbn) +{ + const struct NTFS_RECORD_HEADER *rhdr = &ib->rhdr; + u16 fo = le16_to_cpu(rhdr->fix_off); + u16 fn = le16_to_cpu(rhdr->fix_num); + + if (bytes <= offsetof(struct INDEX_BUFFER, ihdr) || + rhdr->sign != NTFS_INDX_SIGNATURE || + fo < sizeof(struct INDEX_BUFFER) + /* Check index buffer vbn. */ + || (vbn && *vbn != le64_to_cpu(ib->vbn)) || (fo % sizeof(short)) || + fo + fn * sizeof(short) >= bytes || + fn != ((bytes >> SECTOR_SHIFT) + 1)) { + /* incorrect index buffer. */ + return false; + } + + return index_hdr_check(&ib->ihdr, + bytes - offsetof(struct INDEX_BUFFER, ihdr)); +} + void fnd_clear(struct ntfs_fnd *fnd) { int i;
- for (i = 0; i < fnd->level; i++) { + for (i = fnd->level - 1; i >= 0; i--) { struct indx_node *n = fnd->nodes[i];
if (!n) @@ -828,9 +875,16 @@ int indx_init(struct ntfs_index *indx, s u32 t32; const struct INDEX_ROOT *root = resident_data(attr);
+ t32 = le32_to_cpu(attr->res.data_size); + if (t32 <= offsetof(struct INDEX_ROOT, ihdr) || + !index_hdr_check(&root->ihdr, + t32 - offsetof(struct INDEX_ROOT, ihdr))) { + goto out; + } + /* Check root fields. */ if (!root->index_block_clst) - return -EINVAL; + goto out;
indx->type = type; indx->idx2vbn_bits = __ffs(root->index_block_clst); @@ -842,19 +896,19 @@ int indx_init(struct ntfs_index *indx, s if (t32 < sbi->cluster_size) { /* Index record is smaller than a cluster, use 512 blocks. */ if (t32 != root->index_block_clst * SECTOR_SIZE) - return -EINVAL; + goto out;
/* Check alignment to a cluster. */ if ((sbi->cluster_size >> SECTOR_SHIFT) & (root->index_block_clst - 1)) { - return -EINVAL; + goto out; }
indx->vbn2vbo_bits = SECTOR_SHIFT; } else { /* Index record must be a multiple of cluster size. */ if (t32 != root->index_block_clst << sbi->cluster_bits) - return -EINVAL; + goto out;
indx->vbn2vbo_bits = sbi->cluster_bits; } @@ -862,7 +916,14 @@ int indx_init(struct ntfs_index *indx, s init_rwsem(&indx->run_lock);
indx->cmp = get_cmp_func(root); - return indx->cmp ? 0 : -EINVAL; + if (!indx->cmp) + goto out; + + return 0; + +out: + ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); + return -EINVAL; }
static struct indx_node *indx_new(struct ntfs_index *indx, @@ -1029,6 +1090,13 @@ int indx_read(struct ntfs_index *indx, s goto out;
ok: + if (!index_buf_check(ib, bytes, &vbn)) { + ntfs_inode_err(&ni->vfs_inode, "directory corrupted"); + ntfs_set_state(ni->mi.sbi, NTFS_DIRTY_ERROR); + err = -EINVAL; + goto out; + } + if (err == -E_NTFS_FIXUP) { ntfs_write_bh(ni->mi.sbi, &ib->rhdr, &in->nb, 0); err = 0; @@ -1623,9 +1691,9 @@ static int indx_insert_into_root(struct
if (err) { /* Restore root. */ - if (mi_resize_attr(mi, attr, -ds_root)) + if (mi_resize_attr(mi, attr, -ds_root)) { memcpy(attr, a_root, asize); - else { + } else { /* Bug? */ ntfs_set_state(sbi, NTFS_DIRTY_ERROR); } --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -81,7 +81,7 @@ static struct inode *ntfs_read_mft(struc le16_to_cpu(ref->seq), le16_to_cpu(rec->seq)); goto out; } else if (!is_rec_inuse(rec)) { - err = -EINVAL; + err = -ESTALE; ntfs_err(sb, "Inode r=%x is not in use!", (u32)ino); goto out; } @@ -92,8 +92,10 @@ static struct inode *ntfs_read_mft(struc goto out; }
- if (!is_rec_base(rec)) - goto Ok; + if (!is_rec_base(rec)) { + err = -EINVAL; + goto out; + }
/* Record should contain $I30 root. */ is_dir = rec->flags & RECORD_FLAG_DIR; @@ -472,7 +474,6 @@ end_enum: inode->i_flags |= S_NOSEC; }
-Ok: if (ino == MFT_REC_MFT && !sb->s_root) sbi->mft.ni = NULL;
@@ -526,6 +527,9 @@ struct inode *ntfs_iget5(struct super_bl make_bad_inode(inode); }
+ if (IS_ERR(inode) && name) + ntfs_set_state(sb->s_fs_info, NTFS_DIRTY_ERROR); + return inode; }
@@ -1647,10 +1651,8 @@ out6: ntfs_remove_reparse(sbi, IO_REPARSE_TAG_SYMLINK, &new_de->ref);
out5: - if (S_ISDIR(mode) || run_is_empty(&ni->file.run)) - goto out4; - - run_deallocate(sbi, &ni->file.run, false); + if (!S_ISDIR(mode)) + run_deallocate(sbi, &ni->file.run, false);
out4: clear_rec_inuse(rec); --- a/fs/ntfs3/ntfs_fs.h +++ b/fs/ntfs3/ntfs_fs.h @@ -789,12 +789,12 @@ int run_pack(const struct runs_tree *run u32 run_buf_size, CLST *packed_vcns); int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino, CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf, - u32 run_buf_size); + int run_buf_size);
#ifdef NTFS3_CHECK_FREE_CLST int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino, CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf, - u32 run_buf_size); + int run_buf_size); #else #define run_unpack_ex run_unpack #endif --- a/fs/ntfs3/run.c +++ b/fs/ntfs3/run.c @@ -872,12 +872,15 @@ error: */ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino, CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf, - u32 run_buf_size) + int run_buf_size) { u64 prev_lcn, vcn64, lcn, next_vcn; const u8 *run_last, *run_0; bool is_mft = ino == MFT_REC_MFT;
+ if (run_buf_size < 0) + return -EINVAL; + /* Check for empty. */ if (evcn + 1 == svcn) return 0; @@ -999,7 +1002,7 @@ int run_unpack(struct runs_tree *run, st */ int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino, CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf, - u32 run_buf_size) + int run_buf_size) { int ret, err; CLST next_vcn, lcn, len; --- a/fs/ntfs3/xattr.c +++ b/fs/ntfs3/xattr.c @@ -42,28 +42,26 @@ static inline size_t packed_ea_size(cons * Assume there is at least one xattr in the list. */ static inline bool find_ea(const struct EA_FULL *ea_all, u32 bytes, - const char *name, u8 name_len, u32 *off) + const char *name, u8 name_len, u32 *off, u32 *ea_sz) { - *off = 0; + u32 ea_size;
- if (!ea_all || !bytes) + *off = 0; + if (!ea_all) return false;
- for (;;) { + for (; *off < bytes; *off += ea_size) { const struct EA_FULL *ea = Add2Ptr(ea_all, *off); - u32 next_off = *off + unpacked_ea_size(ea); - - if (next_off > bytes) - return false; - + ea_size = unpacked_ea_size(ea); if (ea->name_len == name_len && - !memcmp(ea->name, name, name_len)) + !memcmp(ea->name, name, name_len)) { + if (ea_sz) + *ea_sz = ea_size; return true; - - *off = next_off; - if (next_off >= bytes) - return false; + } } + + return false; }
/* @@ -74,12 +72,12 @@ static inline bool find_ea(const struct static int ntfs_read_ea(struct ntfs_inode *ni, struct EA_FULL **ea, size_t add_bytes, const struct EA_INFO **info) { - int err; + int err = -EINVAL; struct ntfs_sb_info *sbi = ni->mi.sbi; struct ATTR_LIST_ENTRY *le = NULL; struct ATTRIB *attr_info, *attr_ea; void *ea_p; - u32 size; + u32 size, off, ea_size;
static_assert(le32_to_cpu(ATTR_EA_INFO) < le32_to_cpu(ATTR_EA));
@@ -96,24 +94,31 @@ static int ntfs_read_ea(struct ntfs_inod
*info = resident_data_ex(attr_info, sizeof(struct EA_INFO)); if (!*info) - return -EINVAL; + goto out;
/* Check Ea limit. */ size = le32_to_cpu((*info)->size); - if (size > sbi->ea_max_size) - return -EFBIG; + if (size > sbi->ea_max_size) { + err = -EFBIG; + goto out; + }
- if (attr_size(attr_ea) > sbi->ea_max_size) - return -EFBIG; + if (attr_size(attr_ea) > sbi->ea_max_size) { + err = -EFBIG; + goto out; + } + + if (!size) { + /* EA info persists, but xattr is empty. Looks like EA problem. */ + goto out; + }
/* Allocate memory for packed Ea. */ ea_p = kmalloc(size_add(size, add_bytes), GFP_NOFS); if (!ea_p) return -ENOMEM;
- if (!size) { - /* EA info persists, but xattr is empty. Looks like EA problem. */ - } else if (attr_ea->non_res) { + if (attr_ea->non_res) { struct runs_tree run;
run_init(&run); @@ -124,24 +129,52 @@ static int ntfs_read_ea(struct ntfs_inod run_close(&run);
if (err) - goto out; + goto out1; } else { void *p = resident_data_ex(attr_ea, size);
- if (!p) { - err = -EINVAL; - goto out; - } + if (!p) + goto out1; memcpy(ea_p, p, size); }
memset(Add2Ptr(ea_p, size), 0, add_bytes); + + /* Check all attributes for consistency. */ + for (off = 0; off < size; off += ea_size) { + const struct EA_FULL *ef = Add2Ptr(ea_p, off); + u32 bytes = size - off; + + /* Check if we can use field ea->size. */ + if (bytes < sizeof(ef->size)) + goto out1; + + if (ef->size) { + ea_size = le32_to_cpu(ef->size); + if (ea_size > bytes) + goto out1; + continue; + } + + /* Check if we can use fields ef->name_len and ef->elength. */ + if (bytes < offsetof(struct EA_FULL, name)) + goto out1; + + ea_size = ALIGN(struct_size(ef, name, + 1 + ef->name_len + + le16_to_cpu(ef->elength)), + 4); + if (ea_size > bytes) + goto out1; + } + *ea = ea_p; return 0;
-out: +out1: kfree(ea_p); - *ea = NULL; +out: + ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); return err; }
@@ -163,6 +196,7 @@ static ssize_t ntfs_list_ea(struct ntfs_ const struct EA_FULL *ea; u32 off, size; int err; + int ea_size; size_t ret;
err = ntfs_read_ea(ni, &ea_all, 0, &info); @@ -175,8 +209,9 @@ static ssize_t ntfs_list_ea(struct ntfs_ size = le32_to_cpu(info->size);
/* Enumerate all xattrs. */ - for (ret = 0, off = 0; off < size; off += unpacked_ea_size(ea)) { + for (ret = 0, off = 0; off < size; off += ea_size) { ea = Add2Ptr(ea_all, off); + ea_size = unpacked_ea_size(ea);
if (!ea->name_len) break; @@ -230,7 +265,8 @@ static int ntfs_get_ea(struct inode *ino goto out;
/* Enumerate all xattrs. */ - if (!find_ea(ea_all, le32_to_cpu(info->size), name, name_len, &off)) { + if (!find_ea(ea_all, le32_to_cpu(info->size), name, name_len, &off, + NULL)) { err = -ENODATA; goto out; } @@ -272,7 +308,7 @@ static noinline int ntfs_set_ea(struct i struct EA_FULL *new_ea; struct EA_FULL *ea_all = NULL; size_t add, new_pack; - u32 off, size; + u32 off, size, ea_sz; __le16 size_pack; struct ATTRIB *attr; struct ATTR_LIST_ENTRY *le; @@ -306,9 +342,8 @@ static noinline int ntfs_set_ea(struct i size_pack = ea_info.size_pack; }
- if (info && find_ea(ea_all, size, name, name_len, &off)) { + if (info && find_ea(ea_all, size, name, name_len, &off, &ea_sz)) { struct EA_FULL *ea; - size_t ea_sz;
if (flags & XATTR_CREATE) { err = -EEXIST; @@ -331,8 +366,6 @@ static noinline int ntfs_set_ea(struct i if (ea->flags & FILE_NEED_EA) le16_add_cpu(&ea_info.count, -1);
- ea_sz = unpacked_ea_size(ea); - le16_add_cpu(&ea_info.size_pack, 0 - packed_ea_size(ea));
memmove(ea, Add2Ptr(ea, ea_sz), size - off - ea_sz);
From: Chao Yu chao@kernel.org
commit d8189834d4348ae608083e1f1f53792cfcc2a9bc upstream.
butt3rflyh4ck reports a bug as below:
When a thread always calls F2FS_IOC_RESIZE_FS to resize fs, if resize fs is failed, f2fs kernel thread would invoke callback function to update f2fs io info, it would call f2fs_write_end_io and may trigger null-ptr-deref in NODE_MAPPING.
general protection fault, probably for non-canonical address KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037] RIP: 0010:NODE_MAPPING fs/f2fs/f2fs.h:1972 [inline] RIP: 0010:f2fs_write_end_io+0x727/0x1050 fs/f2fs/data.c:370 <TASK> bio_endio+0x5af/0x6c0 block/bio.c:1608 req_bio_endio block/blk-mq.c:761 [inline] blk_update_request+0x5cc/0x1690 block/blk-mq.c:906 blk_mq_end_request+0x59/0x4c0 block/blk-mq.c:1023 lo_complete_rq+0x1c6/0x280 drivers/block/loop.c:370 blk_complete_reqs+0xad/0xe0 block/blk-mq.c:1101 __do_softirq+0x1d4/0x8ef kernel/softirq.c:571 run_ksoftirqd kernel/softirq.c:939 [inline] run_ksoftirqd+0x31/0x60 kernel/softirq.c:931 smpboot_thread_fn+0x659/0x9e0 kernel/smpboot.c:164 kthread+0x33e/0x440 kernel/kthread.c:379 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308
The root cause is below race case can cause leaving dirty metadata in f2fs after filesystem is remount as ro:
Thread A Thread B - f2fs_ioc_resize_fs - f2fs_readonly --- return false - f2fs_resize_fs - f2fs_remount - write_checkpoint - set f2fs as ro - free_segment_range - update meta_inode's data
Then, if f2fs_put_super() fails to write_checkpoint due to readonly status, and meta_inode's dirty data will be writebacked after node_inode is put, finally, f2fs_write_end_io will access NULL pointer on sbi->node_inode.
Thread A IRQ context - f2fs_put_super - write_checkpoint fails - iput(node_inode) - node_inode = NULL - iput(meta_inode) - write_inode_now - f2fs_write_meta_page - f2fs_write_end_io - NODE_MAPPING(sbi) : access NULL pointer on node_inode
Fixes: b4b10061ef98 ("f2fs: refactor resize_fs to avoid meta updates in progress") Reported-by: butt3rflyh4ck butterflyhuangxx@gmail.com Closes: https://lore.kernel.org/r/1684480657-2375-1-git-send-email-yangtiezhu@loongs... Tested-by: butt3rflyh4ck butterflyhuangxx@gmail.com Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Stefan Ghinea stefan.ghinea@windriver.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 2 +- fs/f2fs/gc.c | 21 ++++++++++++++++++--- 3 files changed, 20 insertions(+), 5 deletions(-)
--- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3660,7 +3660,7 @@ block_t f2fs_start_bidx_of_node(unsigned int f2fs_gc(struct f2fs_sb_info *sbi, bool sync, bool background, bool force, unsigned int segno); void f2fs_build_gc_manager(struct f2fs_sb_info *sbi); -int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count); +int f2fs_resize_fs(struct file *filp, __u64 block_count); int __init f2fs_create_garbage_collection_cache(void); void f2fs_destroy_garbage_collection_cache(void);
--- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3251,7 +3251,7 @@ static int f2fs_ioc_resize_fs(struct fil sizeof(block_count))) return -EFAULT;
- return f2fs_resize_fs(sbi, block_count); + return f2fs_resize_fs(filp, block_count); }
static int f2fs_ioc_enable_verity(struct file *filp, unsigned long arg) --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1992,8 +1992,9 @@ static void update_fs_metadata(struct f2 } }
-int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count) +int f2fs_resize_fs(struct file *filp, __u64 block_count) { + struct f2fs_sb_info *sbi = F2FS_I_SB(file_inode(filp)); __u64 old_block_count, shrunk_blocks; struct cp_control cpc = { CP_RESIZE, 0, 0, 0 }; unsigned int secs; @@ -2031,12 +2032,18 @@ int f2fs_resize_fs(struct f2fs_sb_info * return -EINVAL; }
+ err = mnt_want_write_file(filp); + if (err) + return err; + shrunk_blocks = old_block_count - block_count; secs = div_u64(shrunk_blocks, BLKS_PER_SEC(sbi));
/* stop other GC */ - if (!down_write_trylock(&sbi->gc_lock)) - return -EAGAIN; + if (!down_write_trylock(&sbi->gc_lock)) { + err = -EAGAIN; + goto out_drop_write; + }
/* stop CP to protect MAIN_SEC in free_segment_range */ f2fs_lock_op(sbi); @@ -2056,10 +2063,18 @@ int f2fs_resize_fs(struct f2fs_sb_info * out_unlock: f2fs_unlock_op(sbi); up_write(&sbi->gc_lock); +out_drop_write: + mnt_drop_write_file(filp); if (err) return err;
freeze_super(sbi->sb); + + if (f2fs_readonly(sbi->sb)) { + thaw_super(sbi->sb); + return -EROFS; + } + down_write(&sbi->gc_lock); down_write(&sbi->cp_global_sem);
From: Mario Limonciello mario.limonciello@amd.com
commit a855724dc08b8cb0c13ab1e065a4922f1e5a7552 upstream.
commit 4e5a04be88fe ("pinctrl: amd: disable and mask interrupts on probe") had a mistake in loop iteration 63 that it would clear offset 0xFC instead of 0x100. Offset 0xFC is actually `WAKE_INT_MASTER_REG`. This was clearing bits 13 and 15 from the register which significantly changed the expected handling for some platforms for GPIO0.
Cc: stable@vger.kernel.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=217315 Signed-off-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20230421120625.3366-3-mario.limonciello@amd.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/pinctrl-amd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -883,9 +883,9 @@ static void amd_gpio_irq_init(struct amd
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
- pin_reg = readl(gpio_dev->base + i * 4); + pin_reg = readl(gpio_dev->base + pin * 4); pin_reg &= ~mask; - writel(pin_reg, gpio_dev->base + i * 4); + writel(pin_reg, gpio_dev->base + pin * 4);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); }
From: Mario Limonciello mario.limonciello@amd.com
commit 968ab9261627fa305307e3935ca1a32fcddd36cb upstream.
commit 4e5a04be88fe ("pinctrl: amd: disable and mask interrupts on probe") had a mistake in loop iteration 63 that it would clear offset 0xFC instead of 0x100. Offset 0xFC is actually `WAKE_INT_MASTER_REG`. This was clearing bits 13 and 15 from the register which significantly changed the expected handling for some platforms for GPIO0.
commit b26cd9325be4 ("pinctrl: amd: Disable and mask interrupts on resume") actually fixed this bug, but lead to regressions on Lenovo Z13 and some other systems. This is because there was no handling in the driver for bit 15 debounce behavior.
Quoting a public BKDG: ``` EnWinBlueBtn. Read-write. Reset: 0. 0=GPIO0 detect debounced power button; Power button override is 4 seconds. 1=GPIO0 detect debounced power button in S3/S5/S0i3, and detect "pressed less than 2 seconds" and "pressed 2~10 seconds" in S0; Power button override is 10 seconds ```
Cross referencing the same master register in Windows it's obvious that Windows doesn't use debounce values in this configuration. So align the Linux driver to do this as well. This fixes wake on lid when WAKE_INT_MASTER_REG is properly programmed.
Cc: stable@vger.kernel.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=217315 Signed-off-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20230421120625.3366-2-mario.limonciello@amd.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/pinctrl-amd.c | 7 +++++++ drivers/pinctrl/pinctrl-amd.h | 1 + 2 files changed, 8 insertions(+)
--- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -126,6 +126,12 @@ static int amd_gpio_set_debounce(struct struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
raw_spin_lock_irqsave(&gpio_dev->lock, flags); + + /* Use special handling for Pin0 debounce */ + pin_reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG); + if (pin_reg & INTERNAL_GPIO0_DEBOUNCE) + debounce = 0; + pin_reg = readl(gpio_dev->base + offset * 4);
if (debounce) { @@ -223,6 +229,7 @@ static void amd_gpio_dbg_show(struct seq char debounce_value[40]; char *debounce_enable;
+ seq_printf(s, "WAKE_INT_MASTER_REG: 0x%08x\n", readl(gpio_dev->base + WAKE_INT_MASTER_REG)); for (bank = 0; bank < gpio_dev->hwbank_num; bank++) { seq_printf(s, "GPIO bank%d\t", bank);
--- a/drivers/pinctrl/pinctrl-amd.h +++ b/drivers/pinctrl/pinctrl-amd.h @@ -17,6 +17,7 @@ #define AMD_GPIO_PINS_BANK3 32
#define WAKE_INT_MASTER_REG 0xfc +#define INTERNAL_GPIO0_DEBOUNCE (1 << 15) #define EOI_MASK (1 << 29)
#define WAKE_INT_STATUS_REG0 0x2f8
From: Kornel Dulęba korneld@chromium.org
commit 0cf9e48ff22e15f3f0882991f33d23ccc5ae1d01 upstream.
Leverage gpiochip_line_is_irq to check whether a pin has an irq associated with it. The previous check ("irq == 0") didn't make much sense. The irq variable refers to the pinctrl irq, and has nothing do to with an individual pin.
On some systems, during suspend/resume cycle, the firmware leaves an interrupt enabled on a pin that is not used by the kernel. Without this patch that caused an interrupt storm.
Cc: stable@vger.kernel.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=217315 Signed-off-by: Kornel Dulęba korneld@chromium.org Reviewed-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20230421120625.3366-4-mario.limonciello@amd.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/pinctrl-amd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -653,21 +653,21 @@ static bool do_amd_gpio_irq_handler(int * We must read the pin register again, in case the * value was changed while executing * generic_handle_domain_irq() above. - * If we didn't find a mapping for the interrupt, - * disable it in order to avoid a system hang caused - * by an interrupt storm. + * If the line is not an irq, disable it in order to + * avoid a system hang caused by an interrupt storm. */ raw_spin_lock_irqsave(&gpio_dev->lock, flags); regval = readl(regs + i); - if (irq == 0) { - regval &= ~BIT(INTERRUPT_ENABLE_OFF); + if (!gpiochip_line_is_irq(gc, irqnr + i)) { + regval &= ~BIT(INTERRUPT_MASK_OFF); dev_dbg(&gpio_dev->pdev->dev, "Disabling spurious GPIO IRQ %d\n", irqnr + i); + } else { + ret = true; } writel(regval, regs + i); raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); - ret = true; } } /* did not cause wake on resume context for shared IRQ */
From: Mario Limonciello mario.limonciello@amd.com
commit 0d5ace1a07f7e846d0f6d972af60d05515599d0b upstream.
It's uncommon to use debounce on any other pin, but technically we should only set debounce to 0 when working off GPIO0.
Cc: stable@vger.kernel.org Tested-by: Jan Visser starquake@linuxeverywhere.org Fixes: 968ab9261627 ("pinctrl: amd: Detect internal GPIO0 debounce handling") Signed-off-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20230705133005.577-2-mario.limonciello@amd.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/pinctrl-amd.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -128,9 +128,11 @@ static int amd_gpio_set_debounce(struct raw_spin_lock_irqsave(&gpio_dev->lock, flags);
/* Use special handling for Pin0 debounce */ - pin_reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG); - if (pin_reg & INTERNAL_GPIO0_DEBOUNCE) - debounce = 0; + if (offset == 0) { + pin_reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG); + if (pin_reg & INTERNAL_GPIO0_DEBOUNCE) + debounce = 0; + }
pin_reg = readl(gpio_dev->base + offset * 4);
From: Jarkko Sakkinen jarkko.sakkinen@tuni.fi
commit f4032d615f90970d6c3ac1d9c0bce3351eb4445c upstream.
/dev/vtpmx is made visible before 'workqueue' is initialized, which can lead to a memory corruption in the worst case scenario.
Address this by initializing 'workqueue' as the very first step of the driver initialization.
Cc: stable@vger.kernel.org Fixes: 6f99612e2500 ("tpm: Proxy driver for supporting multiple emulated TPMs") Reviewed-by: Stefan Berger stefanb@linux.ibm.com Signed-off-by: Jarkko Sakkinen jarkko.sakkinen@tuni.fi Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/tpm/tpm_vtpm_proxy.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-)
--- a/drivers/char/tpm/tpm_vtpm_proxy.c +++ b/drivers/char/tpm/tpm_vtpm_proxy.c @@ -683,37 +683,21 @@ static struct miscdevice vtpmx_miscdev = .fops = &vtpmx_fops, };
-static int vtpmx_init(void) -{ - return misc_register(&vtpmx_miscdev); -} - -static void vtpmx_cleanup(void) -{ - misc_deregister(&vtpmx_miscdev); -} - static int __init vtpm_module_init(void) { int rc;
- rc = vtpmx_init(); - if (rc) { - pr_err("couldn't create vtpmx device\n"); - return rc; - } - workqueue = create_workqueue("tpm-vtpm"); if (!workqueue) { pr_err("couldn't create workqueue\n"); - rc = -ENOMEM; - goto err_vtpmx_cleanup; + return -ENOMEM; }
- return 0; - -err_vtpmx_cleanup: - vtpmx_cleanup(); + rc = misc_register(&vtpmx_miscdev); + if (rc) { + pr_err("couldn't create vtpmx device\n"); + destroy_workqueue(workqueue); + }
return rc; } @@ -721,7 +705,7 @@ err_vtpmx_cleanup: static void __exit vtpm_module_exit(void) { destroy_workqueue(workqueue); - vtpmx_cleanup(); + misc_deregister(&vtpmx_miscdev); }
module_init(vtpm_module_init);
From: Arseniy Krasnov AVKrasnov@sberdevices.ru
commit 98480a181a08ceeede417e5b28f6d0429d8ae156 upstream.
Meson NAND controller requires 8 bytes alignment for DMA addresses, otherwise it "aligns" passed address by itself thus accessing invalid location in the provided buffer. This patch makes unaligned buffers to be reallocated to become valid.
Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller") Cc: Stable@vger.kernel.org Signed-off-by: Arseniy Krasnov AVKrasnov@sberdevices.ru Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20230615080815.3291006-1-AVKrasnov@sberdev... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/meson_nand.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/mtd/nand/raw/meson_nand.c +++ b/drivers/mtd/nand/raw/meson_nand.c @@ -72,6 +72,7 @@ #define GENCMDIADDRH(aih, addr) ((aih) | (((addr) >> 16) & 0xffff))
#define DMA_DIR(dir) ((dir) ? NFC_CMD_N2M : NFC_CMD_M2N) +#define DMA_ADDR_ALIGN 8
#define ECC_CHECK_RETURN_FF (-1)
@@ -838,6 +839,9 @@ static int meson_nfc_read_oob(struct nan
static bool meson_nfc_is_buffer_dma_safe(const void *buffer) { + if ((uintptr_t)buffer % DMA_ADDR_ALIGN) + return false; + if (virt_addr_valid(buffer) && (!object_is_on_stack(buffer))) return true; return false;
From: Florian Fainelli florian.fainelli@broadcom.com
commit 1b5ea7ffb7a3bdfffb4b7f40ce0d20a3372ee405 upstream.
With support for Ethernet PHY LEDs having been added, while unregistering a MDIO bus and its child device liks PHYs there may be "late" accesses to the MDIO bus. One typical use case is setting the PHY LEDs brightness to OFF for instance.
We need to ensure that the MDIO bus controller remains entirely functional since it runs off the main GENET adapter clock.
Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20230617155500.4005881-1-andrew@lunn.ch/ Fixes: 9a4e79697009 ("net: bcmgenet: utilize generic Broadcom UniMAC MDIO controller driver") Signed-off-by: Florian Fainelli florian.fainelli@broadcom.com Reviewed-by: Andrew Lunn andrew@lunn.ch Link: https://lore.kernel.org/r/20230622103107.1760280-1-florian.fainelli@broadcom... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -627,5 +627,7 @@ void bcmgenet_mii_exit(struct net_device if (of_phy_is_fixed_link(dn)) of_phy_deregister_fixed_link(dn); of_node_put(priv->phy_dn); + clk_prepare_enable(priv->clk); platform_device_unregister(priv->mii_pdev); + clk_disable_unprepare(priv->clk); }
From: Ryan Roberts ryan.roberts@arm.com
commit c11d34fa139e4b0fb4249a30f37b178353533fa1 upstream.
It is racy to non-atomically read a pte, then clear the young bit, then write it back as this could discard dirty information. Further, it is bad practice to directly set a pte entry within a table. Instead clearing young must go through the arch-provided helper, ptep_test_and_clear_young() to ensure it is modified atomically and to give the arch code visibility and allow it to check (and potentially modify) the operation.
Link: https://lkml.kernel.org/r/20230602092949.545577-3-ryan.roberts@arm.com Fixes: 3f49584b262c ("mm/damon: implement primitives for the virtual memory address spaces"). Signed-off-by: Ryan Roberts ryan.roberts@arm.com Reviewed-by: Zi Yan ziy@nvidia.com Reviewed-by: SeongJae Park sj@kernel.org Reviewed-by: Mike Rapoport (IBM) rppt@kernel.org Cc: Christoph Hellwig hch@lst.de Cc: Kirill A. Shutemov kirill.shutemov@linux.intel.com Cc: Lorenzo Stoakes lstoakes@gmail.com Cc: Matthew Wilcox (Oracle) willy@infradead.org Cc: Uladzislau Rezki (Sony) urezki@gmail.com Cc: Yu Zhao yuzhao@google.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: SeongJae Park sj@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/damon/vaddr.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-)
--- a/mm/damon/vaddr.c +++ b/mm/damon/vaddr.c @@ -393,7 +393,7 @@ static struct page *damon_get_page(unsig return page; }
-static void damon_ptep_mkold(pte_t *pte, struct mm_struct *mm, +static void damon_ptep_mkold(pte_t *pte, struct vm_area_struct *vma, unsigned long addr) { bool referenced = false; @@ -402,13 +402,11 @@ static void damon_ptep_mkold(pte_t *pte, if (!page) return;
- if (pte_young(*pte)) { + if (ptep_test_and_clear_young(vma, addr, pte)) referenced = true; - *pte = pte_mkold(*pte); - }
#ifdef CONFIG_MMU_NOTIFIER - if (mmu_notifier_clear_young(mm, addr, addr + PAGE_SIZE)) + if (mmu_notifier_clear_young(vma->vm_mm, addr, addr + PAGE_SIZE)) referenced = true; #endif /* CONFIG_MMU_NOTIFIER */
@@ -419,7 +417,7 @@ static void damon_ptep_mkold(pte_t *pte, put_page(page); }
-static void damon_pmdp_mkold(pmd_t *pmd, struct mm_struct *mm, +static void damon_pmdp_mkold(pmd_t *pmd, struct vm_area_struct *vma, unsigned long addr) { #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -429,13 +427,11 @@ static void damon_pmdp_mkold(pmd_t *pmd, if (!page) return;
- if (pmd_young(*pmd)) { + if (pmdp_test_and_clear_young(vma, addr, pmd)) referenced = true; - *pmd = pmd_mkold(*pmd); - }
#ifdef CONFIG_MMU_NOTIFIER - if (mmu_notifier_clear_young(mm, addr, + if (mmu_notifier_clear_young(vma->vm_mm, addr, addr + ((1UL) << HPAGE_PMD_SHIFT))) referenced = true; #endif /* CONFIG_MMU_NOTIFIER */ @@ -462,7 +458,7 @@ static int damon_mkold_pmd_entry(pmd_t * }
if (pmd_huge(*pmd)) { - damon_pmdp_mkold(pmd, walk->mm, addr); + damon_pmdp_mkold(pmd, walk->vma, addr); spin_unlock(ptl); return 0; } @@ -474,7 +470,7 @@ static int damon_mkold_pmd_entry(pmd_t * pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); if (!pte_present(*pte)) goto out; - damon_ptep_mkold(pte, walk->mm, addr); + damon_ptep_mkold(pte, walk->vma, addr); out: pte_unmap_unlock(pte, ptl); return 0;
From: Naveen N Rao naveen@kernel.org
commit 25ea739ea1d4d3de41acc4f4eb2d1a97eee0eb75 upstream.
binutils v2.37 drops unused section symbols, which prevents recordmcount from capturing mcount locations in sections that have no non-weak symbols. This results in a build failure with a message such as: Cannot find symbol for section 12: .text.perf_callchain_kernel. kernel/events/callchain.o: failed
The change to binutils was reverted for v2.38, so this behavior is specific to binutils v2.37: https://sourceware.org/git/?p=binutils-gdb.git%3Ba=commit%3Bh=c09c8b42021180...
Objtool is able to cope with such sections, so this issue is specific to recordmcount.
Fail the build and print a warning if binutils v2.37 is detected and if we are using recordmcount.
Cc: stable@vger.kernel.org Suggested-by: Joel Stanley joel@jms.id.au Signed-off-by: Naveen N Rao naveen@kernel.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230530061436.56925-1-naveen@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -444,3 +444,11 @@ checkbin: echo -n '*** Please use a different binutils version.' ; \ false ; \ fi + @if test "x${CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT}" = "xy" -a \ + "x${CONFIG_LD_IS_BFD}" = "xy" -a \ + "${CONFIG_LD_VERSION}" = "23700" ; then \ + echo -n '*** binutils 2.37 drops unused section symbols, which recordmcount ' ; \ + echo 'is unable to handle.' ; \ + echo '*** Please use a different binutils version.' ; \ + false ; \ + fi
From: Ekansh Gupta quic_ekangupt@quicinc.com
commit 0b4e32df3e09406b835d8230b9331273f2805058 upstream.
A process can spawn a PD on DSP with some attributes that can be associated with the PD during spawn and run. The invocation corresponding to the create request with attributes has total 4 buffers at the DSP side implementation. If this number is not correct, the invocation is expected to fail on DSP. Added change to use correct number of buffer count for creating fastrpc scalar.
Fixes: d73f71c7c6ee ("misc: fastrpc: Add support for create remote init process") Cc: stable stable@kernel.org Tested-by: Ekansh Gupta quic_ekangupt@quicinc.com Signed-off-by: Ekansh Gupta quic_ekangupt@quicinc.com Message-ID: 1686743685-21715-1-git-send-email-quic_ekangupt@quicinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/fastrpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -1108,7 +1108,7 @@ static int fastrpc_init_create_process(s
sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0); if (init.attrs) - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 6, 0); + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 4, 0);
err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, args);
From: Michael Ellerman mpe@ellerman.id.au
commit 5bcedc5931e7bd6928a2d8207078d4cb476b3b55 upstream.
Nageswara reported that /proc/self/status was showing "vulnerable" for the Speculation_Store_Bypass feature on Power10, eg:
$ grep Speculation_Store_Bypass: /proc/self/status Speculation_Store_Bypass: vulnerable
But at the same time the sysfs files, and lscpu, were showing "Not affected".
This turns out to simply be a bug in the reporting of the Speculation_Store_Bypass, aka. PR_SPEC_STORE_BYPASS, case.
When SEC_FTR_STF_BARRIER was added, so that firmware could communicate the vulnerability was not present, the code in ssb_prctl_get() was not updated to check the new flag.
So add the check for SEC_FTR_STF_BARRIER being disabled. Rather than adding the new check to the existing if block and expanding the comment to cover both cases, rewrite the three cases to be separate so they can be commented separately for clarity.
Fixes: 84ed26fd00c5 ("powerpc/security: Add a security feature for STF barrier") Cc: stable@vger.kernel.org # v5.14+ Reported-by: Nageswara R Sastry rnsastry@linux.ibm.com Tested-by: Nageswara R Sastry rnsastry@linux.ibm.com Reviewed-by: Russell Currey ruscur@russell.cc Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230517074945.53188-1-mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/security.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-)
--- a/arch/powerpc/kernel/security.c +++ b/arch/powerpc/kernel/security.c @@ -363,26 +363,27 @@ ssize_t cpu_show_spec_store_bypass(struc
static int ssb_prctl_get(struct task_struct *task) { + /* + * The STF_BARRIER feature is on by default, so if it's off that means + * firmware has explicitly said the CPU is not vulnerable via either + * the hypercall or device tree. + */ + if (!security_ftr_enabled(SEC_FTR_STF_BARRIER)) + return PR_SPEC_NOT_AFFECTED; + + /* + * If the system's CPU has no known barrier (see setup_stf_barrier()) + * then assume that the CPU is not vulnerable. + */ if (stf_enabled_flush_types == STF_BARRIER_NONE) - /* - * We don't have an explicit signal from firmware that we're - * vulnerable or not, we only have certain CPU revisions that - * are known to be vulnerable. - * - * We assume that if we're on another CPU, where the barrier is - * NONE, then we are not vulnerable. - */ return PR_SPEC_NOT_AFFECTED; - else - /* - * If we do have a barrier type then we are vulnerable. The - * barrier is not a global or per-process mitigation, so the - * only value we can report here is PR_SPEC_ENABLE, which - * appears as "vulnerable" in /proc. - */ - return PR_SPEC_ENABLE;
- return -EINVAL; + /* + * Otherwise the CPU is vulnerable. The barrier is not a global or + * per-process mitigation, so the only value that can be reported here + * is PR_SPEC_ENABLE, which appears as "vulnerable" in /proc. + */ + return PR_SPEC_ENABLE; }
int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
From: Suzuki K Poulose suzuki.poulose@arm.com
commit b9d216fcef4298de76519e2baeed69ba482467bd upstream
Arm Neoverse-N2 and the Cortex-A710 cores are affected by a CPU erratum where the TRBE will overwrite the trace buffer in FILL mode. The TRBE doesn't stop (as expected in FILL mode) when it reaches the limit and wraps to the base to continue writing upto 3 cache lines. This will overwrite any trace that was written previously.
Add the Neoverse-N2 erratum(#2139208) and Cortex-A710 erratum (#2119858) to the detection logic.
This will be used by the TRBE driver in later patches to work around the issue. The detection has been kept with the core arm64 errata framework list to make sure : - We don't duplicate the framework in TRBE driver - The errata detection is advertised like the rest of the CPU errata.
Note that the Kconfig entries are not fully active until the TRBE driver implements the work around.
Cc: Will Deacon will@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Anshuman Khandual anshuman.khandual@arm.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Mike Leach mike.leach@linaro.org cc: Leo Yan leo.yan@linaro.org Acked-by: Catalin Marinas catalin.marinas@arm.com Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org Reviewed-by: Anshuman Khandual anshuman.khandual@arm.com Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Link: https://lore.kernel.org/r/20211019163153.3692640-3-suzuki.poulose@arm.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Easwar Hariharan eahariha@linux.microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/arm64/silicon-errata.rst | 4 +++ arch/arm64/Kconfig | 41 +++++++++++++++++++++++++++++++++ arch/arm64/kernel/cpu_errata.c | 26 ++++++++++++++++++++ arch/arm64/tools/cpucaps | 1 4 files changed, 72 insertions(+)
--- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -102,12 +102,16 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A510 | #2457168 | ARM64_ERRATUM_2457168 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A710 | #2119858 | ARM64_ERRATUM_2119858 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1349291 | N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N2 | #2139208 | ARM64_ERRATUM_2139208 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -733,6 +733,47 @@ config ARM64_ERRATUM_2457168
If unsure, say Y.
+config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE + bool + +config ARM64_ERRATUM_2119858 + bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode" + default y + depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in + depends on CORESIGHT_TRBE + select ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE + help + This option adds the workaround for ARM Cortex-A710 erratum 2119858. + + Affected Cortex-A710 cores could overwrite up to 3 cache lines of trace + data at the base of the buffer (pointed to by TRBASER_EL1) in FILL mode in + the event of a WRAP event. + + Work around the issue by always making sure we move the TRBPTR_EL1 by + 256 bytes before enabling the buffer and filling the first 256 bytes of + the buffer with ETM ignore packets upon disabling. + + If unsure, say Y. + +config ARM64_ERRATUM_2139208 + bool "Neoverse-N2: 2139208: workaround TRBE overwriting trace data in FILL mode" + default y + depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in + depends on CORESIGHT_TRBE + select ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE + help + This option adds the workaround for ARM Neoverse-N2 erratum 2139208. + + Affected Neoverse-N2 cores could overwrite up to 3 cache lines of trace + data at the base of the buffer (pointed to by TRBASER_EL1) in FILL mode in + the event of a WRAP event. + + Work around the issue by always making sure we move the TRBPTR_EL1 by + 256 bytes before enabling the buffer and filling the first 256 bytes of + the buffer with ETM ignore packets upon disabling. + + If unsure, say Y. + config CAVIUM_ERRATUM_22375 bool "Cavium erratum 22375, 24313" default y --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -363,6 +363,18 @@ static struct midr_range broken_aarch32_ }; #endif
+#ifdef CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE +static const struct midr_range trbe_overwrite_fill_mode_cpus[] = { +#ifdef CONFIG_ARM64_ERRATUM_2139208 + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), +#endif +#ifdef CONFIG_ARM64_ERRATUM_2119858 + MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), +#endif + {}, +}; +#endif /* CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE */ + const struct arm64_cpu_capabilities arm64_errata[] = { #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE { @@ -564,6 +576,7 @@ const struct arm64_cpu_capabilities arm6 ERRATA_MIDR_ALL_VERSIONS(MIDR_NVIDIA_CARMEL), }, #endif + #ifdef CONFIG_ARM64_ERRATUM_2457168 { .desc = "ARM erratum 2457168", @@ -581,6 +594,19 @@ const struct arm64_cpu_capabilities arm6 .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, }, #endif +#ifdef CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE + { + /* + * The erratum work around is handled within the TRBE + * driver and can be applied per-cpu. So, we can allow + * a late CPU to come online with this erratum. + */ + .desc = "ARM erratum 2119858 or 2139208", + .capability = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE, + .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE, + CAP_MIDR_RANGE_LIST(trbe_overwrite_fill_mode_cpus), + }, +#endif { } }; --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -56,6 +56,7 @@ WORKAROUND_1508412 WORKAROUND_1542419 WORKAROUND_1742098 WORKAROUND_2457168 +WORKAROUND_TRBE_OVERWRITE_FILL_MODE WORKAROUND_CAVIUM_23154 WORKAROUND_CAVIUM_27456 WORKAROUND_CAVIUM_30115
From: Gao Xiang hsiangkao@linux.alibaba.com
commit 001b8ccd0650727e54ec16ef72bf1b8eeab7168e upstream.
In compact 4B, two adjacent lclusters are packed together as a unit to form on-disk indexes for effective random access, as below:
(amortized = 4, vcnt = 2) _____________________________________________ |___@_____ encoded bits __________|_ blkaddr _| 0 . amortized * vcnt = 8 . . . . amortized * vcnt - 4 = 4 . . .____________________________. |_type (2 bits)_|_clusterofs_|
Therefore, encoded bits for each pack are 32 bits (4 bytes). IOWs, since each lcluster can get 16 bits for its type and clusterofs, the maximum supported lclustersize for compact 4B format is 16k (14 bits).
Fix this to enable compact 4B format for 16k lclusters (blocks), which is tested on an arm64 server with 16k page size.
Fixes: 152a333a5895 ("staging: erofs: add compacted compression indexes support") Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Link: https://lore.kernel.org/r/20230601112341.56960-1-hsiangkao@linux.alibaba.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/erofs/zmap.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
--- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -253,7 +253,7 @@ static int unpack_compacted_index(struct u8 *in, type; bool big_pcluster;
- if (1 << amortizedshift == 4) + if (1 << amortizedshift == 4 && lclusterbits <= 14) vcnt = 2; else if (1 << amortizedshift == 2 && lclusterbits == 12) vcnt = 16; @@ -351,7 +351,6 @@ static int compacted_load_cluster_from_d { struct inode *const inode = m->inode; struct erofs_inode *const vi = EROFS_I(inode); - const unsigned int lclusterbits = vi->z_logical_clusterbits; const erofs_off_t ebase = ALIGN(iloc(EROFS_I_SB(inode), vi->nid) + vi->inode_isize + vi->xattr_isize, 8) + sizeof(struct z_erofs_map_header); @@ -361,9 +360,6 @@ static int compacted_load_cluster_from_d erofs_off_t pos; int err;
- if (lclusterbits != 12) - return -EOPNOTSUPP; - if (lcn >= totalidx) return -EINVAL;
From: Huacai Chen chenhuacai@loongson.cn
commit 65fee014dc41a774bcd94896f3fb380bc39d8dda upstream.
Commit 7db5e9e9e5e6c10d7d ("MIPS: loongson64: fix FTLB configuration") move decode_configs() from the beginning of cpu_probe_loongson() to the end in order to fix FTLB configuration. However, it breaks the CPUCFG decoding because decode_configs() use "c->options = xxxx" rather than "c->options |= xxxx", all information get from CPUCFG by decode_cpucfg() is lost.
This causes error when creating a KVM guest on Loongson-3A4000: Exception Code: 4 not handled @ PC: 0000000087ad5981, inst: 0xcb7a1898 BadVaddr: 0x0 Status: 0x0
Fix this by moving the c->cputype setting to the beginning and moving decode_configs() after that.
Fixes: 7db5e9e9e5e6c10d7d ("MIPS: loongson64: fix FTLB configuration") Cc: stable@vger.kernel.org Cc: Huang Pei huangpei@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/kernel/cpu-probe.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
--- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1734,7 +1734,10 @@ static inline void decode_cpucfg(struct
static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) { + c->cputype = CPU_LOONGSON64; + /* All Loongson processors covered here define ExcCode 16 as GSExc. */ + decode_configs(c); c->options |= MIPS_CPU_GSEXCEX;
switch (c->processor_id & PRID_IMP_MASK) { @@ -1744,7 +1747,6 @@ static inline void cpu_probe_loongson(st case PRID_REV_LOONGSON2K_R1_1: case PRID_REV_LOONGSON2K_R1_2: case PRID_REV_LOONGSON2K_R1_3: - c->cputype = CPU_LOONGSON64; __cpu_name[cpu] = "Loongson-2K"; set_elf_platform(cpu, "gs264e"); set_isa(c, MIPS_CPU_ISA_M64R2); @@ -1757,14 +1759,12 @@ static inline void cpu_probe_loongson(st switch (c->processor_id & PRID_REV_MASK) { case PRID_REV_LOONGSON3A_R2_0: case PRID_REV_LOONGSON3A_R2_1: - c->cputype = CPU_LOONGSON64; __cpu_name[cpu] = "ICT Loongson-3"; set_elf_platform(cpu, "loongson3a"); set_isa(c, MIPS_CPU_ISA_M64R2); break; case PRID_REV_LOONGSON3A_R3_0: case PRID_REV_LOONGSON3A_R3_1: - c->cputype = CPU_LOONGSON64; __cpu_name[cpu] = "ICT Loongson-3"; set_elf_platform(cpu, "loongson3a"); set_isa(c, MIPS_CPU_ISA_M64R2); @@ -1784,7 +1784,6 @@ static inline void cpu_probe_loongson(st c->ases &= ~MIPS_ASE_VZ; /* VZ of Loongson-3A2000/3000 is incomplete */ break; case PRID_IMP_LOONGSON_64G: - c->cputype = CPU_LOONGSON64; __cpu_name[cpu] = "ICT Loongson-3"; set_elf_platform(cpu, "loongson3a"); set_isa(c, MIPS_CPU_ISA_M64R2); @@ -1794,8 +1793,6 @@ static inline void cpu_probe_loongson(st panic("Unknown Loongson Processor ID!"); break; } - - decode_configs(c); } #else static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) { }
From: Huacai Chen chenhuacai@loongson.cn
commit e4de2057698636c0ee709e545d19b169d2069fa3 upstream.
After commit 45c7e8af4a5e3f0bea4ac209 ("MIPS: Remove KVM_TE support") we get a NULL pointer dereference when creating a KVM guest:
[ 146.243409] Starting KVM with MIPS VZ extensions [ 149.849151] CPU 3 Unable to handle kernel paging request at virtual address 0000000000000300, epc == ffffffffc06356ec, ra == ffffffffc063568c [ 149.849177] Oops[#1]: [ 149.849182] CPU: 3 PID: 2265 Comm: qemu-system-mip Not tainted 6.4.0-rc3+ #1671 [ 149.849188] Hardware name: THTF CX TL630 Series/THTF-LS3A4000-7A1000-ML4A, BIOS KL4.1F.TF.D.166.201225.R 12/25/2020 [ 149.849192] $ 0 : 0000000000000000 000000007400cce0 0000000000400004 ffffffff8119c740 [ 149.849209] $ 4 : 000000007400cce1 000000007400cce1 0000000000000000 0000000000000000 [ 149.849221] $ 8 : 000000240058bb36 ffffffff81421ac0 0000000000000000 0000000000400dc0 [ 149.849233] $12 : 9800000102a07cc8 ffffffff80e40e38 0000000000000001 0000000000400dc0 [ 149.849245] $16 : 0000000000000000 9800000106cd0000 9800000106cd0000 9800000100cce000 [ 149.849257] $20 : ffffffffc0632b28 ffffffffc05b31b0 9800000100ccca00 0000000000400000 [ 149.849269] $24 : 9800000106cd09ce ffffffff802f69d0 [ 149.849281] $28 : 9800000102a04000 9800000102a07cd0 98000001106a8000 ffffffffc063568c [ 149.849293] Hi : 00000335b2111e66 [ 149.849295] Lo : 6668d90061ae0ae9 [ 149.849298] epc : ffffffffc06356ec kvm_vz_vcpu_setup+0xc4/0x328 [kvm] [ 149.849324] ra : ffffffffc063568c kvm_vz_vcpu_setup+0x64/0x328 [kvm] [ 149.849336] Status: 7400cce3 KX SX UX KERNEL EXL IE [ 149.849351] Cause : 1000000c (ExcCode 03) [ 149.849354] BadVA : 0000000000000300 [ 149.849357] PrId : 0014c004 (ICT Loongson-3) [ 149.849360] Modules linked in: kvm nfnetlink_queue nfnetlink_log nfnetlink fuse sha256_generic libsha256 cfg80211 rfkill binfmt_misc vfat fat snd_hda_codec_hdmi input_leds led_class snd_hda_intel snd_intel_dspcfg snd_hda_codec snd_hda_core snd_pcm snd_timer snd serio_raw xhci_pci radeon drm_suballoc_helper drm_display_helper xhci_hcd ip_tables x_tables [ 149.849432] Process qemu-system-mip (pid: 2265, threadinfo=00000000ae2982d2, task=0000000038e09ad4, tls=000000ffeba16030) [ 149.849439] Stack : 9800000000000003 9800000100ccca00 9800000100ccc000 ffffffffc062cef4 [ 149.849453] 9800000102a07d18 c89b63a7ab338e00 0000000000000000 ffffffff811a0000 [ 149.849465] 0000000000000000 9800000106cd0000 ffffffff80e59938 98000001106a8920 [ 149.849476] ffffffff80e57f30 ffffffffc062854c ffffffff811a0000 9800000102bf4240 [ 149.849488] ffffffffc05b0000 ffffffff80e3a798 000000ff78000000 000000ff78000010 [ 149.849500] 0000000000000255 98000001021f7de0 98000001023f0078 ffffffff81434000 [ 149.849511] 0000000000000000 0000000000000000 9800000102ae0000 980000025e92ae28 [ 149.849523] 0000000000000000 c89b63a7ab338e00 0000000000000001 ffffffff8119dce0 [ 149.849535] 000000ff78000010 ffffffff804f3d3c 9800000102a07eb0 0000000000000255 [ 149.849546] 0000000000000000 ffffffff8049460c 000000ff78000010 0000000000000255 [ 149.849558] ... [ 149.849565] Call Trace: [ 149.849567] [<ffffffffc06356ec>] kvm_vz_vcpu_setup+0xc4/0x328 [kvm] [ 149.849586] [<ffffffffc062cef4>] kvm_arch_vcpu_create+0x184/0x228 [kvm] [ 149.849605] [<ffffffffc062854c>] kvm_vm_ioctl+0x64c/0xf28 [kvm] [ 149.849623] [<ffffffff805209c0>] sys_ioctl+0xc8/0x118 [ 149.849631] [<ffffffff80219eb0>] syscall_common+0x34/0x58
The root cause is the deletion of kvm_mips_commpage_init() leaves vcpu ->arch.cop0 NULL. So fix it by making cop0 from a pointer to an embedded object.
Fixes: 45c7e8af4a5e3f0bea4ac209 ("MIPS: Remove KVM_TE support") Cc: stable@vger.kernel.org Reported-by: Yu Zhao yuzhao@google.com Suggested-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Reviewed-by: Philippe Mathieu-Daudé philmd@linaro.org Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/include/asm/kvm_host.h | 6 +++--- arch/mips/kvm/emulate.c | 22 +++++++++++----------- arch/mips/kvm/mips.c | 16 ++++++++-------- arch/mips/kvm/trace.h | 8 ++++---- arch/mips/kvm/vz.c | 20 ++++++++++---------- 5 files changed, 36 insertions(+), 36 deletions(-)
--- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -318,7 +318,7 @@ struct kvm_vcpu_arch { unsigned int aux_inuse;
/* COP0 State */ - struct mips_coproc *cop0; + struct mips_coproc cop0;
/* Resume PC after MMIO completion */ unsigned long io_pc; @@ -699,7 +699,7 @@ static inline bool kvm_mips_guest_can_ha static inline bool kvm_mips_guest_has_fpu(struct kvm_vcpu_arch *vcpu) { return kvm_mips_guest_can_have_fpu(vcpu) && - kvm_read_c0_guest_config1(vcpu->cop0) & MIPS_CONF1_FP; + kvm_read_c0_guest_config1(&vcpu->cop0) & MIPS_CONF1_FP; }
static inline bool kvm_mips_guest_can_have_msa(struct kvm_vcpu_arch *vcpu) @@ -711,7 +711,7 @@ static inline bool kvm_mips_guest_can_ha static inline bool kvm_mips_guest_has_msa(struct kvm_vcpu_arch *vcpu) { return kvm_mips_guest_can_have_msa(vcpu) && - kvm_read_c0_guest_config3(vcpu->cop0) & MIPS_CONF3_MSA; + kvm_read_c0_guest_config3(&vcpu->cop0) & MIPS_CONF3_MSA; }
struct kvm_mips_callbacks { --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c @@ -312,7 +312,7 @@ int kvm_get_badinstrp(u32 *opc, struct k */ int kvm_mips_count_disabled(struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0;
return (vcpu->arch.count_ctl & KVM_REG_MIPS_COUNT_CTL_DC) || (kvm_read_c0_guest_cause(cop0) & CAUSEF_DC); @@ -384,7 +384,7 @@ static inline ktime_t kvm_mips_count_tim */ static u32 kvm_mips_read_count_running(struct kvm_vcpu *vcpu, ktime_t now) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; ktime_t expires, threshold; u32 count, compare; int running; @@ -444,7 +444,7 @@ static u32 kvm_mips_read_count_running(s */ u32 kvm_mips_read_count(struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0;
/* If count disabled just read static copy of count */ if (kvm_mips_count_disabled(vcpu)) @@ -502,7 +502,7 @@ ktime_t kvm_mips_freeze_hrtimer(struct k static void kvm_mips_resume_hrtimer(struct kvm_vcpu *vcpu, ktime_t now, u32 count) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; u32 compare; u64 delta; ktime_t expire; @@ -603,7 +603,7 @@ resume: */ void kvm_mips_write_count(struct kvm_vcpu *vcpu, u32 count) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; ktime_t now;
/* Calculate bias */ @@ -649,7 +649,7 @@ void kvm_mips_init_count(struct kvm_vcpu */ int kvm_mips_set_count_hz(struct kvm_vcpu *vcpu, s64 count_hz) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; int dc; ktime_t now; u32 count; @@ -696,7 +696,7 @@ int kvm_mips_set_count_hz(struct kvm_vcp */ void kvm_mips_write_compare(struct kvm_vcpu *vcpu, u32 compare, bool ack) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; int dc; u32 old_compare = kvm_read_c0_guest_compare(cop0); s32 delta = compare - old_compare; @@ -779,7 +779,7 @@ void kvm_mips_write_compare(struct kvm_v */ static ktime_t kvm_mips_count_disable(struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; u32 count; ktime_t now;
@@ -806,7 +806,7 @@ static ktime_t kvm_mips_count_disable(st */ void kvm_mips_count_disable_cause(struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0;
kvm_set_c0_guest_cause(cop0, CAUSEF_DC); if (!(vcpu->arch.count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) @@ -826,7 +826,7 @@ void kvm_mips_count_disable_cause(struct */ void kvm_mips_count_enable_cause(struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; u32 count;
kvm_clear_c0_guest_cause(cop0, CAUSEF_DC); @@ -852,7 +852,7 @@ void kvm_mips_count_enable_cause(struct */ int kvm_mips_set_count_ctl(struct kvm_vcpu *vcpu, s64 count_ctl) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; s64 changed = count_ctl ^ vcpu->arch.count_ctl; s64 delta; ktime_t expire, now; --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -652,7 +652,7 @@ static int kvm_mips_copy_reg_indices(str static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; struct mips_fpu_struct *fpu = &vcpu->arch.fpu; int ret; s64 v; @@ -764,7 +764,7 @@ static int kvm_mips_get_reg(struct kvm_v static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; struct mips_fpu_struct *fpu = &vcpu->arch.fpu; s64 v; s64 vs[2]; @@ -1104,7 +1104,7 @@ int kvm_vm_ioctl_check_extension(struct int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) { return kvm_mips_pending_timer(vcpu) || - kvm_read_c0_guest_cause(vcpu->arch.cop0) & C_TI; + kvm_read_c0_guest_cause(&vcpu->arch.cop0) & C_TI; }
int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu) @@ -1128,7 +1128,7 @@ int kvm_arch_vcpu_dump_regs(struct kvm_v kvm_debug("\thi: 0x%08lx\n", vcpu->arch.hi); kvm_debug("\tlo: 0x%08lx\n", vcpu->arch.lo);
- cop0 = vcpu->arch.cop0; + cop0 = &vcpu->arch.cop0; kvm_debug("\tStatus: 0x%08x, Cause: 0x%08x\n", kvm_read_c0_guest_status(cop0), kvm_read_c0_guest_cause(cop0)); @@ -1250,7 +1250,7 @@ int kvm_mips_handle_exit(struct kvm_vcpu
case EXCCODE_TLBS: kvm_debug("TLB ST fault: cause %#x, status %#x, PC: %p, BadVaddr: %#lx\n", - cause, kvm_read_c0_guest_status(vcpu->arch.cop0), opc, + cause, kvm_read_c0_guest_status(&vcpu->arch.cop0), opc, badvaddr);
++vcpu->stat.tlbmiss_st_exits; @@ -1322,7 +1322,7 @@ int kvm_mips_handle_exit(struct kvm_vcpu kvm_get_badinstr(opc, vcpu, &inst); kvm_err("Exception Code: %d, not yet handled, @ PC: %p, inst: 0x%08x BadVaddr: %#lx Status: %#x\n", exccode, opc, inst, badvaddr, - kvm_read_c0_guest_status(vcpu->arch.cop0)); + kvm_read_c0_guest_status(&vcpu->arch.cop0)); kvm_arch_vcpu_dump_regs(vcpu); run->exit_reason = KVM_EXIT_INTERNAL_ERROR; ret = RESUME_HOST; @@ -1384,7 +1384,7 @@ int kvm_mips_handle_exit(struct kvm_vcpu /* Enable FPU for guest and restore context */ void kvm_own_fpu(struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; unsigned int sr, cfg5;
preempt_disable(); @@ -1428,7 +1428,7 @@ void kvm_own_fpu(struct kvm_vcpu *vcpu) /* Enable MSA for guest and restore context */ void kvm_own_msa(struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; unsigned int sr, cfg5;
preempt_disable(); --- a/arch/mips/kvm/trace.h +++ b/arch/mips/kvm/trace.h @@ -322,11 +322,11 @@ TRACE_EVENT_FN(kvm_guest_mode_change, ),
TP_fast_assign( - __entry->epc = kvm_read_c0_guest_epc(vcpu->arch.cop0); + __entry->epc = kvm_read_c0_guest_epc(&vcpu->arch.cop0); __entry->pc = vcpu->arch.pc; - __entry->badvaddr = kvm_read_c0_guest_badvaddr(vcpu->arch.cop0); - __entry->status = kvm_read_c0_guest_status(vcpu->arch.cop0); - __entry->cause = kvm_read_c0_guest_cause(vcpu->arch.cop0); + __entry->badvaddr = kvm_read_c0_guest_badvaddr(&vcpu->arch.cop0); + __entry->status = kvm_read_c0_guest_status(&vcpu->arch.cop0); + __entry->cause = kvm_read_c0_guest_cause(&vcpu->arch.cop0); ),
TP_printk("EPC: 0x%08lx PC: 0x%08lx Status: 0x%08x Cause: 0x%08x BadVAddr: 0x%08lx", --- a/arch/mips/kvm/vz.c +++ b/arch/mips/kvm/vz.c @@ -422,7 +422,7 @@ static void _kvm_vz_restore_htimer(struc */ static void kvm_vz_restore_timer(struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; u32 cause, compare;
compare = kvm_read_sw_gc0_compare(cop0); @@ -517,7 +517,7 @@ static void _kvm_vz_save_htimer(struct k */ static void kvm_vz_save_timer(struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; u32 gctl0, compare, cause;
gctl0 = read_c0_guestctl0(); @@ -863,7 +863,7 @@ static unsigned long mips_process_maar(u
static void kvm_write_maari(struct kvm_vcpu *vcpu, unsigned long val) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0;
val &= MIPS_MAARI_INDEX; if (val == MIPS_MAARI_INDEX) @@ -876,7 +876,7 @@ static enum emulation_result kvm_vz_gpsi u32 *opc, u32 cause, struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; enum emulation_result er = EMULATE_DONE; u32 rt, rd, sel; unsigned long curr_pc; @@ -1905,7 +1905,7 @@ static int kvm_vz_get_one_reg(struct kvm const struct kvm_one_reg *reg, s64 *v) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; unsigned int idx;
switch (reg->id) { @@ -2075,7 +2075,7 @@ static int kvm_vz_get_one_reg(struct kvm case KVM_REG_MIPS_CP0_MAARI: if (!cpu_guest_has_maar || cpu_guest_has_dyn_maar) return -EINVAL; - *v = kvm_read_sw_gc0_maari(vcpu->arch.cop0); + *v = kvm_read_sw_gc0_maari(&vcpu->arch.cop0); break; #ifdef CONFIG_64BIT case KVM_REG_MIPS_CP0_XCONTEXT: @@ -2129,7 +2129,7 @@ static int kvm_vz_set_one_reg(struct kvm const struct kvm_one_reg *reg, s64 v) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; unsigned int idx; int ret = 0; unsigned int cur, change; @@ -2556,7 +2556,7 @@ static void kvm_vz_vcpu_load_tlb(struct
static int kvm_vz_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; bool migrated, all;
/* @@ -2698,7 +2698,7 @@ static int kvm_vz_vcpu_load(struct kvm_v
static int kvm_vz_vcpu_put(struct kvm_vcpu *vcpu, int cpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0;
if (current->flags & PF_VCPU) kvm_vz_vcpu_save_wired(vcpu); @@ -3070,7 +3070,7 @@ static void kvm_vz_vcpu_uninit(struct kv
static int kvm_vz_vcpu_setup(struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu->arch.cop0; + struct mips_coproc *cop0 = &vcpu->arch.cop0; unsigned long count_hz = 100*1000*1000; /* default to 100 MHz */
/*
From: Zhihao Cheng chengzhihao1@huawei.com
commit 26fb5290240dc31cae99b8b4dd2af7f46dfcba6b upstream.
Following process makes ext4 load stale buffer heads from last failed mounting in a new mounting operation: mount_bdev ext4_fill_super | ext4_load_and_init_journal | ext4_load_journal | jbd2_journal_load | load_superblock | journal_get_superblock | set_buffer_verified(bh) // buffer head is verified | jbd2_journal_recover // failed caused by EIO | goto failed_mount3a // skip 'sb->s_root' initialization deactivate_locked_super kill_block_super generic_shutdown_super if (sb->s_root) // false, skip ext4_put_super->invalidate_bdev-> // invalidate_mapping_pages->mapping_evict_folio-> // filemap_release_folio->try_to_free_buffers, which // cannot drop buffer head. blkdev_put blkdev_put_whole if (atomic_dec_and_test(&bdev->bd_openers)) // false, systemd-udev happens to open the device. Then // blkdev_flush_mapping->kill_bdev->truncate_inode_pages-> // truncate_inode_folio->truncate_cleanup_folio-> // folio_invalidate->block_invalidate_folio-> // filemap_release_folio->try_to_free_buffers will be skipped, // dropping buffer head is missed again.
Second mount: ext4_fill_super ext4_load_and_init_journal ext4_load_journal ext4_get_journal jbd2_journal_init_inode journal_init_common bh = getblk_unmovable bh = __find_get_block // Found stale bh in last failed mounting journal->j_sb_buffer = bh jbd2_journal_load load_superblock journal_get_superblock if (buffer_verified(bh)) // true, skip journal->j_format_version = 2, value is 0 jbd2_journal_recover do_one_pass next_log_block += count_tags(journal, bh) // According to journal_tag_bytes(), 'tag_bytes' calculating is // affected by jbd2_has_feature_csum3(), jbd2_has_feature_csum3() // returns false because 'j->j_format_version >= 2' is not true, // then we get wrong next_log_block. The do_one_pass may exit // early whenoccuring non JBD2_MAGIC_NUMBER in 'next_log_block'.
The filesystem is corrupted here, journal is partially replayed, and new journal sequence number actually is already used by last mounting.
The invalidate_bdev() can drop all buffer heads even racing with bare reading block device(eg. systemd-udev), so we can fix it by invalidating bdev in error handling path in __ext4_fill_super().
Fetch a reproducer in [Link].
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217171 Fixes: 25ed6e8a54df ("jbd2: enable journal clients to enable v2 checksumming") Cc: stable@vger.kernel.org # v3.5 Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20230315013128.3911115-2-chengzhihao1@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/super.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1097,6 +1097,12 @@ static void ext4_blkdev_remove(struct ex struct block_device *bdev; bdev = sbi->s_journal_bdev; if (bdev) { + /* + * Invalidate the journal device's buffers. We don't want them + * floating about in memory - the physical journal device may + * hotswapped, and it breaks the `ro-after' testing code. + */ + invalidate_bdev(bdev); ext4_blkdev_put(bdev); sbi->s_journal_bdev = NULL; } @@ -1239,13 +1245,7 @@ static void ext4_put_super(struct super_ sync_blockdev(sb->s_bdev); invalidate_bdev(sb->s_bdev); if (sbi->s_journal_bdev && sbi->s_journal_bdev != sb->s_bdev) { - /* - * Invalidate the journal device's buffers. We don't want them - * floating about in memory - the physical journal device may - * hotswapped, and it breaks the `ro-after' testing code. - */ sync_blockdev(sbi->s_journal_bdev); - invalidate_bdev(sbi->s_journal_bdev); ext4_blkdev_remove(sbi); }
@@ -5100,6 +5100,7 @@ failed_mount: brelse(bh); ext4_blkdev_remove(sbi); out_fail: + invalidate_bdev(sb->s_bdev); sb->s_fs_info = NULL; kfree(sbi->s_blockgroup_lock); out_free_base:
From: Kemeng Shi shikemeng@huaweicloud.com
commit 247c3d214c23dfeeeb892e91a82ac1188bdaec9f upstream.
Function ext4_issue_discard need count in cluster. Pass count_clusters instead of count to fix the mismatch.
Signed-off-by: Kemeng Shi shikemeng@huaweicloud.com Cc: stable@kernel.org Reviewed-by: Ojaswin Mujoo ojaswin@linux.ibm.com Link: https://lore.kernel.org/r/20230603150327.3596033-11-shikemeng@huaweicloud.co... Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/mballoc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -6086,8 +6086,8 @@ do_more: * them with group lock_held */ if (test_opt(sb, DISCARD)) { - err = ext4_issue_discard(sb, block_group, bit, count, - NULL); + err = ext4_issue_discard(sb, block_group, bit, + count_clusters, NULL); if (err && err != -EOPNOTSUPP) ext4_msg(sb, KERN_WARNING, "discard request in" " group:%u block:%d count:%lu failed"
From: Kemeng Shi shikemeng@huaweicloud.com
commit 11b6890be0084ad4df0e06d89a9fdcc948472c65 upstream.
ext4_free_blocks will retrieve block from bh if block parameter is zero. Retrieve block before ext4_free_blocks_simple to avoid potentially passing wrong block to ext4_free_blocks_simple.
Signed-off-by: Kemeng Shi shikemeng@huaweicloud.com Cc: stable@kernel.org Reviewed-by: Ojaswin Mujoo ojaswin@linux.ibm.com Link: https://lore.kernel.org/r/20230603150327.3596033-9-shikemeng@huaweicloud.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/mballoc.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
--- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -6171,12 +6171,6 @@ void ext4_free_blocks(handle_t *handle,
sbi = EXT4_SB(sb);
- if (sbi->s_mount_state & EXT4_FC_REPLAY) { - ext4_free_blocks_simple(inode, block, count); - return; - } - - might_sleep(); if (bh) { if (block) BUG_ON(block != bh->b_blocknr); @@ -6184,6 +6178,13 @@ void ext4_free_blocks(handle_t *handle, block = bh->b_blocknr; }
+ if (sbi->s_mount_state & EXT4_FC_REPLAY) { + ext4_free_blocks_simple(inode, block, count); + return; + } + + might_sleep(); + if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && !ext4_inode_block_valid(inode, block, count)) { ext4_error(sb, "Freeing blocks not in datazone - "
From: Kemeng Shi shikemeng@huaweicloud.com
commit 2ec6d0a5ea72689a79e6f725fd8b443a788ae279 upstream.
Function ext4_free_blocks_simple needs count in cluster. Function ext4_free_blocks accepts count in block. Convert count to cluster to fix the mismatch.
Signed-off-by: Kemeng Shi shikemeng@huaweicloud.com Cc: stable@kernel.org Reviewed-by: Ojaswin Mujoo ojaswin@linux.ibm.com Link: https://lore.kernel.org/r/20230603150327.3596033-12-shikemeng@huaweicloud.co... Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/mballoc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -6179,7 +6179,7 @@ void ext4_free_blocks(handle_t *handle, }
if (sbi->s_mount_state & EXT4_FC_REPLAY) { - ext4_free_blocks_simple(inode, block, count); + ext4_free_blocks_simple(inode, block, EXT4_NUM_B2C(sbi, count)); return; }
From: Chao Yu chao@kernel.org
commit c4d13222afd8a64bf11bc7ec68645496ee8b54b9 upstream.
freeze_bdev() can fail due to a lot of reasons, it needs to check its reason before later process.
Fixes: 783d94854499 ("ext4: add EXT4_IOC_GOINGDOWN ioctl") Cc: stable@kernel.org Signed-off-by: Chao Yu chao@kernel.org Link: https://lore.kernel.org/r/20230606073203.1310389-1-chao@kernel.org Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/ioctl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -559,6 +559,7 @@ static int ext4_shutdown(struct super_bl { struct ext4_sb_info *sbi = EXT4_SB(sb); __u32 flags; + int ret;
if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -577,7 +578,9 @@ static int ext4_shutdown(struct super_bl
switch (flags) { case EXT4_GOING_FLAGS_DEFAULT: - freeze_bdev(sb->s_bdev); + ret = freeze_bdev(sb->s_bdev); + if (ret) + return ret; set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); thaw_bdev(sb->s_bdev); break;
From: Baokun Li libaokun1@huawei.com
commit d13f99632748462c32fc95d729f5e754bab06064 upstream.
Yi found during a review of the patch "ext4: don't BUG on inconsistent journal feature" that when ext4_mark_recovery_complete() returns an error value, the error handling path does not turn off the enabled quotas, which triggers the following kmemleak:
================================================================ unreferenced object 0xffff8cf68678e7c0 (size 64): comm "mount", pid 746, jiffies 4294871231 (age 11.540s) hex dump (first 32 bytes): 00 90 ef 82 f6 8c ff ff 00 00 00 00 41 01 00 00 ............A... c7 00 00 00 bd 00 00 00 0a 00 00 00 48 00 00 00 ............H... backtrace: [<00000000c561ef24>] __kmem_cache_alloc_node+0x4d4/0x880 [<00000000d4e621d7>] kmalloc_trace+0x39/0x140 [<00000000837eee74>] v2_read_file_info+0x18a/0x3a0 [<0000000088f6c877>] dquot_load_quota_sb+0x2ed/0x770 [<00000000340a4782>] dquot_load_quota_inode+0xc6/0x1c0 [<0000000089a18bd5>] ext4_enable_quotas+0x17e/0x3a0 [ext4] [<000000003a0268fa>] __ext4_fill_super+0x3448/0x3910 [ext4] [<00000000b0f2a8a8>] ext4_fill_super+0x13d/0x340 [ext4] [<000000004a9489c4>] get_tree_bdev+0x1dc/0x370 [<000000006e723bf1>] ext4_get_tree+0x1d/0x30 [ext4] [<00000000c7cb663d>] vfs_get_tree+0x31/0x160 [<00000000320e1bed>] do_new_mount+0x1d5/0x480 [<00000000c074654c>] path_mount+0x22e/0xbe0 [<0000000003e97a8e>] do_mount+0x95/0xc0 [<000000002f3d3736>] __x64_sys_mount+0xc4/0x160 [<0000000027d2140c>] do_syscall_64+0x3f/0x90 ================================================================
To solve this problem, we add a "failed_mount10" tag, and call ext4_quota_off_umount() in this tag to release the enabled qoutas.
Fixes: 11215630aada ("ext4: don't BUG on inconsistent journal feature") Cc: stable@kernel.org Signed-off-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Baokun Li libaokun1@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20230327141630.156875-2-libaokun1@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/super.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4977,7 +4977,7 @@ no_journal: ext4_msg(sb, KERN_INFO, "recovery complete"); err = ext4_mark_recovery_complete(sb, es); if (err) - goto failed_mount9; + goto failed_mount10; } if (EXT4_SB(sb)->s_journal) { if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) @@ -5023,7 +5023,9 @@ cantfind_ext4: ext4_msg(sb, KERN_ERR, "VFS: Can't find ext4 filesystem"); goto failed_mount;
-failed_mount9: +failed_mount10: + ext4_quota_off_umount(sb); +failed_mount9: __maybe_unused ext4_release_orphan_info(sb); failed_mount8: ext4_unregister_sysfs(sb);
From: Baokun Li libaokun1@huawei.com
commit de25d6e9610a8b30cce9bbb19b50615d02ebca02 upstream.
In our fault injection test, we create an ext4 file, migrate it to non-extent based file, then punch a hole and finally trigger a WARN_ON in the ext4_da_update_reserve_space():
EXT4-fs warning (device sda): ext4_da_update_reserve_space:369: ino 14, used 11 with only 10 reserved data blocks
When writing back a non-extent based file, if we enable delalloc, the number of reserved blocks will be subtracted from the number of blocks mapped by ext4_ind_map_blocks(), and the extent status tree will be updated. We update the extent status tree by first removing the old extent_status and then inserting the new extent_status. If the block range we remove happens to be in an extent, then we need to allocate another extent_status with ext4_es_alloc_extent().
use old to remove to add new |----------|------------|------------| old extent_status
The problem is that the allocation of a new extent_status failed due to a fault injection, and __es_shrink() did not get free memory, resulting in a return of -ENOMEM. Then do_writepages() retries after receiving -ENOMEM, we map to the same extent again, and the number of reserved blocks is again subtracted from the number of blocks in that extent. Since the blocks in the same extent are subtracted twice, we end up triggering WARN_ON at ext4_da_update_reserve_space() because used > ei->i_reserved_data_blocks.
For non-extent based file, we update the number of reserved blocks after ext4_ind_map_blocks() is executed, which causes a problem that when we call ext4_ind_map_blocks() to create a block, it doesn't always create a block, but we always reduce the number of reserved blocks. So we move the logic for updating reserved blocks to ext4_ind_map_blocks() to ensure that the number of reserved blocks is updated only after we do succeed in allocating some new blocks.
Fixes: 5f634d064c70 ("ext4: Fix quota accounting error with fallocate") Cc: stable@kernel.org Signed-off-by: Baokun Li libaokun1@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20230424033846.4732-2-libaokun1@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/indirect.c | 8 ++++++++ fs/ext4/inode.c | 10 ---------- 2 files changed, 8 insertions(+), 10 deletions(-)
--- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c @@ -651,6 +651,14 @@ int ext4_ind_map_blocks(handle_t *handle
ext4_update_inode_fsync_trans(handle, inode, 1); count = ar.len; + + /* + * Update reserved blocks/metadata blocks after successful block + * allocation which had been deferred till now. + */ + if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) + ext4_da_update_reserve_space(inode, count, 1); + got_it: map->m_flags |= EXT4_MAP_MAPPED; map->m_pblk = le32_to_cpu(chain[depth-1].key); --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -654,16 +654,6 @@ found: */ ext4_clear_inode_state(inode, EXT4_STATE_EXT_MIGRATE); } - - /* - * Update reserved blocks/metadata blocks after successful - * block allocation which had been deferred till now. We don't - * support fallocate for non extent files. So we can update - * reserve space here. - */ - if ((retval > 0) && - (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)) - ext4_da_update_reserve_space(inode, retval, 1); }
if (retval > 0) {
From: Siddh Raman Pant code@siddh.me
commit 11509910c599cbd04585ec35a6d5e1a0053d84c1 upstream.
In jfs_dmap.c at line 381, BLKTODMAP is used to get a logical block number inside dbFree(). db_l2nbperpage, which is the log2 number of blocks per page, is passed as an argument to BLKTODMAP which uses it for shifting.
Syzbot reported a shift out-of-bounds crash because db_l2nbperpage is too big. This happens because the large value is set without any validation in dbMount() at line 181.
Thus, make sure that db_l2nbperpage is correct while mounting.
Max number of blocks per page = Page size / Min block size => log2(Max num_block per page) = log2(Page size / Min block size) = log2(Page size) - log2(Min block size)
=> Max db_l2nbperpage = L2PSIZE - L2MINBLOCKSIZE
Reported-and-tested-by: syzbot+d2cd27dcf8e04b232eb2@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?id=2a70a453331db32ed491f5cbb07e81bf2d22571... Cc: stable@vger.kernel.org Suggested-by: Dave Kleikamp dave.kleikamp@oracle.com Signed-off-by: Siddh Raman Pant code@siddh.me Signed-off-by: Dave Kleikamp dave.kleikamp@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/jfs/jfs_dmap.c | 6 ++++++ fs/jfs/jfs_filsys.h | 2 ++ 2 files changed, 8 insertions(+)
--- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -178,7 +178,13 @@ int dbMount(struct inode *ipbmap) dbmp_le = (struct dbmap_disk *) mp->data; bmp->db_mapsize = le64_to_cpu(dbmp_le->dn_mapsize); bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree); + bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage); + if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) { + err = -EINVAL; + goto err_release_metapage; + } + bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag); if (!bmp->db_numag) { err = -EINVAL; --- a/fs/jfs/jfs_filsys.h +++ b/fs/jfs/jfs_filsys.h @@ -122,7 +122,9 @@ #define NUM_INODE_PER_IAG INOSPERIAG
#define MINBLOCKSIZE 512 +#define L2MINBLOCKSIZE 9 #define MAXBLOCKSIZE 4096 +#define L2MAXBLOCKSIZE 12 #define MAXFILESIZE ((s64)1 << 52)
#define JFS_LINK_MAX 0xffffffff
From: Martin Kaiser martin@kaiser.cx
commit d744ae7477190967a3ddc289e2cd4ae59e8b1237 upstream.
Fix the timeout that is used for the initialisation and for the self test. wait_for_completion_timeout expects a timeout in jiffies, but RNGC_TIMEOUT is in milliseconds. Call msecs_to_jiffies to do the conversion.
Cc: stable@vger.kernel.org Fixes: 1d5449445bd0 ("hwrng: mx-rngc - add a driver for Freescale RNGC") Signed-off-by: Martin Kaiser martin@kaiser.cx Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/hw_random/imx-rngc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
--- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -110,7 +110,7 @@ static int imx_rngc_self_test(struct imx cmd = readl(rngc->base + RNGC_COMMAND); writel(cmd | RNGC_CMD_SELF_TEST, rngc->base + RNGC_COMMAND);
- ret = wait_for_completion_timeout(&rngc->rng_op_done, RNGC_TIMEOUT); + ret = wait_for_completion_timeout(&rngc->rng_op_done, msecs_to_jiffies(RNGC_TIMEOUT)); imx_rngc_irq_mask_clear(rngc); if (!ret) return -ETIMEDOUT; @@ -187,9 +187,7 @@ static int imx_rngc_init(struct hwrng *r cmd = readl(rngc->base + RNGC_COMMAND); writel(cmd | RNGC_CMD_SEED, rngc->base + RNGC_COMMAND);
- ret = wait_for_completion_timeout(&rngc->rng_op_done, - RNGC_TIMEOUT); - + ret = wait_for_completion_timeout(&rngc->rng_op_done, msecs_to_jiffies(RNGC_TIMEOUT)); if (!ret) { ret = -ETIMEDOUT; goto err;
From: Mikulas Patocka mpatocka@redhat.com
commit 6d50eb4725934fd22f5eeccb401000687c790fd0 upstream.
It was reported that dm-integrity runs out of vmalloc space on 32-bit architectures. On x86, there is only 128MiB vmalloc space and dm-integrity consumes it quickly because it has a 64MiB journal and 8MiB recalculate buffer.
Fix this by reducing the size of the journal to 4MiB and the size of the recalculate buffer to 1MiB, so that multiple dm-integrity devices can be created and activated on 32-bit architectures.
Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/dm-integrity.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -31,11 +31,11 @@ #define DEFAULT_BUFFER_SECTORS 128 #define DEFAULT_JOURNAL_WATERMARK 50 #define DEFAULT_SYNC_MSEC 10000 -#define DEFAULT_MAX_JOURNAL_SECTORS 131072 +#define DEFAULT_MAX_JOURNAL_SECTORS (IS_ENABLED(CONFIG_64BIT) ? 131072 : 8192) #define MIN_LOG2_INTERLEAVE_SECTORS 3 #define MAX_LOG2_INTERLEAVE_SECTORS 31 #define METADATA_WORKQUEUE_MAX_ACTIVE 16 -#define RECALC_SECTORS 32768 +#define RECALC_SECTORS (IS_ENABLED(CONFIG_64BIT) ? 32768 : 2048) #define RECALC_WRITE_SUPER 16 #define BITMAP_BLOCK_SIZE 4096 /* don't change it */ #define BITMAP_FLUSH_INTERVAL (10 * HZ)
From: Ondrej Zary linux@zary.sk
commit 9e30fd26f43b89cb6b4e850a86caa2e50dedb454 upstream.
The quirk for Elo i2 introduced in commit 92597f97a40b ("PCI/PM: Avoid putting Elo i2 PCIe Ports in D3cold") is also needed by EloPOS E2/S2/H2 which uses the same Continental Z2 board.
Change the quirk to match the board instead of system.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215715 Link: https://lore.kernel.org/r/20230614074253.22318-1-linux@zary.sk Signed-off-by: Ondrej Zary linux@zary.sk Signed-off-by: Bjorn Helgaas bhelgaas@google.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/pci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
--- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2886,13 +2886,13 @@ static const struct dmi_system_id bridge { /* * Downstream device is not accessible after putting a root port - * into D3cold and back into D0 on Elo i2. + * into D3cold and back into D0 on Elo Continental Z2 board */ - .ident = "Elo i2", + .ident = "Elo Continental Z2", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Elo Touch Solutions"), - DMI_MATCH(DMI_PRODUCT_NAME, "Elo i2"), - DMI_MATCH(DMI_PRODUCT_VERSION, "RevB"), + DMI_MATCH(DMI_BOARD_VENDOR, "Elo Touch Solutions"), + DMI_MATCH(DMI_BOARD_NAME, "Geminilake"), + DMI_MATCH(DMI_BOARD_VERSION, "Continental Z2"), }, }, #endif
From: Robin Murphy robin.murphy@arm.com
commit 88d341716b83abd355558523186ca488918627ee upstream.
Marvell's own product brief implies the 92xx series are a closely related family, and sure enough it turns out that 9235 seems to need the same quirk as the other three, although possibly only when certain ports are used.
Link: https://lore.kernel.org/linux-iommu/2a699a99-545c-1324-e052-7d2f41fed1ae@yah... Link: https://lore.kernel.org/r/731507e05d70239aec96fcbfab6e65d8ce00edd2.168615716... Reported-by: Jason Adriaanse jason_a69@yahoo.co.uk Signed-off-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Christoph Hellwig hch@lst.de Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4149,6 +4149,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_M /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c49 */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9230, quirk_dma_func1_alias); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9235, + quirk_dma_func1_alias); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0642, quirk_dma_func1_alias); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0645,
From: Igor Mammedov imammedo@redhat.com
commit 40613da52b13fb21c5566f10b287e0ca8c12c4e9 upstream.
When using ACPI PCI hotplug, hotplugging a device with large BARs may fail if bridge windows programmed by firmware are not large enough.
Reproducer: $ qemu-kvm -monitor stdio -M q35 -m 4G \ -global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=on \ -device id=rp1,pcie-root-port,bus=pcie.0,chassis=4 \ disk_image
wait till linux guest boots, then hotplug device: (qemu) device_add qxl,bus=rp1
hotplug on guest side fails with: pci 0000:01:00.0: [1b36:0100] type 00 class 0x038000 pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x03ffffff] pci 0000:01:00.0: reg 0x14: [mem 0x00000000-0x03ffffff] pci 0000:01:00.0: reg 0x18: [mem 0x00000000-0x00001fff] pci 0000:01:00.0: reg 0x1c: [io 0x0000-0x001f] pci 0000:01:00.0: BAR 0: no space for [mem size 0x04000000] pci 0000:01:00.0: BAR 0: failed to assign [mem size 0x04000000] pci 0000:01:00.0: BAR 1: no space for [mem size 0x04000000] pci 0000:01:00.0: BAR 1: failed to assign [mem size 0x04000000] pci 0000:01:00.0: BAR 2: assigned [mem 0xfe800000-0xfe801fff] pci 0000:01:00.0: BAR 3: assigned [io 0x1000-0x101f] qxl 0000:01:00.0: enabling device (0000 -> 0003) Unable to create vram_mapping qxl: probe of 0000:01:00.0 failed with error -12
However when using native PCIe hotplug '-global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off' it works fine, since kernel attempts to reassign unused resources.
Use the same machinery as native PCIe hotplug to (re)assign resources.
Link: https://lore.kernel.org/r/20230424191557.2464760-1-imammedo@redhat.com Signed-off-by: Igor Mammedov imammedo@redhat.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Acked-by: Michael S. Tsirkin mst@redhat.com Acked-by: Rafael J. Wysocki rafael@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/hotplug/acpiphp_glue.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
--- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -489,7 +489,6 @@ static void enable_slot(struct acpiphp_s acpiphp_native_scan_bridge(dev); } } else { - LIST_HEAD(add_list); int max, pass;
acpiphp_rescan_slot(slot); @@ -503,12 +502,10 @@ static void enable_slot(struct acpiphp_s if (pass && dev->subordinate) { check_hotplug_bridge(slot, dev); pcibios_resource_survey_bus(dev->subordinate); - __pci_bus_size_bridges(dev->subordinate, - &add_list); } } } - __pci_bus_assign_resources(bus, &add_list, NULL); + pci_assign_unassigned_bridge_resources(bus->self); }
acpiphp_sanitize_bus(bus);
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
commit a33d700e8eea76c62120cb3dbf5e01328f18319a upstream.
In the post init sequence of v2.9.0, write access to read only registers are not disabled after updating the registers. Fix it by disabling the access after register update.
Link: https://lore.kernel.org/r/20230619150408.8468-2-manivannan.sadhasivam@linaro... Fixes: 5d76117f070d ("PCI: qcom: Add support for IPQ8074 PCIe controller") Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/dwc/pcie-qcom.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1134,6 +1134,8 @@ static int qcom_pcie_post_init_2_3_3(str writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset + PCI_EXP_DEVCTL2);
+ dw_pcie_dbi_ro_wr_dis(pci); + return 0; }
From: Rick Wertenbroek rick.wertenbroek@gmail.com
commit f397fd4ac1fa3afcabd8cee030f953ccaed2a364 upstream.
Assert PCI Configuration Enable bit after probe. When this bit is left to 0 in the endpoint mode, the RK3399 PCIe endpoint core will generate configuration request retry status (CRS) messages back to the root complex. Assert this bit after probe to allow the RK3399 PCIe endpoint core to reply to configuration requests from the root complex. This is documented in section 17.5.8.1.2 of the RK3399 TRM.
Link: https://lore.kernel.org/r/20230418074700.1083505-4-rick.wertenbroek@gmail.co... Fixes: cf590b078391 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") Tested-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Rick Wertenbroek rick.wertenbroek@gmail.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Damien Le Moal dlemoal@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pcie-rockchip-ep.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/pci/controller/pcie-rockchip-ep.c +++ b/drivers/pci/controller/pcie-rockchip-ep.c @@ -631,6 +631,9 @@ static int rockchip_pcie_ep_probe(struct
ep->irq_pci_addr = ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR;
+ rockchip_pcie_write(rockchip, PCIE_CLIENT_CONF_ENABLE, + PCIE_CLIENT_CONFIG); + return 0; err_epc_mem_exit: pci_epc_mem_exit(epc);
From: Rick Wertenbroek rick.wertenbroek@gmail.com
commit 1f1c42ece18de365c976a060f3c8eb481b038e3a upstream.
Write PCI Device ID (DID) to the correct register. The Device ID was not updated through the correct register. Device ID was written to a read-only register and therefore did not work. The Device ID is now set through the correct register. This is documented in the RK3399 TRM section 17.6.6.1.1
Link: https://lore.kernel.org/r/20230418074700.1083505-3-rick.wertenbroek@gmail.co... Fixes: cf590b078391 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") Tested-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Rick Wertenbroek rick.wertenbroek@gmail.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Damien Le Moal dlemoal@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pcie-rockchip-ep.c | 6 ++++-- drivers/pci/controller/pcie-rockchip.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/pci/controller/pcie-rockchip-ep.c +++ b/drivers/pci/controller/pcie-rockchip-ep.c @@ -125,6 +125,7 @@ static void rockchip_pcie_prog_ep_ob_atu static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn, struct pci_epf_header *hdr) { + u32 reg; struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); struct rockchip_pcie *rockchip = &ep->rockchip;
@@ -137,8 +138,9 @@ static int rockchip_pcie_ep_write_header PCIE_CORE_CONFIG_VENDOR); }
- rockchip_pcie_write(rockchip, hdr->deviceid << 16, - ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + PCI_VENDOR_ID); + reg = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_DID_VID); + reg = (reg & 0xFFFF) | (hdr->deviceid << 16); + rockchip_pcie_write(rockchip, reg, PCIE_EP_CONFIG_DID_VID);
rockchip_pcie_write(rockchip, hdr->revid | --- a/drivers/pci/controller/pcie-rockchip.h +++ b/drivers/pci/controller/pcie-rockchip.h @@ -133,6 +133,8 @@ #define PCIE_RC_RP_ATS_BASE 0x400000 #define PCIE_RC_CONFIG_NORMAL_BASE 0x800000 #define PCIE_RC_CONFIG_BASE 0xa00000 +#define PCIE_EP_CONFIG_BASE 0xa00000 +#define PCIE_EP_CONFIG_DID_VID (PCIE_EP_CONFIG_BASE + 0x00) #define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) #define PCIE_RC_CONFIG_SCC_SHIFT 16 #define PCIE_RC_CONFIG_DCR (PCIE_RC_CONFIG_BASE + 0xc4)
From: Rick Wertenbroek rick.wertenbroek@gmail.com
commit 9dd3c7c4c8c3f7f010d9cdb7c3f42506d93c9527 upstream.
The RK3399 PCIe controller should wait until the PHY PLLs are locked. Add poll and timeout to wait for PHY PLLs to be locked. If they cannot be locked generate error message and jump to error handler. Accessing registers in the PHY clock domain when PLLs are not locked causes hang The PHY PLLs status is checked through a side channel register. This is documented in the TRM section 17.5.8.1 "PCIe Initialization Sequence".
Link: https://lore.kernel.org/r/20230418074700.1083505-5-rick.wertenbroek@gmail.co... Fixes: cf590b078391 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") Tested-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Rick Wertenbroek rick.wertenbroek@gmail.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Damien Le Moal dlemoal@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pcie-rockchip.c | 17 +++++++++++++++++ drivers/pci/controller/pcie-rockchip.h | 2 ++ 2 files changed, 19 insertions(+)
--- a/drivers/pci/controller/pcie-rockchip.c +++ b/drivers/pci/controller/pcie-rockchip.c @@ -14,6 +14,7 @@ #include <linux/clk.h> #include <linux/delay.h> #include <linux/gpio/consumer.h> +#include <linux/iopoll.h> #include <linux/of_pci.h> #include <linux/phy/phy.h> #include <linux/platform_device.h> @@ -153,6 +154,12 @@ int rockchip_pcie_parse_dt(struct rockch } EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt);
+#define rockchip_pcie_read_addr(addr) rockchip_pcie_read(rockchip, addr) +/* 100 ms max wait time for PHY PLLs to lock */ +#define RK_PHY_PLL_LOCK_TIMEOUT_US 100000 +/* Sleep should be less than 20ms */ +#define RK_PHY_PLL_LOCK_SLEEP_US 1000 + int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) { struct device *dev = rockchip->dev; @@ -254,6 +261,16 @@ int rockchip_pcie_init_port(struct rockc } }
+ err = readx_poll_timeout(rockchip_pcie_read_addr, + PCIE_CLIENT_SIDE_BAND_STATUS, + regs, !(regs & PCIE_CLIENT_PHY_ST), + RK_PHY_PLL_LOCK_SLEEP_US, + RK_PHY_PLL_LOCK_TIMEOUT_US); + if (err) { + dev_err(dev, "PHY PLLs could not lock, %d\n", err); + goto err_power_off_phy; + } + /* * Please don't reorder the deassert sequence of the following * four reset pins. --- a/drivers/pci/controller/pcie-rockchip.h +++ b/drivers/pci/controller/pcie-rockchip.h @@ -38,6 +38,8 @@ #define PCIE_CLIENT_MODE_EP HIWORD_UPDATE(0x0040, 0) #define PCIE_CLIENT_GEN_SEL_1 HIWORD_UPDATE(0x0080, 0) #define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080) +#define PCIE_CLIENT_SIDE_BAND_STATUS (PCIE_CLIENT_BASE + 0x20) +#define PCIE_CLIENT_PHY_ST BIT(12) #define PCIE_CLIENT_DEBUG_OUT_0 (PCIE_CLIENT_BASE + 0x3c) #define PCIE_CLIENT_DEBUG_LTSSM_MASK GENMASK(5, 0) #define PCIE_CLIENT_DEBUG_LTSSM_L1 0x18
From: Rick Wertenbroek rick.wertenbroek@gmail.com
commit 166e89d99dd85a856343cca51eee781b793801f2 upstream.
Fix legacy IRQ generation for RK3399 PCIe endpoint core according to the technical reference manual (TRM). Assert and deassert legacy interrupt (INTx) through the legacy interrupt control register ("PCIE_CLIENT_LEGACY_INT_CTRL") instead of manually generating a PCIe message. The generation of the legacy interrupt was tested and validated with the PCIe endpoint test driver.
Link: https://lore.kernel.org/r/20230418074700.1083505-8-rick.wertenbroek@gmail.co... Fixes: cf590b078391 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") Tested-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Rick Wertenbroek rick.wertenbroek@gmail.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Damien Le Moal dlemoal@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pcie-rockchip-ep.c | 45 +++++++----------------------- drivers/pci/controller/pcie-rockchip.h | 6 +++- 2 files changed, 16 insertions(+), 35 deletions(-)
--- a/drivers/pci/controller/pcie-rockchip-ep.c +++ b/drivers/pci/controller/pcie-rockchip-ep.c @@ -347,48 +347,25 @@ static int rockchip_pcie_ep_get_msi(stru }
static void rockchip_pcie_ep_assert_intx(struct rockchip_pcie_ep *ep, u8 fn, - u8 intx, bool is_asserted) + u8 intx, bool do_assert) { struct rockchip_pcie *rockchip = &ep->rockchip; - u32 r = ep->max_regions - 1; - u32 offset; - u32 status; - u8 msg_code; - - if (unlikely(ep->irq_pci_addr != ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR || - ep->irq_pci_fn != fn)) { - rockchip_pcie_prog_ep_ob_atu(rockchip, fn, r, - AXI_WRAPPER_NOR_MSG, - ep->irq_phys_addr, 0, 0); - ep->irq_pci_addr = ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR; - ep->irq_pci_fn = fn; - }
intx &= 3; - if (is_asserted) { + + if (do_assert) { ep->irq_pending |= BIT(intx); - msg_code = ROCKCHIP_PCIE_MSG_CODE_ASSERT_INTA + intx; + rockchip_pcie_write(rockchip, + PCIE_CLIENT_INT_IN_ASSERT | + PCIE_CLIENT_INT_PEND_ST_PEND, + PCIE_CLIENT_LEGACY_INT_CTRL); } else { ep->irq_pending &= ~BIT(intx); - msg_code = ROCKCHIP_PCIE_MSG_CODE_DEASSERT_INTA + intx; + rockchip_pcie_write(rockchip, + PCIE_CLIENT_INT_IN_DEASSERT | + PCIE_CLIENT_INT_PEND_ST_NORMAL, + PCIE_CLIENT_LEGACY_INT_CTRL); } - - status = rockchip_pcie_read(rockchip, - ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + - ROCKCHIP_PCIE_EP_CMD_STATUS); - status &= ROCKCHIP_PCIE_EP_CMD_STATUS_IS; - - if ((status != 0) ^ (ep->irq_pending != 0)) { - status ^= ROCKCHIP_PCIE_EP_CMD_STATUS_IS; - rockchip_pcie_write(rockchip, status, - ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + - ROCKCHIP_PCIE_EP_CMD_STATUS); - } - - offset = - ROCKCHIP_PCIE_MSG_ROUTING(ROCKCHIP_PCIE_MSG_ROUTING_LOCAL_INTX) | - ROCKCHIP_PCIE_MSG_CODE(msg_code) | ROCKCHIP_PCIE_MSG_NO_DATA; - writel(0, ep->irq_cpu_addr + offset); }
static int rockchip_pcie_ep_send_legacy_irq(struct rockchip_pcie_ep *ep, u8 fn, --- a/drivers/pci/controller/pcie-rockchip.h +++ b/drivers/pci/controller/pcie-rockchip.h @@ -38,6 +38,11 @@ #define PCIE_CLIENT_MODE_EP HIWORD_UPDATE(0x0040, 0) #define PCIE_CLIENT_GEN_SEL_1 HIWORD_UPDATE(0x0080, 0) #define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080) +#define PCIE_CLIENT_LEGACY_INT_CTRL (PCIE_CLIENT_BASE + 0x0c) +#define PCIE_CLIENT_INT_IN_ASSERT HIWORD_UPDATE_BIT(0x0002) +#define PCIE_CLIENT_INT_IN_DEASSERT HIWORD_UPDATE(0x0002, 0) +#define PCIE_CLIENT_INT_PEND_ST_PEND HIWORD_UPDATE_BIT(0x0001) +#define PCIE_CLIENT_INT_PEND_ST_NORMAL HIWORD_UPDATE(0x0001, 0) #define PCIE_CLIENT_SIDE_BAND_STATUS (PCIE_CLIENT_BASE + 0x20) #define PCIE_CLIENT_PHY_ST BIT(12) #define PCIE_CLIENT_DEBUG_OUT_0 (PCIE_CLIENT_BASE + 0x3c) @@ -228,7 +233,6 @@ #define ROCKCHIP_PCIE_EP_MSI_CTRL_ME BIT(16) #define ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP BIT(24) #define ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR 0x1 -#define ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR 0x3 #define ROCKCHIP_PCIE_EP_FUNC_BASE(fn) (((fn) << 12) & GENMASK(19, 12)) #define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \ (PCIE_RC_RP_ATS_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008)
From: Rick Wertenbroek rick.wertenbroek@gmail.com
commit 8962b2cb39119cbda4fc69a1f83957824f102f81 upstream.
Previously u16 variables were used to access 32-bit registers, this resulted in not all of the data being read from the registers. Also the left shift of more than 16-bits would result in moving data out of the variable. Use u32 variables to access 32-bit registers
Link: https://lore.kernel.org/r/20230418074700.1083505-10-rick.wertenbroek@gmail.c... Fixes: cf590b078391 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") Tested-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Rick Wertenbroek rick.wertenbroek@gmail.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Damien Le Moal dlemoal@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pcie-rockchip-ep.c | 10 +++++----- drivers/pci/controller/pcie-rockchip.h | 1 + 2 files changed, 6 insertions(+), 5 deletions(-)
--- a/drivers/pci/controller/pcie-rockchip-ep.c +++ b/drivers/pci/controller/pcie-rockchip-ep.c @@ -314,15 +314,15 @@ static int rockchip_pcie_ep_set_msi(stru { struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); struct rockchip_pcie *rockchip = &ep->rockchip; - u16 flags; + u32 flags;
flags = rockchip_pcie_read(rockchip, ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + ROCKCHIP_PCIE_EP_MSI_CTRL_REG); flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK; flags |= - ((multi_msg_cap << 1) << ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) | - PCI_MSI_FLAGS_64BIT; + (multi_msg_cap << ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) | + (PCI_MSI_FLAGS_64BIT << ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET); flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP; rockchip_pcie_write(rockchip, flags, ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + @@ -334,7 +334,7 @@ static int rockchip_pcie_ep_get_msi(stru { struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); struct rockchip_pcie *rockchip = &ep->rockchip; - u16 flags; + u32 flags;
flags = rockchip_pcie_read(rockchip, ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + @@ -395,7 +395,7 @@ static int rockchip_pcie_ep_send_msi_irq u8 interrupt_num) { struct rockchip_pcie *rockchip = &ep->rockchip; - u16 flags, mme, data, data_mask; + u32 flags, mme, data, data_mask; u8 msi_count; u64 pci_addr, pci_addr_mask = 0xff;
--- a/drivers/pci/controller/pcie-rockchip.h +++ b/drivers/pci/controller/pcie-rockchip.h @@ -226,6 +226,7 @@ #define ROCKCHIP_PCIE_EP_CMD_STATUS 0x4 #define ROCKCHIP_PCIE_EP_CMD_STATUS_IS BIT(19) #define ROCKCHIP_PCIE_EP_MSI_CTRL_REG 0x90 +#define ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET 16 #define ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET 17 #define ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK GENMASK(19, 17) #define ROCKCHIP_PCIE_EP_MSI_CTRL_MME_OFFSET 20
From: Damien Le Moal dlemoal@kernel.org
commit 7e6689b34a815bd379dfdbe9855d36f395ef056c upstream.
The address translation unit of the rockchip EP controller does not use the lower 8 bits of a PCIe-space address to map local memory. Thus we must set the align feature field to 256 to let the user know about this constraint.
Link: https://lore.kernel.org/r/20230418074700.1083505-12-rick.wertenbroek@gmail.c... Fixes: cf590b078391 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") Signed-off-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Rick Wertenbroek rick.wertenbroek@gmail.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pcie-rockchip-ep.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/pci/controller/pcie-rockchip-ep.c +++ b/drivers/pci/controller/pcie-rockchip-ep.c @@ -485,6 +485,7 @@ static const struct pci_epc_features roc .linkup_notifier = false, .msi_capable = true, .msix_capable = false, + .align = 256, };
static const struct pci_epc_features*
From: Damien Le Moal dlemoal@kernel.org
commit f61b7634a3249d12b9daa36ffbdb9965b6f24c6c upstream.
In pci_endpoint_test_remove(), freeing the IRQs after removing the device creates a small race window for IRQs to be received with the test device memory already released, causing the IRQ handler to access invalid memory, resulting in an oops.
Free the device IRQs before removing the device to avoid this issue.
Link: https://lore.kernel.org/r/20230415023542.77601-15-dlemoal@kernel.org Fixes: e03327122e2c ("pci_endpoint_test: Add 2 ioctl commands") Signed-off-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Manivannan Sadhasivam mani@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/pci_endpoint_test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c @@ -937,6 +937,9 @@ static void pci_endpoint_test_remove(str if (id < 0) return;
+ pci_endpoint_test_release_irq(test); + pci_endpoint_test_free_irq_vectors(test); + misc_deregister(&test->miscdev); kfree(misc_device->name); kfree(test->name); @@ -946,9 +949,6 @@ static void pci_endpoint_test_remove(str pci_iounmap(pdev, test->bar[bar]); }
- pci_endpoint_test_release_irq(test); - pci_endpoint_test_free_irq_vectors(test); - pci_release_regions(pdev); pci_disable_device(pdev); }
From: Damien Le Moal dlemoal@kernel.org
commit fb620ae73b70c2f57b9d3e911fc24c024ba2324f upstream.
The irq_raised completion used to detect the end of a test case is initialized when the test device is probed, but never reinitialized again before a test case. As a result, the irq_raised completion synchronization is effective only for the first ioctl test case executed. Any subsequent call to wait_for_completion() by another ioctl() call will immediately return, potentially too early, leading to false positive failures.
Fix this by reinitializing the irq_raised completion before starting a new ioctl() test command.
Link: https://lore.kernel.org/r/20230415023542.77601-16-dlemoal@kernel.org Fixes: 2c156ac71c6b ("misc: Add host side PCI driver for PCI test function device") Signed-off-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Manivannan Sadhasivam mani@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/pci_endpoint_test.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c @@ -728,6 +728,10 @@ static long pci_endpoint_test_ioctl(stru struct pci_dev *pdev = test->pdev;
mutex_lock(&test->mutex); + + reinit_completion(&test->irq_raised); + test->last_irq = -ENODATA; + switch (cmd) { case PCITEST_BAR: bar = arg;
From: Johan Hovold johan+linaro@kernel.org
commit d420c9886f5369697047b880221789bf0054e438 upstream.
Add the missing module device table alias to that the driver can be autoloaded when built as a module.
Cc: stable@vger.kernel.org # 5.14 Fixes: 6b149f3310a4 ("mfd: pm8008: Add driver for QCOM PM8008 PMIC") Signed-off-by: Johan Hovold johan+linaro@kernel.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Lee Jones lee@kernel.org Link: https://lore.kernel.org/r/20230526091646.17318-2-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mfd/qcom-pm8008.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/mfd/qcom-pm8008.c +++ b/drivers/mfd/qcom-pm8008.c @@ -233,6 +233,7 @@ static const struct of_device_id pm8008_ { .compatible = "qcom,pm8008", }, { }, }; +MODULE_DEVICE_TABLE(of, pm8008_match);
static struct i2c_driver pm8008_mfd_driver = { .driver = {
From: Jason Baron jbaron@akamai.com
commit e836007089ba8fdf24e636ef2b007651fb4582e6 upstream.
We've found that using raid0 with the 'original' layout and discard enabled with different disk sizes (such that at least two zones are created) can result in data corruption. This is due to the fact that the discard handling in 'raid0_handle_discard()' assumes the 'alternate' layout. We've seen this corruption using ext4 but other filesystems are likely susceptible as well.
More specifically, while multiple zones are necessary to create the corruption, the corruption may not occur with multiple zones if they layout in such a way the layout matches what the 'alternate' layout would have produced. Thus, not all raid0 devices with the 'original' layout, different size disks and discard enabled will encounter this corruption.
The 3.14 kernel inadvertently changed the raid0 disk layout for different size disks. Thus, running a pre-3.14 kernel and post-3.14 kernel on the same raid0 array could corrupt data. This lead to the creation of the 'original' layout (to match the pre-3.14 layout) and the 'alternate' layout (to match the post 3.14 layout) in the 5.4 kernel time frame and an option to tell the kernel which layout to use (since it couldn't be autodetected). However, when the 'original' layout was added back to 5.4 discard support for the 'original' layout was not added leading this issue.
I've been able to reliably reproduce the corruption with the following test case:
1. create raid0 array with different size disks using original layout 2. mkfs 3. mount -o discard 4. create lots of files 5. remove 1/2 the files 6. fstrim -a (or just the mount point for the raid0 array) 7. umount 8. fsck -fn /dev/md0 (spews all sorts of corruptions)
Let's fix this by adding proper discard support to the 'original' layout. The fix 'maps' the 'original' layout disks to the order in which they are read/written such that we can compare the disks in the same way that the current 'alternate' layout does. A 'disk_shift' field is added to 'struct strip_zone'. This could be computed on the fly in raid0_handle_discard() but by adding this field, we save some computation in the discard path.
Note we could also potentially fix this by re-ordering the disks in the zones that follow the first one, and then always read/writing them using the 'alternate' layout. However, that is seen as a more substantial change, and we are attempting the least invasive fix at this time to remedy the corruption.
I've verified the change using the reproducer mentioned above. Typically, the corruption is seen after less than 3 iterations, while the patch has run 500+ iterations.
Cc: NeilBrown neilb@suse.de Cc: Song Liu song@kernel.org Fixes: c84a1372df92 ("md/raid0: avoid RAID0 data corruption due to layout confusion.") Cc: stable@vger.kernel.org Signed-off-by: Jason Baron jbaron@akamai.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230623180523.1901230-1-jbaron@akamai.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/raid0.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++------- drivers/md/raid0.h | 1 2 files changed, 55 insertions(+), 8 deletions(-)
--- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -274,6 +274,18 @@ static int create_strip_zones(struct mdd goto abort; }
+ if (conf->layout == RAID0_ORIG_LAYOUT) { + for (i = 1; i < conf->nr_strip_zones; i++) { + sector_t first_sector = conf->strip_zone[i-1].zone_end; + + sector_div(first_sector, mddev->chunk_sectors); + zone = conf->strip_zone + i; + /* disk_shift is first disk index used in the zone */ + zone->disk_shift = sector_div(first_sector, + zone->nb_dev); + } + } + pr_debug("md/raid0:%s: done.\n", mdname(mddev)); *private_conf = conf;
@@ -444,6 +456,20 @@ exit_acct_set: return ret; }
+/* + * Convert disk_index to the disk order in which it is read/written. + * For example, if we have 4 disks, they are numbered 0,1,2,3. If we + * write the disks starting at disk 3, then the read/write order would + * be disk 3, then 0, then 1, and then disk 2 and we want map_disk_shift() + * to map the disks as follows 0,1,2,3 => 1,2,3,0. So disk 0 would map + * to 1, 1 to 2, 2 to 3, and 3 to 0. That way we can compare disks in + * that 'output' space to understand the read/write disk ordering. + */ +static int map_disk_shift(int disk_index, int num_disks, int disk_shift) +{ + return ((disk_index + num_disks - disk_shift) % num_disks); +} + static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) { struct r0conf *conf = mddev->private; @@ -457,7 +483,9 @@ static void raid0_handle_discard(struct sector_t end_disk_offset; unsigned int end_disk_index; unsigned int disk; + sector_t orig_start, orig_end;
+ orig_start = start; zone = find_zone(conf, &start);
if (bio_end_sector(bio) > zone->zone_end) { @@ -471,6 +499,7 @@ static void raid0_handle_discard(struct } else end = bio_end_sector(bio);
+ orig_end = end; if (zone != conf->strip_zone) end = end - zone[-1].zone_end;
@@ -482,13 +511,26 @@ static void raid0_handle_discard(struct last_stripe_index = end; sector_div(last_stripe_index, stripe_size);
- start_disk_index = (int)(start - first_stripe_index * stripe_size) / - mddev->chunk_sectors; + /* In the first zone the original and alternate layouts are the same */ + if ((conf->layout == RAID0_ORIG_LAYOUT) && (zone != conf->strip_zone)) { + sector_div(orig_start, mddev->chunk_sectors); + start_disk_index = sector_div(orig_start, zone->nb_dev); + start_disk_index = map_disk_shift(start_disk_index, + zone->nb_dev, + zone->disk_shift); + sector_div(orig_end, mddev->chunk_sectors); + end_disk_index = sector_div(orig_end, zone->nb_dev); + end_disk_index = map_disk_shift(end_disk_index, + zone->nb_dev, zone->disk_shift); + } else { + start_disk_index = (int)(start - first_stripe_index * stripe_size) / + mddev->chunk_sectors; + end_disk_index = (int)(end - last_stripe_index * stripe_size) / + mddev->chunk_sectors; + } start_disk_offset = ((int)(start - first_stripe_index * stripe_size) % mddev->chunk_sectors) + first_stripe_index * mddev->chunk_sectors; - end_disk_index = (int)(end - last_stripe_index * stripe_size) / - mddev->chunk_sectors; end_disk_offset = ((int)(end - last_stripe_index * stripe_size) % mddev->chunk_sectors) + last_stripe_index * mddev->chunk_sectors; @@ -496,18 +538,22 @@ static void raid0_handle_discard(struct for (disk = 0; disk < zone->nb_dev; disk++) { sector_t dev_start, dev_end; struct md_rdev *rdev; + int compare_disk; + + compare_disk = map_disk_shift(disk, zone->nb_dev, + zone->disk_shift);
- if (disk < start_disk_index) + if (compare_disk < start_disk_index) dev_start = (first_stripe_index + 1) * mddev->chunk_sectors; - else if (disk > start_disk_index) + else if (compare_disk > start_disk_index) dev_start = first_stripe_index * mddev->chunk_sectors; else dev_start = start_disk_offset;
- if (disk < end_disk_index) + if (compare_disk < end_disk_index) dev_end = (last_stripe_index + 1) * mddev->chunk_sectors; - else if (disk > end_disk_index) + else if (compare_disk > end_disk_index) dev_end = last_stripe_index * mddev->chunk_sectors; else dev_end = end_disk_offset; --- a/drivers/md/raid0.h +++ b/drivers/md/raid0.h @@ -6,6 +6,7 @@ struct strip_zone { sector_t zone_end; /* Start of the next zone (in sectors) */ sector_t dev_start; /* Zone offset in real dev (in sectors) */ int nb_dev; /* # of devices attached to the zone */ + int disk_shift; /* start disk for the original layout */ };
/* Linux 3.14 (20d0189b101) made an unintended change to
From: Peter Korsgaard peter@korsgaard.com
commit 035641b01e72af4f6c6cf22a4bdb5d7dfc4e8e8e upstream.
Just calling wait_for_device_probe() is not enough to ensure that asynchronously probed block devices are available (E.G. mmc, usb), so add a "dm-mod.waitfor=<device1>[,..,<deviceN>]" parameter to get dm-init to explicitly wait for specific block devices before initializing the tables with logic similar to the rootwait logic that was introduced with commit cc1ed7542c8c ("init: wait for asynchronously scanned block devices").
E.G. with dm-verity on mmc using: dm-mod.waitfor="PARTLABEL=hash-a,PARTLABEL=root-a"
[ 0.671671] device-mapper: init: waiting for all devices to be available before creating mapped devices [ 0.671679] device-mapper: init: waiting for device PARTLABEL=hash-a ... [ 0.710695] mmc0: new HS200 MMC card at address 0001 [ 0.711158] mmcblk0: mmc0:0001 004GA0 3.69 GiB [ 0.715954] mmcblk0boot0: mmc0:0001 004GA0 partition 1 2.00 MiB [ 0.722085] mmcblk0boot1: mmc0:0001 004GA0 partition 2 2.00 MiB [ 0.728093] mmcblk0rpmb: mmc0:0001 004GA0 partition 3 512 KiB, chardev (249:0) [ 0.738274] mmcblk0: p1 p2 p3 p4 p5 p6 p7 [ 0.751282] device-mapper: init: waiting for device PARTLABEL=root-a ... [ 0.751306] device-mapper: init: all devices available [ 0.751683] device-mapper: verity: sha256 using implementation "sha256-generic" [ 0.759344] device-mapper: ioctl: dm-0 (vroot) is ready [ 0.766540] VFS: Mounted root (squashfs filesystem) readonly on device 254:0.
Signed-off-by: Peter Korsgaard peter@korsgaard.com Signed-off-by: Mike Snitzer snitzer@kernel.org Cc: Mark-PK Tsai mark-pk.tsai@mediatek.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/admin-guide/device-mapper/dm-init.rst | 8 +++++++ drivers/md/dm-init.c | 22 +++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-)
--- a/Documentation/admin-guide/device-mapper/dm-init.rst +++ b/Documentation/admin-guide/device-mapper/dm-init.rst @@ -123,3 +123,11 @@ Other examples (per target): 0 1638400 verity 1 8:1 8:2 4096 4096 204800 1 sha256 fb1a5a0f00deb908d8b53cb270858975e76cf64105d412ce764225d53b8f3cfd 51934789604d1b92399c52e7cb149d1b3a1b74bbbcb103b2a0aaacbed5c08584 + +For setups using device-mapper on top of asynchronously probed block +devices (MMC, USB, ..), it may be necessary to tell dm-init to +explicitly wait for them to become available before setting up the +device-mapper tables. This can be done with the "dm-mod.waitfor=" +module parameter, which takes a list of devices to wait for:: + + dm-mod.waitfor=<device1>[,..,<deviceN>] --- a/drivers/md/dm-init.c +++ b/drivers/md/dm-init.c @@ -8,6 +8,7 @@ */
#include <linux/ctype.h> +#include <linux/delay.h> #include <linux/device.h> #include <linux/device-mapper.h> #include <linux/init.h> @@ -18,12 +19,17 @@ #define DM_MAX_DEVICES 256 #define DM_MAX_TARGETS 256 #define DM_MAX_STR_SIZE 4096 +#define DM_MAX_WAITFOR 256
static char *create;
+static char *waitfor[DM_MAX_WAITFOR]; + /* * Format: dm-mod.create=<name>,<uuid>,<minor>,<flags>,<table>[,<table>+][;<name>,<uuid>,<minor>,<flags>,<table>[,<table>+]+] * Table format: <start_sector> <num_sectors> <target_type> <target_args> + * Block devices to wait for to become available before setting up tables: + * dm-mod.waitfor=<device1>[,..,<deviceN>] * * See Documentation/admin-guide/device-mapper/dm-init.rst for dm-mod.create="..." format * details. @@ -266,7 +272,7 @@ static int __init dm_init_init(void) struct dm_device *dev; LIST_HEAD(devices); char *str; - int r; + int i, r;
if (!create) return 0; @@ -286,6 +292,17 @@ static int __init dm_init_init(void) DMINFO("waiting for all devices to be available before creating mapped devices"); wait_for_device_probe();
+ for (i = 0; i < ARRAY_SIZE(waitfor); i++) { + if (waitfor[i]) { + DMINFO("waiting for device %s ...", waitfor[i]); + while (!dm_get_dev_t(waitfor[i])) + msleep(5); + } + } + + if (waitfor[0]) + DMINFO("all devices available"); + list_for_each_entry(dev, &devices, list) { if (dm_early_create(&dev->dmi, dev->table, dev->target_args_array)) @@ -301,3 +318,6 @@ late_initcall(dm_init_init);
module_param(create, charp, 0); MODULE_PARM_DESC(create, "Create a mapped device in early boot"); + +module_param_array(waitfor, charp, NULL, 0); +MODULE_PARM_DESC(waitfor, "Devices to wait for before setting up tables");
From: Alexander Aring aahringo@redhat.com
commit 92655fbda5c05950a411eaabc19e025e86e2a291 upstream.
The GETLK pid values have all been negated since commit 9d5b86ac13c5 ("fs/locks: Remove fl_nspid and use fs-specific l_pid for remote locks"). Revert this for local pids, and leave in place negative pids for remote owners.
Cc: stable@vger.kernel.org Fixes: 9d5b86ac13c5 ("fs/locks: Remove fl_nspid and use fs-specific l_pid for remote locks") Signed-off-by: Alexander Aring aahringo@redhat.com Signed-off-by: David Teigland teigland@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/dlm/plock.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c @@ -363,7 +363,9 @@ int dlm_posix_get(dlm_lockspace_t *locks locks_init_lock(fl); fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK; fl->fl_flags = FL_POSIX; - fl->fl_pid = -op->info.pid; + fl->fl_pid = op->info.pid; + if (op->info.nodeid != dlm_our_nodeid()) + fl->fl_pid = -fl->fl_pid; fl->fl_start = op->info.start; fl->fl_end = op->info.end; rv = 0;
From: Brian Norris briannorris@chromium.org
commit 9d0e3cac3517942a6e00eeecfe583a98715edb16 upstream.
The self-refresh helper framework overloads "disable" to sometimes mean "go into self-refresh mode," and this mode activates automatically (e.g., after some period of unchanging display output). In such cases, the display pipe is still considered "on", and user-space is not aware that we went into self-refresh mode. Thus, users may expect that vblank-related features (such as DRM_IOCTL_WAIT_VBLANK) still work properly.
However, we trigger the WARN_ONCE() here if a CRTC driver tries to leave vblank enabled.
Add a different expectation: that CRTCs *should* leave vblank enabled when going into self-refresh.
This patch is preparation for another patch -- "drm/rockchip: vop: Leave vblank enabled in self-refresh" -- which resolves conflicts between the above self-refresh behavior and the API tests in IGT's kms_vblank test module.
== Some alternatives discussed: ==
It's likely that on many display controllers, vblank interrupts will turn off when the CRTC is disabled, and so in some cases, self-refresh may not support vblank. To support such cases, we might consider additions to the generic helpers such that we fire vblank events based on a timer.
However, there is currently only one driver using the common self-refresh helpers (i.e., rockchip), and at least as of commit bed030a49f3e ("drm/rockchip: Don't fully disable vop on self refresh"), the CRTC hardware is powered enough to continue to generate vblank interrupts.
So we chose the simpler option of leaving vblank interrupts enabled. We can reevaluate this decision and perhaps augment the helpers if/when we gain a second driver that has different requirements.
v3: * include discussion summary
v2: * add 'ret != 0' warning case for self-refresh * describe failing test case and relation to drm/rockchip patch better
Cc: stable@vger.kernel.org # dependency for "drm/rockchip: vop: Leave # vblank enabled in self-refresh" Signed-off-by: Brian Norris briannorris@chromium.org Signed-off-by: Sean Paul seanpaul@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20230109171809.v3.1.I3904f6978... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_atomic_helper.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1115,7 +1115,16 @@ disable_outputs(struct drm_device *dev, continue;
ret = drm_crtc_vblank_get(crtc); - WARN_ONCE(ret != -EINVAL, "driver forgot to call drm_crtc_vblank_off()\n"); + /* + * Self-refresh is not a true "disable"; ensure vblank remains + * enabled. + */ + if (new_crtc_state->self_refresh_active) + WARN_ONCE(ret != 0, + "driver disabled vblank in self-refresh\n"); + else + WARN_ONCE(ret != -EINVAL, + "driver forgot to call drm_crtc_vblank_off()\n"); if (ret == 0) drm_crtc_vblank_put(crtc); }
From: Brian Norris briannorris@chromium.org
commit 2bdba9d4a3baa758c2ca7f5b37b35c7b3391dc42 upstream.
If we disable vblank when entering self-refresh, vblank APIs (like DRM_IOCTL_WAIT_VBLANK) no longer work. But user space is not aware when we enter self-refresh, so this appears to be an API violation -- that DRM_IOCTL_WAIT_VBLANK fails with EINVAL whenever the display is idle and enters self-refresh.
The downstream driver used by many of these systems never used to disable vblank for PSR, and in fact, even upstream, we didn't do that until radically redesigning the state machine in commit 6c836d965bad ("drm/rockchip: Use the helpers for PSR").
Thus, it seems like a reasonable API fix to simply restore that behavior, and leave vblank enabled.
Note that this appears to potentially unbalance the drm_crtc_vblank_{off,on}() calls in some cases, but: (a) drm_crtc_vblank_on() documents this as OK and (b) if I do the naive balancing, I find state machine issues such that we're not in sync properly; so it's easier to take advantage of (a).
This issue was exposed by IGT's kms_vblank tests, and reported by KernelCI. The bug has been around a while (longer than KernelCI noticed), but was only exposed once self-refresh was bugfixed more recently, and so KernelCI could properly test it. Some other notes in:
https://lore.kernel.org/dri-devel/Y6OCg9BPnJvimQLT@google.com/ Re: renesas/master bisection: igt-kms-rockchip.kms_vblank.pipe-A-wait-forked on rk3399-gru-kevin
== Backporting notes: ==
Marking as 'Fixes' commit 6c836d965bad ("drm/rockchip: Use the helpers for PSR"), but it probably depends on commit bed030a49f3e ("drm/rockchip: Don't fully disable vop on self refresh") as well.
We also need the previous patch ("drm/atomic: Allow vblank-enabled + self-refresh "disable""), of course.
v3: * no update
v2: * skip unnecessary lock/unlock
Fixes: 6c836d965bad ("drm/rockchip: Use the helpers for PSR") Cc: stable@vger.kernel.org Reported-by: "kernelci.org bot" bot@kernelci.org Link: https://lore.kernel.org/dri-devel/Y5itf0+yNIQa6fU4@sirena.org.uk/ Signed-off-by: Brian Norris briannorris@chromium.org Signed-off-by: Sean Paul seanpaul@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20230109171809.v3.2.Ic07cba4ab... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -703,13 +703,13 @@ static void vop_crtc_atomic_disable(stru if (crtc->state->self_refresh_active) rockchip_drm_set_win_enabled(crtc, false);
+ if (crtc->state->self_refresh_active) + goto out; + mutex_lock(&vop->vop_lock);
drm_crtc_vblank_off(crtc);
- if (crtc->state->self_refresh_active) - goto out; - /* * Vop standby will take effect at end of current frame, * if dsp hold valid irq happen, it means standby complete. @@ -741,9 +741,9 @@ static void vop_crtc_atomic_disable(stru vop_core_clks_disable(vop); pm_runtime_put(vop->dev);
-out: mutex_unlock(&vop->vop_lock);
+out: if (crtc->state->event && !crtc->state->active) { spin_lock_irq(&crtc->dev->event_lock); drm_crtc_send_vblank_event(crtc, crtc->state->event);
From: Samuel Pitoiset samuel.pitoiset@gmail.com
commit ea2c3c08554601b051d91403a241266e1cf490a5 upstream.
Per VM BOs must be marked as moved or otherwise their ranges are not updated on use which might be necessary when the replace operation splits mappings.
This fixes random GPU hangs when replacing sparse mappings from the userspace, while OP_MAP/OP_UNMAP works fine because always valid BOs are correctly handled there.
Cc: stable@vger.kernel.org Signed-off-by: Samuel Pitoiset samuel.pitoiset@gmail.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2575,18 +2575,30 @@ int amdgpu_vm_bo_clear_mappings(struct a
/* Insert partial mapping before the range */ if (!list_empty(&before->list)) { + struct amdgpu_bo *bo = before->bo_va->base.bo; + amdgpu_vm_it_insert(before, &vm->va); if (before->flags & AMDGPU_PTE_PRT) amdgpu_vm_prt_get(adev); + + if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv && + !before->bo_va->base.moved) + amdgpu_vm_bo_moved(&before->bo_va->base); } else { kfree(before); }
/* Insert partial mapping after the range */ if (!list_empty(&after->list)) { + struct amdgpu_bo *bo = after->bo_va->base.bo; + amdgpu_vm_it_insert(after, &vm->va); if (after->flags & AMDGPU_PTE_PRT) amdgpu_vm_prt_get(adev); + + if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv && + !after->bo_va->base.moved) + amdgpu_vm_bo_moved(&after->bo_va->base); } else { kfree(after); }
From: Mario Limonciello mario.limonciello@amd.com
commit 274d205cb59f43815542e04b42a9e6d0b9b95eff upstream.
The `DMUB_FW_VERSION` macro has a mistake in that the revision field is off by one byte. The last byte is typically used for other purposes and not a revision.
Cc: stable@vger.kernel.org Cc: Sean Wang sean.ns.wang@amd.com Cc: Marc Rossi Marc.Rossi@amd.com Cc: Hamza Mahfooz Hamza.Mahfooz@amd.com Cc: Tsung-hua (Ryan) Lin Tsung-hua.Lin@amd.com Reviewed-by: Leo Li sunpeng.li@amd.com Signed-off-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -445,7 +445,7 @@ struct dmub_notification { * of a firmware to know if feature or functionality is supported or present. */ #define DMUB_FW_VERSION(major, minor, revision) \ - ((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | ((revision) & 0xFFFF)) + ((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | (((revision) & 0xFF) << 8))
/** * dmub_srv_create() - creates the DMUB service.
From: gaba gaba@amd.com
commit 8a774fe912ff09e39c2d3a3589c729330113f388 upstream.
In restore process worker, pinned BO cause update PTE fail, then the function re-schedule the restore_work. This will generate dead loop.
Signed-off-by: gaba gaba@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -2350,6 +2350,9 @@ int amdgpu_amdkfd_gpuvm_restore_process_ if (!attachment->is_mapped) continue;
+ if (attachment->bo_va->base.bo->tbo.pin_count) + continue; + kfd_mem_dmaunmap_attachment(mem, attachment); ret = update_gpuvm_pte(mem, attachment, &sync_obj, NULL); if (ret) {
From: Thomas Hellström thomas.hellstrom@linux.intel.com
commit a590f03d8de7c4cb7ce4916dc7f2fd10711faabe upstream.
If moving the bo to system for swapout failed, we were leaking a resource. Fix.
Fixes: bfa3357ef9ab ("drm/ttm: allocate resource object instead of embedding it v2") Cc: Christian König christian.koenig@amd.com Cc: "Christian König" ckoenig.leichtzumerken@gmail.com Cc: dri-devel@lists.freedesktop.org Cc: stable@vger.kernel.org # v5.14+ Signed-off-by: Thomas Hellström thomas.hellstrom@linux.intel.com Reviewed-by: Nirmoy Das nirmoy.das@intel.com Reviewed-by: Andi Shyti andi.shyti@linux.intel.com Reviewed-by: Christian König christian.koenig@amd.com Link: https://patchwork.freedesktop.org/patch/msgid/20230626091450.14757-5-thomas.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/ttm/ttm_bo.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1187,6 +1187,7 @@ int ttm_bo_swapout(struct ttm_buffer_obj ret = ttm_bo_handle_move_mem(bo, evict_mem, true, &ctx, &hop); if (unlikely(ret != 0)) { WARN(ret == -EMULTIHOP, "Unexpected multihop in swaput - likely driver bug.\n"); + ttm_resource_free(bo, &evict_mem); goto out; } }
From: Christian König christian.koenig@amd.com
commit a2848d08742c8e8494675892c02c0d22acbe3cf8 upstream.
There is a small window where we have already incremented the pin count but not yet moved the bo from the lru to the pinned list.
Signed-off-by: Christian König christian.koenig@amd.com Reported-by: Pelloux-Prayer, Pierre-Eric Pierre-eric.Pelloux-prayer@amd.com Tested-by: Pelloux-Prayer, Pierre-Eric Pierre-eric.Pelloux-prayer@amd.com Acked-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230707120826.3701-1-christia... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/ttm/ttm_bo.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -603,6 +603,12 @@ static bool ttm_bo_evict_swapout_allowab { bool ret = false;
+ if (bo->pin_count) { + *locked = false; + *busy = false; + return false; + } + if (bo->base.resv == ctx->resv) { dma_resv_assert_held(bo->base.resv); if (ctx->allow_res_evict)
From: Dan Carpenter dan.carpenter@linaro.org
commit 27a826837ec9a3e94cc44bd9328b8289b0fcecd7 upstream.
The atmel_complete_tx_dma() function disables IRQs at the start of the function by calling spin_lock_irqsave(&port->lock, flags); There is no need to disable them a second time using the spin_lock_irq() function and, in fact, doing so is a bug because it will enable IRQs prematurely when we call spin_unlock_irq().
Just use spin_lock/unlock() instead without disabling or enabling IRQs.
Fixes: 08f738be88bb ("serial: at91: add tx dma support") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Reviewed-by: Jiri Slaby jirislaby@kernel.org Acked-by: Richard Genoud richard.genoud@gmail.com Link: https://lore.kernel.org/r/cb7c39a9-c004-4673-92e1-be4e34b85368@moroto.mounta... Cc: stable stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/atmel_serial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -873,11 +873,11 @@ static void atmel_complete_tx_dma(void *
port->icount.tx += atmel_port->tx_len;
- spin_lock_irq(&atmel_port->lock_tx); + spin_lock(&atmel_port->lock_tx); async_tx_ack(atmel_port->desc_tx); atmel_port->cookie_tx = -EINVAL; atmel_port->desc_tx = NULL; - spin_unlock_irq(&atmel_port->lock_tx); + spin_unlock(&atmel_port->lock_tx);
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
commit a9c09546e903f1068acfa38e1ee18bded7114b37 upstream.
If clk_get_rate() fails, the clk that has just been allocated needs to be freed.
Cc: stable@vger.kernel.org # v3.3+ Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Andi Shyti andi.shyti@kernel.org Fixes: 5f5a7a5578c5 ("serial: samsung: switch to clkdev based clock lookup") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Jiri Slaby jirislaby@kernel.org Message-ID: e4baf6039368f52e5a5453982ddcb9a330fc689e.1686412569.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/samsung_tty.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -1478,8 +1478,12 @@ static unsigned int s3c24xx_serial_getcl continue;
rate = clk_get_rate(clk); - if (!rate) + if (!rate) { + dev_err(ourport->port.dev, + "Failed to get clock rate for %s.\n", clkname); + clk_put(clk); continue; + }
if (ourport->info->has_divslot) { unsigned long div = rate / req_baud;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
commit 832e231cff476102e8204a9e7bddfe5c6154a375 upstream.
When the best clk is searched, we iterate over all possible clk.
If we find a better match, the previous one, if any, needs to be freed. If a better match has already been found, we still need to free the new one, otherwise it leaks.
Cc: stable@vger.kernel.org # v3.3+ Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Andi Shyti andi.shyti@kernel.org Fixes: 5f5a7a5578c5 ("serial: samsung: switch to clkdev based clock lookup") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Jiri Slaby jirislaby@kernel.org Message-ID: cf3e0053d2fc7391b2d906a86cd01a5ef15fb9dc.1686412569.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/samsung_tty.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -1509,10 +1509,18 @@ static unsigned int s3c24xx_serial_getcl calc_deviation = -calc_deviation;
if (calc_deviation < deviation) { + /* + * If we find a better clk, release the previous one, if + * any. + */ + if (!IS_ERR(*best_clk)) + clk_put(*best_clk); *best_clk = clk; best_quot = quot; *clk_num = cnt; deviation = calc_deviation; + } else { + clk_put(clk); } }
From: Martin Fuzzey martin.fuzzey@flowbird.group
commit 639949a7031e04c59ec91614eceb9543e9120f43 upstream.
Since commit 79d0224f6bf2 ("tty: serial: imx: Handle RS485 DE signal active high") RS485 reception no longer works after a transmission.
The following scenario shows the problem: 1) Open a port in RS485 mode 2) Receive data from remote (OK) 3) Transmit data to remote (OK) 4) Receive data from remote (Nothing received)
In RS485 mode, imx_uart_start_tx() calls imx_uart_stop_rx() and, when the transmission is complete, imx_uart_stop_tx() calls imx_uart_start_rx().
Since the above commit imx_uart_stop_rx() now sets the loopback bit but imx_uart_start_rx() does not clear it causing the hardware to remain in loopback mode and not receive external data.
Fix this by moving the existing loopback disable code to a helper function and calling it from imx_uart_start_rx() too.
Fixes: 79d0224f6bf2 ("tty: serial: imx: Handle RS485 DE signal active high") Cc: stable@vger.kernel.org Signed-off-by: Martin Fuzzey martin.fuzzey@flowbird.group Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/r/20230616104838.2729694-1-martin.fuzzey@flowbird.gr... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/imx.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
--- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -397,6 +397,16 @@ static void start_hrtimer_ms(struct hrti hrtimer_start(hrt, ms_to_ktime(msec), HRTIMER_MODE_REL); }
+static void imx_uart_disable_loopback_rs485(struct imx_port *sport) +{ + unsigned int uts; + + /* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */ + uts = imx_uart_readl(sport, imx_uart_uts_reg(sport)); + uts &= ~UTS_LOOP; + imx_uart_writel(sport, uts, imx_uart_uts_reg(sport)); +} + /* called with port.lock taken and irqs off */ static void imx_uart_start_rx(struct uart_port *port) { @@ -418,6 +428,7 @@ static void imx_uart_start_rx(struct uar /* Write UCR2 first as it includes RXEN */ imx_uart_writel(sport, ucr2, UCR2); imx_uart_writel(sport, ucr1, UCR1); + imx_uart_disable_loopback_rs485(sport); }
/* called with port.lock taken and irqs off */ @@ -1394,7 +1405,7 @@ static int imx_uart_startup(struct uart_ int retval, i; unsigned long flags; int dma_is_inited = 0; - u32 ucr1, ucr2, ucr3, ucr4, uts; + u32 ucr1, ucr2, ucr3, ucr4;
retval = clk_prepare_enable(sport->clk_per); if (retval) @@ -1499,10 +1510,7 @@ static int imx_uart_startup(struct uart_ imx_uart_writel(sport, ucr2, UCR2); }
- /* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */ - uts = imx_uart_readl(sport, imx_uart_uts_reg(sport)); - uts &= ~UTS_LOOP; - imx_uart_writel(sport, uts, imx_uart_uts_reg(sport)); + imx_uart_disable_loopback_rs485(sport);
spin_unlock_irqrestore(&sport->port.lock, flags);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
commit 1995f15590ca222f91193ed11461862b450abfd6 upstream.
svc_create_memory_pool() is only called from stratix10_svc_drv_probe(). Most of resources in the probe are managed, but not this memremap() call.
There is also no memunmap() call in the file.
So switch to devm_memremap() to avoid a resource leak.
Cc: stable@vger.kernel.org Fixes: 7ca5ce896524 ("firmware: add Intel Stratix10 service layer driver") Link: https://lore.kernel.org/all/783e9dfbba34e28505c9efa8bba41f97fd0fa1dc.1686109... Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Dinh Nguyen dinguyen@kernel.org Message-ID: 20230613211521.16366-1-dinguyen@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/firmware/stratix10-svc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -622,7 +622,7 @@ svc_create_memory_pool(struct platform_d end = rounddown(sh_memory->addr + sh_memory->size, PAGE_SIZE); paddr = begin; size = end - begin; - va = memremap(paddr, size, MEMREMAP_WC); + va = devm_memremap(dev, paddr, size, MEMREMAP_WC); if (!va) { dev_err(dev, "fail to remap shared memory\n"); return ERR_PTR(-EINVAL);
From: Ilya Dryomov idryomov@gmail.com
commit a282a2f10539dce2aa619e71e1817570d557fc97 upstream.
ceph_frame_desc::fd_lens is an int array. decode_preamble() thus effectively casts u32 -> int but the checks for segment lengths are written as if on unsigned values. While reading in HELLO or one of the AUTH frames (before authentication is completed), arithmetic in head_onwire_len() can get duped by negative ctrl_len and produce head_len which is less than CEPH_PREAMBLE_LEN but still positive. This would lead to a buffer overrun in prepare_read_control() as the preamble gets copied to the newly allocated buffer of size head_len.
Cc: stable@vger.kernel.org Fixes: cd1a677cad99 ("libceph, ceph: implement msgr2.1 protocol (crc and secure modes)") Reported-by: Thelford Williams thelford@google.com Signed-off-by: Ilya Dryomov idryomov@gmail.com Reviewed-by: Xiubo Li xiubli@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ceph/messenger_v2.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-)
--- a/net/ceph/messenger_v2.c +++ b/net/ceph/messenger_v2.c @@ -391,6 +391,8 @@ static int head_onwire_len(int ctrl_len, int head_len; int rem_len;
+ BUG_ON(ctrl_len < 0 || ctrl_len > CEPH_MSG_MAX_CONTROL_LEN); + if (secure) { head_len = CEPH_PREAMBLE_SECURE_LEN; if (ctrl_len > CEPH_PREAMBLE_INLINE_LEN) { @@ -409,6 +411,10 @@ static int head_onwire_len(int ctrl_len, static int __tail_onwire_len(int front_len, int middle_len, int data_len, bool secure) { + BUG_ON(front_len < 0 || front_len > CEPH_MSG_MAX_FRONT_LEN || + middle_len < 0 || middle_len > CEPH_MSG_MAX_MIDDLE_LEN || + data_len < 0 || data_len > CEPH_MSG_MAX_DATA_LEN); + if (!front_len && !middle_len && !data_len) return 0;
@@ -521,29 +527,34 @@ static int decode_preamble(void *p, stru desc->fd_aligns[i] = ceph_decode_16(&p); }
- /* - * This would fire for FRAME_TAG_WAIT (it has one empty - * segment), but we should never get it as client. - */ - if (!desc->fd_lens[desc->fd_seg_cnt - 1]) { - pr_err("last segment empty\n"); + if (desc->fd_lens[0] < 0 || + desc->fd_lens[0] > CEPH_MSG_MAX_CONTROL_LEN) { + pr_err("bad control segment length %d\n", desc->fd_lens[0]); return -EINVAL; } - - if (desc->fd_lens[0] > CEPH_MSG_MAX_CONTROL_LEN) { - pr_err("control segment too big %d\n", desc->fd_lens[0]); + if (desc->fd_lens[1] < 0 || + desc->fd_lens[1] > CEPH_MSG_MAX_FRONT_LEN) { + pr_err("bad front segment length %d\n", desc->fd_lens[1]); return -EINVAL; } - if (desc->fd_lens[1] > CEPH_MSG_MAX_FRONT_LEN) { - pr_err("front segment too big %d\n", desc->fd_lens[1]); + if (desc->fd_lens[2] < 0 || + desc->fd_lens[2] > CEPH_MSG_MAX_MIDDLE_LEN) { + pr_err("bad middle segment length %d\n", desc->fd_lens[2]); return -EINVAL; } - if (desc->fd_lens[2] > CEPH_MSG_MAX_MIDDLE_LEN) { - pr_err("middle segment too big %d\n", desc->fd_lens[2]); + if (desc->fd_lens[3] < 0 || + desc->fd_lens[3] > CEPH_MSG_MAX_DATA_LEN) { + pr_err("bad data segment length %d\n", desc->fd_lens[3]); return -EINVAL; } - if (desc->fd_lens[3] > CEPH_MSG_MAX_DATA_LEN) { - pr_err("data segment too big %d\n", desc->fd_lens[3]); + + /* + * This would fire for FRAME_TAG_WAIT (it has one empty + * segment), but we should never get it as client. + */ + if (!desc->fd_lens[desc->fd_seg_cnt - 1]) { + pr_err("last segment empty, segment count %d\n", + desc->fd_seg_cnt); return -EINVAL; }
From: Xiubo Li xiubli@redhat.com
commit 257e6172ab36ebbe295a6c9ee9a9dd0fe54c1dc2 upstream.
If a client sends out a cap update dropping caps with the prior 'seq' just before an incoming cap revoke request, then the client may drop the revoke because it believes it's already released the requested capabilities.
This causes the MDS to wait indefinitely for the client to respond to the revoke. It's therefore always a good idea to ack the cap revoke request with the bumped up 'seq'.
Cc: stable@vger.kernel.org Link: https://tracker.ceph.com/issues/61782 Signed-off-by: Xiubo Li xiubli@redhat.com Reviewed-by: Milind Changire mchangir@redhat.com Reviewed-by: Patrick Donnelly pdonnell@redhat.com Signed-off-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ceph/caps.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -3517,6 +3517,15 @@ static void handle_cap_grant(struct inod } BUG_ON(cap->issued & ~cap->implemented);
+ /* don't let check_caps skip sending a response to MDS for revoke msgs */ + if (le32_to_cpu(grant->op) == CEPH_CAP_OP_REVOKE) { + cap->mds_wanted = 0; + if (cap == ci->i_auth_cap) + check_caps = 1; /* check auth cap only */ + else + check_caps = 2; /* check all caps */ + } + if (extra_info->inline_version > 0 && extra_info->inline_version >= ci->i_inline_version) { ci->i_inline_version = extra_info->inline_version;
From: Weitao Wang WeitaoWang-oc@zhaoxin.com
commit f927728186f0de1167262d6a632f9f7e96433d1a upstream.
On ZHAOXIN ZX-100 project, xHCI can't work normally after resume from system Sx state. To fix this issue, when resume from system Sx state, reinitialize xHCI instead of restore. So, Add XHCI_RESET_ON_RESUME quirk for ZX-100 to fix issue of resuming from system Sx state.
Cc: stable@vger.kernel.org Signed-off-by: Weitao Wang WeitaoWang-oc@zhaoxin.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Message-ID: 20230602144009.1225632-9-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/xhci-pci.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -336,6 +336,11 @@ static void xhci_pci_quirks(struct devic pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4)) xhci->quirks |= XHCI_NO_SOFT_RETRY;
+ if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { + if (pdev->device == 0x9202) + xhci->quirks |= XHCI_RESET_ON_RESUME; + } + /* xHC spec requires PCI devices to support D3hot and D3cold */ if (xhci->hci_version >= 0x120) xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
From: Weitao Wang WeitaoWang-oc@zhaoxin.com
commit 2a865a652299f5666f3b785cbe758c5f57453036 upstream.
On some ZHAOXIN hosts, xHCI will prefetch TRB for performance improvement. However this TRB prefetch mechanism may cross page boundary, which may access memory not allocated by xHCI driver. In order to fix this issue, two pages was allocated for a segment and only the first page will be used. And add a quirk XHCI_ZHAOXIN_TRB_FETCH for this issue.
Cc: stable@vger.kernel.org Signed-off-by: Weitao Wang WeitaoWang-oc@zhaoxin.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Message-ID: 20230602144009.1225632-10-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/xhci-mem.c | 8 ++++++-- drivers/usb/host/xhci-pci.c | 7 ++++++- drivers/usb/host/xhci.h | 1 + 3 files changed, 13 insertions(+), 3 deletions(-)
--- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2454,8 +2454,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, * and our use of dma addresses in the trb_address_map radix tree needs * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need. */ - xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, - TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size); + if (xhci->quirks & XHCI_ZHAOXIN_TRB_FETCH) + xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, + TRB_SEGMENT_SIZE * 2, TRB_SEGMENT_SIZE * 2, xhci->page_size * 2); + else + xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, + TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size);
/* See Table 46 and Note on Figure 55 */ xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -337,8 +337,13 @@ static void xhci_pci_quirks(struct devic xhci->quirks |= XHCI_NO_SOFT_RETRY;
if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { - if (pdev->device == 0x9202) + if (pdev->device == 0x9202) { xhci->quirks |= XHCI_RESET_ON_RESUME; + xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH; + } + + if (pdev->device == 0x9203) + xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH; }
/* xHC spec requires PCI devices to support D3hot and D3cold */ --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1906,6 +1906,7 @@ struct xhci_hcd { #define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42) #define XHCI_SUSPEND_RESUME_CLKS BIT_ULL(43) #define XHCI_RESET_TO_DEFAULT BIT_ULL(44) +#define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)
unsigned int num_active_eps; unsigned int limit_active_eps;
From: Weitao Wang WeitaoWang-oc@zhaoxin.com
commit d9b0328d0b8b8298dfdc97cd8e0e2371d4bcc97b upstream.
Some ZHAOXIN xHCI controllers follow usb3.1 spec, but only support gen1 speed 5Gbps. While in Linux kernel, if xHCI suspport usb3.1, root hub speed will show on 10Gbps. To fix this issue of ZHAOXIN xHCI platforms, read usb speed ID supported by xHCI to determine root hub speed. And add a quirk XHCI_ZHAOXIN_HOST for this issue.
[fix warning about uninitialized symbol -Mathias]
Suggested-by: Mathias Nyman mathias.nyman@linux.intel.com Cc: stable@vger.kernel.org Signed-off-by: Weitao Wang WeitaoWang-oc@zhaoxin.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Message-ID: 20230602144009.1225632-11-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/xhci-mem.c | 31 ++++++++++++++++++++++++------- drivers/usb/host/xhci-pci.c | 2 ++ drivers/usb/host/xhci.h | 1 + 3 files changed, 27 insertions(+), 7 deletions(-)
--- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2128,7 +2128,7 @@ static void xhci_add_in_port(struct xhci { u32 temp, port_offset, port_count; int i; - u8 major_revision, minor_revision; + u8 major_revision, minor_revision, tmp_minor_revision; struct xhci_hub *rhub; struct device *dev = xhci_to_hcd(xhci)->self.sysdev; struct xhci_port_cap *port_cap; @@ -2148,6 +2148,15 @@ static void xhci_add_in_port(struct xhci */ if (minor_revision > 0x00 && minor_revision < 0x10) minor_revision <<= 4; + /* + * Some zhaoxin's xHCI controller that follow usb3.1 spec + * but only support Gen1. + */ + if (xhci->quirks & XHCI_ZHAOXIN_HOST) { + tmp_minor_revision = minor_revision; + minor_revision = 0; + } + } else if (major_revision <= 0x02) { rhub = &xhci->usb2_rhub; } else { @@ -2157,10 +2166,6 @@ static void xhci_add_in_port(struct xhci /* Ignoring port protocol we can't understand. FIXME */ return; } - rhub->maj_rev = XHCI_EXT_PORT_MAJOR(temp); - - if (rhub->min_rev < minor_revision) - rhub->min_rev = minor_revision;
/* Port offset and count in the third dword, see section 7.2 */ temp = readl(addr + 2); @@ -2179,8 +2184,6 @@ static void xhci_add_in_port(struct xhci if (xhci->num_port_caps > max_caps) return;
- port_cap->maj_rev = major_revision; - port_cap->min_rev = minor_revision; port_cap->psi_count = XHCI_EXT_PORT_PSIC(temp);
if (port_cap->psi_count) { @@ -2201,6 +2204,11 @@ static void xhci_add_in_port(struct xhci XHCI_EXT_PORT_PSIV(port_cap->psi[i - 1]))) port_cap->psi_uid_count++;
+ if (xhci->quirks & XHCI_ZHAOXIN_HOST && + major_revision == 0x03 && + XHCI_EXT_PORT_PSIV(port_cap->psi[i]) >= 5) + minor_revision = tmp_minor_revision; + xhci_dbg(xhci, "PSIV:%d PSIE:%d PLT:%d PFD:%d LP:%d PSIM:%d\n", XHCI_EXT_PORT_PSIV(port_cap->psi[i]), XHCI_EXT_PORT_PSIE(port_cap->psi[i]), @@ -2210,6 +2218,15 @@ static void xhci_add_in_port(struct xhci XHCI_EXT_PORT_PSIM(port_cap->psi[i])); } } + + rhub->maj_rev = major_revision; + + if (rhub->min_rev < minor_revision) + rhub->min_rev = minor_revision; + + port_cap->maj_rev = major_revision; + port_cap->min_rev = minor_revision; + /* cache usb2 port capabilities */ if (major_revision < 0x03 && xhci->num_ext_caps < max_caps) xhci->ext_caps[xhci->num_ext_caps++] = temp; --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -337,6 +337,8 @@ static void xhci_pci_quirks(struct devic xhci->quirks |= XHCI_NO_SOFT_RETRY;
if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { + xhci->quirks |= XHCI_ZHAOXIN_HOST; + if (pdev->device == 0x9202) { xhci->quirks |= XHCI_RESET_ON_RESUME; xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH; --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1907,6 +1907,7 @@ struct xhci_hcd { #define XHCI_SUSPEND_RESUME_CLKS BIT_ULL(43) #define XHCI_RESET_TO_DEFAULT BIT_ULL(44) #define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45) +#define XHCI_ZHAOXIN_HOST BIT_ULL(46)
unsigned int num_active_eps; unsigned int limit_active_eps;
From: George Stark gnstark@sberdevices.ru
commit c57fa0037024c92c2ca34243e79e857da5d2c0a9 upstream.
According to the datasheets of supported meson SoCs length of ADC_CLK_DIV field is 6-bit. Although all supported SoCs have the register with that field documented later SoCs use external clock rather than ADC internal clock so this patch affects only meson8 family (S8* SoCs).
Fixes: 3adbf3427330 ("iio: adc: add a driver for the SAR ADC found in Amlogic Meson SoCs") Signed-off-by: George Stark GNStark@sberdevices.ru Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Link: https://lore.kernel.org/r/20230606165357.42417-1-gnstark@sberdevices.ru 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/meson_saradc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -71,7 +71,7 @@ #define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK GENMASK(20, 18) #define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK GENMASK(17, 16) #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT 10 - #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 5 + #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 6 #define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK GENMASK(9, 8) #define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK GENMASK(7, 0)
From: Stephan Gerhold stephan.gerhold@kernkonzept.com
commit b2a2ab039bd58f51355e33d7d3fc64605d7f870d upstream.
When dev_pm_opp_of_find_icc_paths() in _allocate_opp_table() returns -EPROBE_DEFER, the opp_table is freed again, to wait until all the interconnect paths are available.
However, if the OPP table is using required-opps then it may already have been added to the global lazy_opp_tables list. The error path does not remove the opp_table from the list again.
This can cause crashes later when the provider of the required-opps is added, since we will iterate over OPP tables that have already been freed. E.g.:
Unable to handle kernel NULL pointer dereference when read CPU: 0 PID: 7 Comm: kworker/0:0 Not tainted 6.4.0-rc3 PC is at _of_add_opp_table_v2 (include/linux/of.h:949 drivers/opp/of.c:98 drivers/opp/of.c:344 drivers/opp/of.c:404 drivers/opp/of.c:1032) -> lazy_link_required_opp_table()
Fix this by calling _of_clear_opp_table() to remove the opp_table from the list and clear other allocated resources. While at it, also add the missing mutex_destroy() calls in the error path.
Cc: stable@vger.kernel.org Suggested-by: Viresh Kumar viresh.kumar@linaro.org Fixes: 7eba0c7641b0 ("opp: Allow lazy-linking of required-opps") Signed-off-by: Stephan Gerhold stephan.gerhold@kernkonzept.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/opp/core.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1249,7 +1249,10 @@ static struct opp_table *_allocate_opp_t return opp_table;
remove_opp_dev: + _of_clear_opp_table(opp_table); _remove_opp_dev(opp_dev, opp_table); + mutex_destroy(&opp_table->genpd_virt_dev_lock); + mutex_destroy(&opp_table->lock); err: kfree(opp_table); return ERR_PTR(ret);
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
commit 490937d479abe5f6584e69b96df066bc87be92e9 upstream.
The 'qcom_swrm_ctrl->pconfig' has size of QCOM_SDW_MAX_PORTS (14), however we index it starting from 1, not 0, to match real port numbers. This can lead to writing port config past 'pconfig' bounds and overwriting next member of 'qcom_swrm_ctrl' struct. Reported also by smatch:
drivers/soundwire/qcom.c:1269 qcom_swrm_get_port_config() error: buffer overflow 'ctrl->pconfig' 14 <= 14
Fixes: 9916c02ccd74 ("soundwire: qcom: cleanup internal port config indexing") Cc: stable@vger.kernel.org Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter error27@gmail.com Link: https://lore.kernel.org/r/202305201301.sCJ8UDKV-lkp@intel.com/ Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@linaro.org Link: https://lore.kernel.org/r/20230601102525.609627-1-krzysztof.kozlowski@linaro... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/soundwire/qcom.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -146,7 +146,8 @@ struct qcom_swrm_ctrl { u32 intr_mask; u8 rcmd_id; u8 wcmd_id; - struct qcom_swrm_port_config pconfig[QCOM_SDW_MAX_PORTS]; + /* Port numbers are 1 - 14 */ + struct qcom_swrm_port_config pconfig[QCOM_SDW_MAX_PORTS + 1]; struct sdw_stream_runtime *sruntime[SWRM_MAX_DAIS]; enum sdw_slave_status status[SDW_MAX_DEVICES + 1]; int (*reg_read)(struct qcom_swrm_ctrl *ctrl, int reg, u32 *val);
From: Jiaqing Zhao jiaqing.zhao@linux.intel.com
commit a82d62f708545d22859584e0e0620da8e3759bbc upstream.
This reverts commit eb26dfe8aa7eeb5a5aa0b7574550125f8aa4c3b3.
Commit eb26dfe8aa7e ("8250: add support for ASIX devices with a FIFO bug") merged on Jul 13, 2012 adds a quirk for PCI_VENDOR_ID_ASIX (0x9710). But that ID is the same as PCI_VENDOR_ID_NETMOS defined in 1f8b061050c7 ("[PATCH] Netmos parallel/serial/combo support") merged on Mar 28, 2005. In pci_serial_quirks array, the NetMos entry always takes precedence over the ASIX entry even since it was initially merged, code in that commit is always unreachable.
In my tests, adding the FIFO workaround to pci_netmos_init() makes no difference, and the vendor driver also does not have such workaround. Given that the code was never used for over a decade, it's safe to revert it.
Also, the real PCI_VENDOR_ID_ASIX should be 0x125b, which is used on their newer AX99100 PCIe serial controllers released on 2016. The FIFO workaround should not be intended for these newer controllers, and it was never implemented in vendor driver.
Fixes: eb26dfe8aa7e ("8250: add support for ASIX devices with a FIFO bug") Cc: stable stable@kernel.org Signed-off-by: Jiaqing Zhao jiaqing.zhao@linux.intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20230619155743.827859-1-jiaqing.zhao@linux.intel.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/8250/8250.h | 1 - drivers/tty/serial/8250/8250_pci.c | 19 ------------------- drivers/tty/serial/8250/8250_port.c | 11 +++-------- include/linux/serial_8250.h | 1 - 4 files changed, 3 insertions(+), 29 deletions(-)
--- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -90,7 +90,6 @@ struct serial8250_config { #define UART_BUG_TXEN BIT(1) /* UART has buggy TX IIR status */ #define UART_BUG_NOMSR BIT(2) /* UART has buggy MSR status bits (Au1x00) */ #define UART_BUG_THRE BIT(3) /* UART has buggy THRE reassertion */ -#define UART_BUG_PARITY BIT(4) /* UART mishandles parity if FIFO enabled */ #define UART_BUG_TXRACE BIT(5) /* UART Tx fails to set remote DR */
--- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1252,14 +1252,6 @@ static int pci_oxsemi_tornado_setup(stru return pci_default_setup(priv, board, up, idx); }
-static int pci_asix_setup(struct serial_private *priv, - const struct pciserial_board *board, - struct uart_8250_port *port, int idx) -{ - port->bugs |= UART_BUG_PARITY; - return pci_default_setup(priv, board, port, idx); -} - /* Quatech devices have their own extra interface features */
struct quatech_feature { @@ -2082,7 +2074,6 @@ pci_moxa_setup(struct serial_private *pr #define PCI_DEVICE_ID_WCH_CH355_4S 0x7173 #define PCI_VENDOR_ID_AGESTAR 0x5372 #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 -#define PCI_VENDOR_ID_ASIX 0x9710 #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a #define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e
@@ -2893,16 +2884,6 @@ static struct pci_serial_quirk pci_seria .setup = pci_wch_ch38x_setup, }, /* - * ASIX devices with FIFO bug - */ - { - .vendor = PCI_VENDOR_ID_ASIX, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .setup = pci_asix_setup, - }, - /* * Broadcom TruManage (NetXtreme) */ { --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2620,11 +2620,8 @@ static unsigned char serial8250_compute_
if (c_cflag & CSTOPB) cval |= UART_LCR_STOP; - if (c_cflag & PARENB) { + if (c_cflag & PARENB) cval |= UART_LCR_PARITY; - if (up->bugs & UART_BUG_PARITY) - up->fifo_bug = true; - } if (!(c_cflag & PARODD)) cval |= UART_LCR_EPAR; #ifdef CMSPAR @@ -2787,8 +2784,7 @@ serial8250_do_set_termios(struct uart_po up->lcr = cval; /* Save computed LCR */
if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { - /* NOTE: If fifo_bug is not set, a user can set RX_trigger. */ - if ((baud < 2400 && !up->dma) || up->fifo_bug) { + if (baud < 2400 && !up->dma) { up->fcr &= ~UART_FCR_TRIGGER_MASK; up->fcr |= UART_FCR_TRIGGER_1; } @@ -3124,8 +3120,7 @@ static int do_set_rxtrig(struct tty_port struct uart_8250_port *up = up_to_u8250p(uport); int rxtrig;
- if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1 || - up->fifo_bug) + if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1) return -EINVAL;
rxtrig = bytes_to_fcr_rxtrig(up, bytes); --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -98,7 +98,6 @@ struct uart_8250_port { struct list_head list; /* ports on this IRQ */ u32 capabilities; /* port capabilities */ unsigned short bugs; /* port bugs */ - bool fifo_bug; /* min RX trigger if enabled */ unsigned int tx_loadsz; /* transmit fifo load size */ unsigned char acr; unsigned char fcr;
From: Jonas Gorski jonas.gorski@gmail.com
commit 6722e46513e0af8e2fff4698f7cb78bc50a9f13f upstream.
The IXP4XX_EXP_T1_MASK was shifted one bit to the right, overlapping IXP4XX_EXP_T2_MASK and leaving bit 29 unused. The offset being wrong is also confirmed at least by the datasheet of IXP45X/46X [1].
Fix this by aligning it to IXP4XX_EXP_T1_SHIFT.
[1] https://www.intel.com/content/dam/www/public/us/en/documents/manuals/ixp45x-...
Cc: stable@vger.kernel.org Fixes: 1c953bda90ca ("bus: ixp4xx: Add a driver for IXP4xx expansion bus") Signed-off-by: Jonas Gorski jonas.gorski@gmail.com Link: https://lore.kernel.org/r/20230624112958.27727-1-jonas.gorski@gmail.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Link: https://lore.kernel.org/r/20230624122139.3229642-1-linus.walleij@linaro.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/bus/intel-ixp4xx-eb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bus/intel-ixp4xx-eb.c b/drivers/bus/intel-ixp4xx-eb.c index f5ba6bee6fd8..320cf307db05 100644 --- a/drivers/bus/intel-ixp4xx-eb.c +++ b/drivers/bus/intel-ixp4xx-eb.c @@ -33,7 +33,7 @@ #define IXP4XX_EXP_TIMING_STRIDE 0x04 #define IXP4XX_EXP_CS_EN BIT(31) #define IXP456_EXP_PAR_EN BIT(30) /* Only on IXP45x and IXP46x */ -#define IXP4XX_EXP_T1_MASK GENMASK(28, 27) +#define IXP4XX_EXP_T1_MASK GENMASK(29, 28) #define IXP4XX_EXP_T1_SHIFT 28 #define IXP4XX_EXP_T2_MASK GENMASK(27, 26) #define IXP4XX_EXP_T2_SHIFT 26
From: Heiko Carstens hca@linux.ibm.com
commit 938f0c35d7d93a822ab9c9728e3205e8e57409d0 upstream.
Nathan Chancellor reported a kernel build error on Fedora 39:
$ clang --version | head -1 clang version 16.0.5 (Fedora 16.0.5-1.fc39)
$ s390x-linux-gnu-ld --version | head -1 GNU ld version 2.40-1.fc39
$ make -skj"$(nproc)" ARCH=s390 CC=clang CROSS_COMPILE=s390x-linux-gnu- olddefconfig all s390x-linux-gnu-ld: arch/s390/boot/startup.o(.text+0x5b4): misaligned symbol `_decompressor_end' (0x35b0f) for relocation R_390_PC32DBL make[3]: *** [.../arch/s390/boot/Makefile:78: arch/s390/boot/vmlinux] Error 1
It turned out that the problem with misaligned symbols on s390 was fixed with commit 80ddf5ce1c92 ("s390: always build relocatable kernel") for the kernel image, but did not take into account that the decompressor uses its own set of CFLAGS, which come without -fPIE.
Add the -fPIE flag also to the decompresser CFLAGS to fix this.
Reported-by: Nathan Chancellor nathan@kernel.org Tested-by: Nathan Chancellor nathan@kernel.org Reported-by: CKI cki-project@redhat.com Suggested-by: Ulrich Weigand Ulrich.Weigand@de.ibm.com Link: https://github.com/ClangBuiltLinux/linux/issues/1747 Link: https://lore.kernel.org/32935.123062114500601371@us-mta-9.us.mimecast.lan/ Link: https://lore.kernel.org/r/20230622125508.1068457-1-hca@linux.ibm.com Cc: stable@vger.kernel.org Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Alexander Gordeev agordeev@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/Makefile | 1 + 1 file changed, 1 insertion(+)
--- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -29,6 +29,7 @@ KBUILD_CFLAGS_DECOMPRESSOR += -fno-delet KBUILD_CFLAGS_DECOMPRESSOR += -fno-asynchronous-unwind-tables KBUILD_CFLAGS_DECOMPRESSOR += -ffreestanding KBUILD_CFLAGS_DECOMPRESSOR += -fno-stack-protector +KBUILD_CFLAGS_DECOMPRESSOR += -fPIE KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g) KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,))
From: Mohamed Khalfella mkhalfella@purestorage.com
commit 6018b585e8c6fa7d85d4b38d9ce49a5b67be7078 upstream.
Hist triggers can have referenced variables without having direct variables fields. This can be the case if referenced variables are added for trigger actions. In this case the newly added references will not have field variables. Not taking such referenced variables into consideration can result in a bug where it would be possible to remove hist trigger with variables being refenced. This will result in a bug that is easily reproducable like so
$ cd /sys/kernel/tracing $ echo 'synthetic_sys_enter char[] comm; long id' >> synthetic_events $ echo 'hist:keys=common_pid.execname,id.syscall:vals=hitcount:comm=common_pid.execname' >> events/raw_syscalls/sys_enter/trigger $ echo 'hist:keys=common_pid.execname,id.syscall:onmatch(raw_syscalls.sys_enter).synthetic_sys_enter($comm, id)' >> events/raw_syscalls/sys_enter/trigger $ echo '!hist:keys=common_pid.execname,id.syscall:vals=hitcount:comm=common_pid.execname' >> events/raw_syscalls/sys_enter/trigger
[ 100.263533] ================================================================== [ 100.264634] BUG: KASAN: slab-use-after-free in resolve_var_refs+0xc7/0x180 [ 100.265520] Read of size 8 at addr ffff88810375d0f0 by task bash/439 [ 100.266320] [ 100.266533] CPU: 2 PID: 439 Comm: bash Not tainted 6.5.0-rc1 #4 [ 100.267277] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-20220807_005459-localhost 04/01/2014 [ 100.268561] Call Trace: [ 100.268902] <TASK> [ 100.269189] dump_stack_lvl+0x4c/0x70 [ 100.269680] print_report+0xc5/0x600 [ 100.270165] ? resolve_var_refs+0xc7/0x180 [ 100.270697] ? kasan_complete_mode_report_info+0x80/0x1f0 [ 100.271389] ? resolve_var_refs+0xc7/0x180 [ 100.271913] kasan_report+0xbd/0x100 [ 100.272380] ? resolve_var_refs+0xc7/0x180 [ 100.272920] __asan_load8+0x71/0xa0 [ 100.273377] resolve_var_refs+0xc7/0x180 [ 100.273888] event_hist_trigger+0x749/0x860 [ 100.274505] ? kasan_save_stack+0x2a/0x50 [ 100.275024] ? kasan_set_track+0x29/0x40 [ 100.275536] ? __pfx_event_hist_trigger+0x10/0x10 [ 100.276138] ? ksys_write+0xd1/0x170 [ 100.276607] ? do_syscall_64+0x3c/0x90 [ 100.277099] ? entry_SYSCALL_64_after_hwframe+0x6e/0xd8 [ 100.277771] ? destroy_hist_data+0x446/0x470 [ 100.278324] ? event_hist_trigger_parse+0xa6c/0x3860 [ 100.278962] ? __pfx_event_hist_trigger_parse+0x10/0x10 [ 100.279627] ? __kasan_check_write+0x18/0x20 [ 100.280177] ? mutex_unlock+0x85/0xd0 [ 100.280660] ? __pfx_mutex_unlock+0x10/0x10 [ 100.281200] ? kfree+0x7b/0x120 [ 100.281619] ? ____kasan_slab_free+0x15d/0x1d0 [ 100.282197] ? event_trigger_write+0xac/0x100 [ 100.282764] ? __kasan_slab_free+0x16/0x20 [ 100.283293] ? __kmem_cache_free+0x153/0x2f0 [ 100.283844] ? sched_mm_cid_remote_clear+0xb1/0x250 [ 100.284550] ? __pfx_sched_mm_cid_remote_clear+0x10/0x10 [ 100.285221] ? event_trigger_write+0xbc/0x100 [ 100.285781] ? __kasan_check_read+0x15/0x20 [ 100.286321] ? __bitmap_weight+0x66/0xa0 [ 100.286833] ? _find_next_bit+0x46/0xe0 [ 100.287334] ? task_mm_cid_work+0x37f/0x450 [ 100.287872] event_triggers_call+0x84/0x150 [ 100.288408] trace_event_buffer_commit+0x339/0x430 [ 100.289073] ? ring_buffer_event_data+0x3f/0x60 [ 100.292189] trace_event_raw_event_sys_enter+0x8b/0xe0 [ 100.295434] syscall_trace_enter.constprop.0+0x18f/0x1b0 [ 100.298653] syscall_enter_from_user_mode+0x32/0x40 [ 100.301808] do_syscall_64+0x1a/0x90 [ 100.304748] entry_SYSCALL_64_after_hwframe+0x6e/0xd8 [ 100.307775] RIP: 0033:0x7f686c75c1cb [ 100.310617] Code: 73 01 c3 48 8b 0d 65 3c 10 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 21 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 35 3c 10 00 f7 d8 64 89 01 48 [ 100.317847] RSP: 002b:00007ffc60137a38 EFLAGS: 00000246 ORIG_RAX: 0000000000000021 [ 100.321200] RAX: ffffffffffffffda RBX: 000055f566469ea0 RCX: 00007f686c75c1cb [ 100.324631] RDX: 0000000000000001 RSI: 0000000000000001 RDI: 000000000000000a [ 100.328104] RBP: 00007ffc60137ac0 R08: 00007f686c818460 R09: 000000000000000a [ 100.331509] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000009 [ 100.334992] R13: 0000000000000007 R14: 000000000000000a R15: 0000000000000007 [ 100.338381] </TASK>
We hit the bug because when second hist trigger has was created has_hist_vars() returned false because hist trigger did not have variables. As a result of that save_hist_vars() was not called to add the trigger to trace_array->hist_vars. Later on when we attempted to remove the first histogram find_any_var_ref() failed to detect it is being used because it did not find the second trigger in hist_vars list.
With this change we wait until trigger actions are created so we can take into consideration if hist trigger has variable references. Also, now we check the return value of save_hist_vars() and fail trigger creation if save_hist_vars() fails.
Link: https://lore.kernel.org/linux-trace-kernel/20230712223021.636335-1-mkhalfell...
Cc: stable@vger.kernel.org Fixes: 067fe038e70f6 ("tracing: Add variable reference handling to hist triggers") Signed-off-by: Mohamed Khalfella mkhalfella@purestorage.com Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace_events_hist.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -5944,13 +5944,15 @@ static int event_hist_trigger_func(struc if (get_named_trigger_data(trigger_data)) goto enable;
- if (has_hist_vars(hist_data)) - save_hist_vars(hist_data); - ret = create_actions(hist_data); if (ret) goto out_unreg;
+ if (has_hist_vars(hist_data) || hist_data->n_var_refs) { + if (save_hist_vars(hist_data)) + goto out_unreg; + } + ret = tracing_map_init(hist_data->map); if (ret) goto out_unreg;
From: Zheng Yejian zhengyejian1@huawei.com
commit d5a821896360cc8b93a15bd888fabc858c038dc0 upstream.
kmemleak reports: unreferenced object 0xffff88814d14e200 (size 256): comm "cat", pid 336, jiffies 4294871818 (age 779.490s) hex dump (first 32 bytes): 04 00 01 03 00 00 00 00 08 00 00 00 00 00 00 00 ................ 0c d8 c8 9b ff ff ff ff 04 5a ca 9b ff ff ff ff .........Z...... backtrace: [<ffffffff9bdff18f>] __kmalloc+0x4f/0x140 [<ffffffff9bc9238b>] trace_find_next_entry+0xbb/0x1d0 [<ffffffff9bc9caef>] trace_print_lat_context+0xaf/0x4e0 [<ffffffff9bc94490>] print_trace_line+0x3e0/0x950 [<ffffffff9bc95499>] tracing_read_pipe+0x2d9/0x5a0 [<ffffffff9bf03a43>] vfs_read+0x143/0x520 [<ffffffff9bf04c2d>] ksys_read+0xbd/0x160 [<ffffffff9d0f0edf>] do_syscall_64+0x3f/0x90 [<ffffffff9d2000aa>] entry_SYSCALL_64_after_hwframe+0x6e/0xd8
when reading file 'trace_pipe', 'iter->temp' is allocated or relocated in trace_find_next_entry() but not freed before 'trace_pipe' is closed.
To fix it, free 'iter->temp' in tracing_release_pipe().
Link: https://lore.kernel.org/linux-trace-kernel/20230713141435.1133021-1-zhengyej...
Cc: stable@vger.kernel.org Fixes: ff895103a84ab ("tracing: Save off entry when peeking at next entry") Signed-off-by: Zheng Yejian zhengyejian1@huawei.com Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace.c | 1 + 1 file changed, 1 insertion(+)
--- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6650,6 +6650,7 @@ static int tracing_release_pipe(struct i
free_cpumask_var(iter->started); kfree(iter->fmt); + kfree(iter->temp); mutex_destroy(&iter->mutex); kfree(iter);
From: Florent Revest revest@chromium.org
commit 8564c315876ab86fcaf8e7f558d6a84cb2ce5590 upstream.
The ftrace-direct-too sample traces the handle_mm_fault function whose signature changed since the introduction of the sample. Since: commit bce617edecad ("mm: do page fault accounting in handle_mm_fault") handle_mm_fault now has 4 arguments. Therefore, the sample trampoline should save 4 argument registers.
s390 saves all argument registers already so it does not need a change but x86_64 needs an extra push and pop.
This also evolves the signature of the tracing function to make it mirror the signature of the traced function.
Link: https://lkml.kernel.org/r/20230427140700.625241-2-revest@chromium.org
Cc: stable@vger.kernel.org Fixes: bce617edecad ("mm: do page fault accounting in handle_mm_fault") Reviewed-by: Steven Rostedt (Google) rostedt@goodmis.org Reviewed-by: Mark Rutland mark.rutland@arm.com Acked-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Florent Revest revest@chromium.org Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- samples/ftrace/ftrace-direct-too.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
--- a/samples/ftrace/ftrace-direct-too.c +++ b/samples/ftrace/ftrace-direct-too.c @@ -4,14 +4,14 @@ #include <linux/mm.h> /* for handle_mm_fault() */ #include <linux/ftrace.h>
-extern void my_direct_func(struct vm_area_struct *vma, - unsigned long address, unsigned int flags); +extern void my_direct_func(struct vm_area_struct *vma, unsigned long address, + unsigned int flags, struct pt_regs *regs);
-void my_direct_func(struct vm_area_struct *vma, - unsigned long address, unsigned int flags) +void my_direct_func(struct vm_area_struct *vma, unsigned long address, + unsigned int flags, struct pt_regs *regs) { - trace_printk("handle mm fault vma=%p address=%lx flags=%x\n", - vma, address, flags); + trace_printk("handle mm fault vma=%p address=%lx flags=%x regs=%p\n", + vma, address, flags, regs); }
extern void my_tramp(void *); @@ -26,7 +26,9 @@ asm ( " pushq %rdi\n" " pushq %rsi\n" " pushq %rdx\n" +" pushq %rcx\n" " call my_direct_func\n" +" popq %rcx\n" " popq %rdx\n" " popq %rsi\n" " popq %rdi\n"
From: Krister Johansen kjlx@templeofstupid.com
commit 1e9cb763e9bacf0c932aa948f50dcfca6f519a26 upstream.
The ENA adapters on our instances occasionally reset. Once recently logged a UBSAN failure to console in the process:
UBSAN: shift-out-of-bounds in build/linux/drivers/net/ethernet/amazon/ena/ena_com.c:540:13 shift exponent 32 is too large for 32-bit type 'unsigned int' CPU: 28 PID: 70012 Comm: kworker/u72:2 Kdump: loaded not tainted 5.15.117 Hardware name: Amazon EC2 c5d.9xlarge/, BIOS 1.0 10/16/2017 Workqueue: ena ena_fw_reset_device [ena] Call Trace: <TASK> dump_stack_lvl+0x4a/0x63 dump_stack+0x10/0x16 ubsan_epilogue+0x9/0x36 __ubsan_handle_shift_out_of_bounds.cold+0x61/0x10e ? __const_udelay+0x43/0x50 ena_delay_exponential_backoff_us.cold+0x16/0x1e [ena] wait_for_reset_state+0x54/0xa0 [ena] ena_com_dev_reset+0xc8/0x110 [ena] ena_down+0x3fe/0x480 [ena] ena_destroy_device+0xeb/0xf0 [ena] ena_fw_reset_device+0x30/0x50 [ena] process_one_work+0x22b/0x3d0 worker_thread+0x4d/0x3f0 ? process_one_work+0x3d0/0x3d0 kthread+0x12a/0x150 ? set_kthread_struct+0x50/0x50 ret_from_fork+0x22/0x30 </TASK>
Apparently, the reset delays are getting so large they can trigger a UBSAN panic.
Looking at the code, the current timeout is capped at 5000us. Using a base value of 100us, the current code will overflow after (1<<29). Even at values before 32, this function wraps around, perhaps unintentionally.
Cap the value of the exponent used for this backoff at (1<<16) which is larger than currently necessary, but large enough to support bigger values in the future.
Cc: stable@vger.kernel.org Fixes: 4bb7f4cf60e3 ("net: ena: reduce driver load time") Signed-off-by: Krister Johansen kjlx@templeofstupid.com Reviewed-by: Leon Romanovsky leonro@nvidia.com Reviewed-by: Shay Agroskin shayagr@amazon.com Link: https://lore.kernel.org/r/20230711013621.GE1926@templeofstupid.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/amazon/ena/ena_com.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/net/ethernet/amazon/ena/ena_com.c +++ b/drivers/net/ethernet/amazon/ena/ena_com.c @@ -35,6 +35,8 @@
#define ENA_REGS_ADMIN_INTR_MASK 1
+#define ENA_MAX_BACKOFF_DELAY_EXP 16U + #define ENA_MIN_ADMIN_POLL_US 100
#define ENA_MAX_ADMIN_POLL_US 5000 @@ -536,6 +538,7 @@ static int ena_com_comp_status_to_errno(
static void ena_delay_exponential_backoff_us(u32 exp, u32 delay_us) { + exp = min_t(u32, exp, ENA_MAX_BACKOFF_DELAY_EXP); delay_us = max_t(u32, ENA_MIN_ADMIN_POLL_US, delay_us); delay_us = min_t(u32, delay_us * (1U << exp), ENA_MAX_ADMIN_POLL_US); usleep_range(delay_us, 2 * delay_us);
From: Zheng Yejian zhengyejian1@huawei.com
commit 7e42907f3a7b4ce3a2d1757f6d78336984daf8f5 upstream.
Soft lockup occurs when reading file 'trace_pipe':
watchdog: BUG: soft lockup - CPU#6 stuck for 22s! [cat:4488] [...] RIP: 0010:ring_buffer_empty_cpu+0xed/0x170 RSP: 0018:ffff88810dd6fc48 EFLAGS: 00000246 RAX: 0000000000000000 RBX: 0000000000000246 RCX: ffffffff93d1aaeb RDX: ffff88810a280040 RSI: 0000000000000008 RDI: ffff88811164b218 RBP: ffff88811164b218 R08: 0000000000000000 R09: ffff88815156600f R10: ffffed102a2acc01 R11: 0000000000000001 R12: 0000000051651901 R13: 0000000000000000 R14: ffff888115e49500 R15: 0000000000000000 [...] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f8d853c2000 CR3: 000000010dcd8000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: __find_next_entry+0x1a8/0x4b0 ? peek_next_entry+0x250/0x250 ? down_write+0xa5/0x120 ? down_write_killable+0x130/0x130 trace_find_next_entry_inc+0x3b/0x1d0 tracing_read_pipe+0x423/0xae0 ? tracing_splice_read_pipe+0xcb0/0xcb0 vfs_read+0x16b/0x490 ksys_read+0x105/0x210 ? __ia32_sys_pwrite64+0x200/0x200 ? switch_fpu_return+0x108/0x220 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x61/0xc6
Through the vmcore, I found it's because in tracing_read_pipe(), ring_buffer_empty_cpu() found some buffer is not empty but then it cannot read anything due to "rb_num_of_entries() == 0" always true, Then it infinitely loop the procedure due to user buffer not been filled, see following code path:
tracing_read_pipe() { ... ... waitagain: tracing_wait_pipe() // 1. find non-empty buffer here trace_find_next_entry_inc() // 2. loop here try to find an entry __find_next_entry() ring_buffer_empty_cpu(); // 3. find non-empty buffer peek_next_entry() // 4. but peek always return NULL ring_buffer_peek() rb_buffer_peek() rb_get_reader_page() // 5. because rb_num_of_entries() == 0 always true here // then return NULL // 6. user buffer not been filled so goto 'waitgain' // and eventually leads to an deadloop in kernel!!! }
By some analyzing, I found that when resetting ringbuffer, the 'entries' of its pages are not all cleared (see rb_reset_cpu()). Then when reducing the ringbuffer, and if some reduced pages exist dirty 'entries' data, they will be added into 'cpu_buffer->overrun' (see rb_remove_pages()), which cause wrong 'overrun' count and eventually cause the deadloop issue.
To fix it, we need to clear every pages in rb_reset_cpu().
Link: https://lore.kernel.org/linux-trace-kernel/20230708225144.3785600-1-zhengyej...
Cc: stable@vger.kernel.org Fixes: a5fb833172eca ("ring-buffer: Fix uninitialized read_stamp") Signed-off-by: Zheng Yejian zhengyejian1@huawei.com Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ring_buffer.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
--- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -5196,28 +5196,34 @@ unsigned long ring_buffer_size(struct tr } EXPORT_SYMBOL_GPL(ring_buffer_size);
+static void rb_clear_buffer_page(struct buffer_page *page) +{ + local_set(&page->write, 0); + local_set(&page->entries, 0); + rb_init_page(page->page); + page->read = 0; +} + static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) { + struct buffer_page *page; + rb_head_page_deactivate(cpu_buffer);
cpu_buffer->head_page = list_entry(cpu_buffer->pages, struct buffer_page, list); - local_set(&cpu_buffer->head_page->write, 0); - local_set(&cpu_buffer->head_page->entries, 0); - local_set(&cpu_buffer->head_page->page->commit, 0); - - cpu_buffer->head_page->read = 0; + rb_clear_buffer_page(cpu_buffer->head_page); + list_for_each_entry(page, cpu_buffer->pages, list) { + rb_clear_buffer_page(page); + }
cpu_buffer->tail_page = cpu_buffer->head_page; cpu_buffer->commit_page = cpu_buffer->head_page;
INIT_LIST_HEAD(&cpu_buffer->reader_page->list); INIT_LIST_HEAD(&cpu_buffer->new_pages); - local_set(&cpu_buffer->reader_page->write, 0); - local_set(&cpu_buffer->reader_page->entries, 0); - local_set(&cpu_buffer->reader_page->page->commit, 0); - cpu_buffer->reader_page->read = 0; + rb_clear_buffer_page(cpu_buffer->reader_page);
local_set(&cpu_buffer->entries_bytes, 0); local_set(&cpu_buffer->overrun, 0);
From: Zheng Yejian zhengyejian1@huawei.com
commit 26efd79c4624294e553aeaa3439c646729bad084 upstream.
As comments in ftrace_process_locs(), there may be NULL pointers in mcount_loc section:
Some architecture linkers will pad between the different mcount_loc sections of different object files to satisfy alignments. Skip any NULL pointers.
After commit 20e5227e9f55 ("ftrace: allow NULL pointers in mcount_loc"), NULL pointers will be accounted when allocating ftrace pages but skipped before adding into ftrace pages, this may result in some pages not being used. Then after commit 706c81f87f84 ("ftrace: Remove extra helper functions"), warning may occur at: WARN_ON(pg->next);
To fix it, only warn for case that no pointers skipped but pages not used up, then free those unused pages after releasing ftrace_lock.
Link: https://lore.kernel.org/linux-trace-kernel/20230712060452.3175675-1-zhengyej...
Cc: stable@vger.kernel.org Fixes: 706c81f87f84 ("ftrace: Remove extra helper functions") Suggested-by: Steven Rostedt rostedt@goodmis.org Signed-off-by: Zheng Yejian zhengyejian1@huawei.com Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ftrace.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-)
--- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -3192,6 +3192,22 @@ static int ftrace_allocate_records(struc return cnt; }
+static void ftrace_free_pages(struct ftrace_page *pages) +{ + struct ftrace_page *pg = pages; + + while (pg) { + if (pg->records) { + free_pages((unsigned long)pg->records, pg->order); + ftrace_number_of_pages -= 1 << pg->order; + } + pages = pg->next; + kfree(pg); + pg = pages; + ftrace_number_of_groups--; + } +} + static struct ftrace_page * ftrace_allocate_pages(unsigned long num_to_init) { @@ -3230,17 +3246,7 @@ ftrace_allocate_pages(unsigned long num_ return start_pg;
free_pages: - pg = start_pg; - while (pg) { - if (pg->records) { - free_pages((unsigned long)pg->records, pg->order); - ftrace_number_of_pages -= 1 << pg->order; - } - start_pg = pg->next; - kfree(pg); - pg = start_pg; - ftrace_number_of_groups--; - } + ftrace_free_pages(start_pg); pr_info("ftrace: FAILED to allocate memory for functions\n"); return NULL; } @@ -6184,9 +6190,11 @@ static int ftrace_process_locs(struct mo unsigned long *start, unsigned long *end) { + struct ftrace_page *pg_unuse = NULL; struct ftrace_page *start_pg; struct ftrace_page *pg; struct dyn_ftrace *rec; + unsigned long skipped = 0; unsigned long count; unsigned long *p; unsigned long addr; @@ -6240,8 +6248,10 @@ static int ftrace_process_locs(struct mo * object files to satisfy alignments. * Skip any NULL pointers. */ - if (!addr) + if (!addr) { + skipped++; continue; + }
end_offset = (pg->index+1) * sizeof(pg->records[0]); if (end_offset > PAGE_SIZE << pg->order) { @@ -6255,8 +6265,10 @@ static int ftrace_process_locs(struct mo rec->ip = addr; }
- /* We should have used all pages */ - WARN_ON(pg->next); + if (pg->next) { + pg_unuse = pg->next; + pg->next = NULL; + }
/* Assign the last page to ftrace_pages */ ftrace_pages = pg; @@ -6278,6 +6290,11 @@ static int ftrace_process_locs(struct mo out: mutex_unlock(&ftrace_lock);
+ /* We should have used all pages unless we skipped some */ + if (pg_unuse) { + WARN_ON(!skipped); + ftrace_free_pages(pg_unuse); + } return ret; }
From: Max Filippov jcmvbkbc@gmail.com
commit bc8d5916541fa19ca5bc598eb51a5f78eb891a36 upstream.
split_if_spec expects a NULL-pointer as an end marker for the argument list, but tuntap_probe never supplied that terminating NULL. As a result incorrectly formatted interface specification string may cause a crash because of the random memory access. Fix that by adding NULL terminator to the split_if_spec argument list.
Cc: stable@vger.kernel.org Fixes: 7282bee78798 ("[PATCH] xtensa: Architecture support for Tensilica Xtensa Part 8") Signed-off-by: Max Filippov jcmvbkbc@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/xtensa/platforms/iss/network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c @@ -231,7 +231,7 @@ static int tuntap_probe(struct iss_net_p
init += sizeof(TRANSPORT_TUNTAP_NAME) - 1; if (*init == ',') { - rem = split_if_spec(init + 1, &mac_str, &dev_name); + rem = split_if_spec(init + 1, &mac_str, &dev_name, NULL); if (rem != NULL) { pr_err("%s: extra garbage on specification : '%s'\n", dev->name, rem);
From: Mateusz Stachyra m.stachyra@samsung.com
commit 02b0095e2fbbc060560c1065f86a211d91e27b26 upstream.
Fix an issue in function 'tracing_err_log_open'. The function doesn't call 'seq_open' if the file is opened only with write permissions, which results in 'file->private_data' being left as null. If we then use 'lseek' on that opened file, 'seq_lseek' dereferences 'file->private_data' in 'mutex_lock(&m->lock)', resulting in a kernel panic. Writing to this node requires root privileges, therefore this bug has very little security impact.
Tracefs node: /sys/kernel/tracing/error_log
Example Kernel panic:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000038 Call trace: mutex_lock+0x30/0x110 seq_lseek+0x34/0xb8 __arm64_sys_lseek+0x6c/0xb8 invoke_syscall+0x58/0x13c el0_svc_common+0xc4/0x10c do_el0_svc+0x24/0x98 el0_svc+0x24/0x88 el0t_64_sync_handler+0x84/0xe4 el0t_64_sync+0x1b4/0x1b8 Code: d503201f aa0803e0 aa1f03e1 aa0103e9 (c8e97d02) ---[ end trace 561d1b49c12cf8a5 ]--- Kernel panic - not syncing: Oops: Fatal exception
Link: https://lore.kernel.org/linux-trace-kernel/20230703155237eucms1p4dfb6a19caa1... Link: https://lore.kernel.org/linux-trace-kernel/20230704102706eucms1p30d7ecdcc287...
Cc: stable@vger.kernel.org Fixes: 8a062902be725 ("tracing: Add tracing error log") Signed-off-by: Mateusz Stachyra m.stachyra@samsung.com Suggested-by: Steven Rostedt rostedt@goodmis.org Acked-by: Masami Hiramatsu (Google) mhiramat@kernel.org Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8014,7 +8014,7 @@ static const struct file_operations trac .open = tracing_err_log_open, .write = tracing_err_log_write, .read = seq_read, - .llseek = seq_lseek, + .llseek = tracing_lseek, .release = tracing_err_log_release, };
From: Matthieu Baerts matthieu.baerts@tessares.net
commit 9ac4c28eb70cd5ea5472a5e1c495dcdd597d4597 upstream.
When an error was detected when checking the marks, a message was correctly printed mentioning the error but followed by another one saying everything was OK and the selftest was not marked as failed as expected.
Now the 'ret' variable is directly set to 1 in order to make sure the exit is done with an error, similar to what is done in other functions. While at it, the error is correctly propagated to the caller.
Link: https://github.com/multipath-tcp/mptcp_net-next/issues/368 Fixes: dc65fe82fb07 ("selftests: mptcp: add packet mark test case") Cc: stable@vger.kernel.org Acked-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Matthieu Baerts matthieu.baerts@tessares.net Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/net/mptcp/mptcp_sockopt.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh @@ -119,6 +119,7 @@ check_mark() for v in $values; do if [ $v -ne 0 ]; then echo "FAIL: got $tables $values in ns $ns , not 0 - not all expected packets marked" 1>&2 + ret=1 return 1 fi done @@ -213,11 +214,11 @@ do_transfer() fi
if [ $local_addr = "::" ];then - check_mark $listener_ns 6 - check_mark $connector_ns 6 + check_mark $listener_ns 6 || retc=1 + check_mark $connector_ns 6 || retc=1 else - check_mark $listener_ns 4 - check_mark $connector_ns 4 + check_mark $listener_ns 4 || retc=1 + check_mark $connector_ns 4 || retc=1 fi
check_transfer $cin $sout "file received by server"
From: Matthieu Baerts matthieu.baerts@tessares.net
commit 6c8880fcaa5c45355179b759c1d11737775e31fc upstream.
MPTCP selftests are using TCP SYN Cookies for quite a while now, since v5.9.
Some CIs don't have this config option enabled and this is causing issues in the tests:
# ns1 MPTCP -> ns1 (10.0.1.1:10000 ) MPTCP (duration 167ms) sysctl: cannot stat /proc/sys/net/ipv4/tcp_syncookies: No such file or directory # [ OK ]./mptcp_connect.sh: line 554: [: -eq: unary operator expected
There is no impact in the results but the test is not doing what it is supposed to do.
Fixes: fed61c4b584c ("selftests: mptcp: make 2nd net namespace use tcp syn cookies unconditionally") Cc: stable@vger.kernel.org Signed-off-by: Matthieu Baerts matthieu.baerts@tessares.net Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/net/mptcp/config | 1 + 1 file changed, 1 insertion(+)
--- a/tools/testing/selftests/net/mptcp/config +++ b/tools/testing/selftests/net/mptcp/config @@ -6,6 +6,7 @@ CONFIG_INET_DIAG=m CONFIG_INET_MPTCP_DIAG=m CONFIG_VETH=y CONFIG_NET_SCH_NETEM=m +CONFIG_SYN_COOKIES=y CONFIG_NETFILTER=y CONFIG_NETFILTER_ADVANCED=y CONFIG_NETFILTER_NETLINK=m
From: Masami Hiramatsu (Google) mhiramat@kernel.org
commit b41326b5e0f82e93592c4366359917b5d67b529f upstream.
Fix not to count the error code (which is minus value) to the total used length of array, because it can mess up the return code of process_fetch_insn_bottom(). Also clear the 'ret' value because it will be used for calculating next data_loc entry.
Link: https://lore.kernel.org/all/168908493827.123124.2175257289106364229.stgit@de...
Reported-by: Dan Carpenter dan.carpenter@linaro.org Closes: https://lore.kernel.org/all/8819b154-2ba1-43c3-98a2-cbde20892023@moroto.moun... Fixes: 9b960a38835f ("tracing: probeevent: Unify fetch_insn processing common part") Cc: stable@vger.kernel.org Signed-off-by: Masami Hiramatsu (Google) mhiramat@kernel.org Reviewed-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace_probe_tmpl.h | 2 ++ 1 file changed, 2 insertions(+)
--- a/kernel/trace/trace_probe_tmpl.h +++ b/kernel/trace/trace_probe_tmpl.h @@ -143,6 +143,8 @@ stage3: array: /* the last stage: Loop on array */ if (code->op == FETCH_OP_LP_ARRAY) { + if (ret < 0) + ret = 0; total += ret; if (++i < code->param) { code = s3;
From: Masami Hiramatsu (Google) mhiramat@kernel.org
commit e38e2c6a9efc435f9de344b7c91f7697e01b47d5 upstream.
Fix to update dynamic data counter ('dyndata') and max length ('maxlen') only if the fetcharg uses the dynamic data. Also get out arg->dynamic from unlikely(). This makes dynamic data address wrong if process_fetch_insn() returns error on !arg->dynamic case.
Link: https://lore.kernel.org/all/168908494781.123124.8160245359962103684.stgit@de...
Suggested-by: Steven Rostedt rostedt@goodmis.org Link: https://lore.kernel.org/all/20230710233400.5aaf024e@gandalf.local.home/ Fixes: 9178412ddf5a ("tracing: probeevent: Return consumed bytes of dynamic area") Cc: stable@vger.kernel.org Signed-off-by: Masami Hiramatsu (Google) mhiramat@kernel.org Reviewed-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace_probe_tmpl.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
--- a/kernel/trace/trace_probe_tmpl.h +++ b/kernel/trace/trace_probe_tmpl.h @@ -206,11 +206,13 @@ store_trace_args(void *data, struct trac if (unlikely(arg->dynamic)) *dl = make_data_loc(maxlen, dyndata - base); ret = process_fetch_insn(arg->code, rec, dl, base); - if (unlikely(ret < 0 && arg->dynamic)) { - *dl = make_data_loc(0, dyndata - base); - } else { - dyndata += ret; - maxlen -= ret; + if (arg->dynamic) { + if (unlikely(ret < 0)) { + *dl = make_data_loc(0, dyndata - base); + } else { + dyndata += ret; + maxlen -= ret; + } } } }
From: Quinn Tran qutran@marvell.com
commit fc0cba0c7be8261a1625098bd1d695077ec621c9 upstream.
System crash due to use after free. Current code allows terminate_rport_io to exit before making sure all IOs has returned. For FCP-2 device, IO's can hang on in HW because driver has not tear down the session in FW at first sign of cable pull. When dev_loss_tmo timer pops, terminate_rport_io is called and upper layer is about to free various resources. Terminate_rport_io trigger qla to do the final cleanup, but the cleanup might not be fast enough where it leave qla still holding on to the same resource.
Wait for IO's to return to upper layer before resources are freed.
Cc: stable@vger.kernel.org Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Link: https://lore.kernel.org/r/20230428075339.32551-7-njavali@marvell.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_attr.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
--- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -2738,6 +2738,7 @@ static void qla2x00_terminate_rport_io(struct fc_rport *rport) { fc_port_t *fcport = *(fc_port_t **)rport->dd_data; + scsi_qla_host_t *vha;
if (!fcport) return; @@ -2747,9 +2748,12 @@ qla2x00_terminate_rport_io(struct fc_rpo
if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) return; + vha = fcport->vha;
if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); + qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, + 0, WAIT_TARGET); return; } /* @@ -2774,6 +2778,15 @@ qla2x00_terminate_rport_io(struct fc_rpo qla2x00_port_logout(fcport->vha, fcport); } } + + /* check for any straggling io left behind */ + if (qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, 0, WAIT_TARGET)) { + ql_log(ql_log_warn, vha, 0x300b, + "IO not return. Resetting. \n"); + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); + qla2xxx_wake_dpc(vha); + qla2x00_wait_for_chip_reset(vha); + } }
static int
From: Nilesh Javali njavali@marvell.com
commit d721b591b95cf3f290f8a7cbe90aa2ee0368388d upstream.
Klocwork reports array 'vha->host_str' of size 16 may use index value(s) 16..19. Use snprintf() instead of sprintf().
Cc: stable@vger.kernel.org Co-developed-by: Bikash Hazarika bhazarika@marvell.com Signed-off-by: Bikash Hazarika bhazarika@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Link: https://lore.kernel.org/r/20230607113843.37185-2-njavali@marvell.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_os.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -5042,7 +5042,8 @@ struct scsi_qla_host *qla2x00_create_hos } INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn);
- sprintf(vha->host_str, "%s_%lu", QLA2XXX_DRIVER_NAME, vha->host_no); + snprintf(vha->host_str, sizeof(vha->host_str), "%s_%lu", + QLA2XXX_DRIVER_NAME, vha->host_no); ql_dbg(ql_dbg_init, vha, 0x0041, "Allocated the host=%p hw=%p vha=%p dev_name=%s", vha->host, vha->hw, vha,
From: Nilesh Javali njavali@marvell.com
commit 6b504d06976fe4a61cc05dedc68b84fadb397f77 upstream.
Klocwork reported warning of NULL pointer may be dereferenced. The routine exits when sa_ctl is NULL and fcport is allocated after the exit call thus causing NULL fcport pointer to dereference at the time of exit.
To avoid fcport pointer dereference, exit the routine when sa_ctl is NULL.
Cc: stable@vger.kernel.org Signed-off-by: Nilesh Javali njavali@marvell.com Link: https://lore.kernel.org/r/20230607113843.37185-4-njavali@marvell.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_edif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -2230,8 +2230,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_h if (!sa_ctl) { ql_dbg(ql_dbg_edif, vha, 0x70e6, "sa_ctl allocation failed\n"); - rval = -ENOMEM; - goto done; + rval = -ENOMEM; + return rval; }
fcport = sa_ctl->fcport;
From: Quinn Tran qutran@marvell.com
commit b68710a8094fdffe8dd4f7a82c82649f479bb453 upstream.
Klocwork warning: Buffer Overflow - Array Index Out of Bounds
Driver uses fc_els_flogi to calculate size of buffer. The actual buffer is nested inside of fc_els_flogi which is smaller.
Replace structure name to allow proper size calculation.
Cc: stable@vger.kernel.org Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Link: https://lore.kernel.org/r/20230607113843.37185-6-njavali@marvell.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5359,7 +5359,7 @@ static void qla_get_login_template(scsi_ __be32 *q;
memset(ha->init_cb, 0, ha->init_cb_size); - sz = min_t(int, sizeof(struct fc_els_flogi), ha->init_cb_size); + sz = min_t(int, sizeof(struct fc_els_csp), ha->init_cb_size); rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma, ha->init_cb, sz); if (rval != QLA_SUCCESS) {
From: Bikash Hazarika bhazarika@marvell.com
commit 464ea494a40c6e3e0e8f91dd325408aaf21515ba upstream.
Klocwork tool reported 'cur_dsd' may be dereferenced. Add fix to validate pointer before dereferencing the pointer.
Cc: stable@vger.kernel.org Signed-off-by: Bikash Hazarika bhazarika@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Link: https://lore.kernel.org/r/20230607113843.37185-3-njavali@marvell.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_iocb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -603,7 +603,8 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *s put_unaligned_le32(COMMAND_TYPE_6, &cmd_pkt->entry_type);
/* No data transfer */ - if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { + if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE || + tot_dsds == 0) { cmd_pkt->byte_count = cpu_to_le32(0); return 0; }
From: Nilesh Javali njavali@marvell.com
commit af73f23a27206ffb3c477cac75b5fcf03410556e upstream.
Klocwork reported warning of rport maybe NULL and will be dereferenced. rport returned by call to fc_bsg_to_rport() could be NULL and dereferenced.
Check valid rport returned by fc_bsg_to_rport().
Cc: stable@vger.kernel.org Signed-off-by: Nilesh Javali njavali@marvell.com Link: https://lore.kernel.org/r/20230607113843.37185-5-njavali@marvell.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_bsg.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -283,6 +283,10 @@ qla2x00_process_els(struct bsg_job *bsg_
if (bsg_request->msgcode == FC_BSG_RPT_ELS) { rport = fc_bsg_to_rport(bsg_job); + if (!rport) { + rval = -ENOMEM; + goto done; + } fcport = *(fc_port_t **) rport->dd_data; host = rport_to_shost(rport); vha = shost_priv(host);
From: Bikash Hazarika bhazarika@marvell.com
commit b1b9d3825df4c757d653d0b1df66f084835db9c3 upstream.
Klocwork reported array 'port_dstate_str' of size 10 may use index value(s) 10..15.
Add a fix to correct the index of array.
Cc: stable@vger.kernel.org Signed-off-by: Bikash Hazarika bhazarika@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Link: https://lore.kernel.org/r/20230607113843.37185-8-njavali@marvell.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_inline.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h @@ -109,11 +109,13 @@ qla2x00_set_fcport_disc_state(fc_port_t { int old_val; uint8_t shiftbits, mask; + uint8_t port_dstate_str_sz;
/* This will have to change when the max no. of states > 16 */ shiftbits = 4; mask = (1 << shiftbits) - 1;
+ port_dstate_str_sz = sizeof(port_dstate_str) / sizeof(char *); fcport->disc_state = state; while (1) { old_val = atomic_read(&fcport->shadow_disc_state); @@ -121,7 +123,8 @@ qla2x00_set_fcport_disc_state(fc_port_t old_val, (old_val << shiftbits) | state)) { ql_dbg(ql_dbg_disc, fcport->vha, 0x2134, "FCPort %8phC disc_state transition: %s to %s - portid=%06x.\n", - fcport->port_name, port_dstate_str[old_val & mask], + fcport->port_name, (old_val & mask) < port_dstate_str_sz ? + port_dstate_str[old_val & mask] : "Unknown", port_dstate_str[state], fcport->d_id.b24); return; }
From: Shreyas Deodhar sdeodhar@marvell.com
commit 00eca15319d9ce8c31cdf22f32a3467775423df4 upstream.
Klocwork tool reported pointer 'rport' returned from call to function fc_bsg_to_rport() may be NULL and will be dereferenced.
Add a fix to validate rport before dereferencing.
Cc: stable@vger.kernel.org Signed-off-by: Shreyas Deodhar sdeodhar@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Link: https://lore.kernel.org/r/20230607113843.37185-7-njavali@marvell.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_bsg.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -2903,6 +2903,8 @@ qla24xx_bsg_request(struct bsg_job *bsg_
if (bsg_request->msgcode == FC_BSG_RPT_ELS) { rport = fc_bsg_to_rport(bsg_job); + if (!rport) + return ret; host = rport_to_shost(rport); vha = shost_priv(host); } else {
From: Manish Rangankar mrangankar@marvell.com
commit 20fce500b232b970e40312a9c97e7f3b6d7a709c upstream.
System crash when qla2x00_start_sp(sp) returns error code EGAIN and wake_up gets called for uninitialized wait queue sp->nvme_ls_waitq.
qla2xxx [0000:37:00.1]-2121:5: Returning existing qpair of ffff8ae2c0513400 for idx=0 qla2xxx [0000:37:00.1]-700e:5: qla2x00_start_sp failed = 11 BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 PGD 0 P4D 0 Oops: 0000 [#1] SMP NOPTI Hardware name: HPE ProLiant DL360 Gen10/ProLiant DL360 Gen10, BIOS U32 09/03/2021 Workqueue: nvme-wq nvme_fc_connect_ctrl_work [nvme_fc] RIP: 0010:__wake_up_common+0x4c/0x190 RSP: 0018:ffff95f3e0cb7cd0 EFLAGS: 00010086 RAX: 0000000000000000 RBX: ffff8b08d3b26328 RCX: 0000000000000000 RDX: 0000000000000001 RSI: 0000000000000003 RDI: ffff8b08d3b26320 RBP: 0000000000000001 R08: 0000000000000000 R09: ffffffffffffffe8 R10: 0000000000000000 R11: ffff95f3e0cb7a60 R12: ffff95f3e0cb7d20 R13: 0000000000000003 R14: 0000000000000000 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff8b2fdf6c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000002f1e410002 CR4: 00000000007706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: __wake_up_common_lock+0x7c/0xc0 qla_nvme_ls_req+0x355/0x4c0 [qla2xxx] ? __nvme_fc_send_ls_req+0x260/0x380 [nvme_fc] ? nvme_fc_send_ls_req.constprop.42+0x1a/0x45 [nvme_fc] ? nvme_fc_connect_ctrl_work.cold.63+0x1e3/0xa7d [nvme_fc]
Remove unused nvme_ls_waitq wait queue. nvme_ls_waitq logic was removed previously in the commits tagged Fixed: below.
Fixes: 219d27d7147e ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands") Fixes: 5621b0dd7453 ("scsi: qla2xxx: Simpify unregistration of FC-NVMe local/remote ports") Cc: stable@vger.kernel.org Signed-off-by: Manish Rangankar mrangankar@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Link: https://lore.kernel.org/r/20230615074633.12721-1-njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_def.h | 1 - drivers/scsi/qla2xxx/qla_nvme.c | 3 --- 2 files changed, 4 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -676,7 +676,6 @@ typedef struct srb { struct iocb_resource iores; struct kref cmd_kref; /* need to migrate ref_count over to this */ void *priv; - wait_queue_head_t nvme_ls_waitq; struct fc_port *fcport; struct scsi_qla_host *vha; unsigned int start_timer:1; --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -355,7 +355,6 @@ static int qla_nvme_ls_req(struct nvme_f if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x700e, "qla2x00_start_sp failed = %d\n", rval); - wake_up(&sp->nvme_ls_waitq); sp->priv = NULL; priv->sp = NULL; qla2x00_rel_sp(sp); @@ -637,7 +636,6 @@ static int qla_nvme_post_cmd(struct nvme if (!sp) return -EBUSY;
- init_waitqueue_head(&sp->nvme_ls_waitq); kref_init(&sp->cmd_kref); spin_lock_init(&priv->cmd_lock); sp->priv = priv; @@ -656,7 +654,6 @@ static int qla_nvme_post_cmd(struct nvme if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x212d, "qla2x00_start_nvme_mq failed = %d\n", rval); - wake_up(&sp->nvme_ls_waitq); sp->priv = NULL; priv->sp = NULL; qla2xxx_rel_qpair_sp(sp->qpair, sp);
From: Thomas Bogendoerfer tsbogend@alpha.franken.de
commit 3a6dbb691782e88e07e5c70b327495dbd58a2e7f upstream.
Commit e4de20576986 ("MIPS: KVM: Fix NULL pointer dereference") missed converting one place accessing cop0 registers, which results in a build error, if KVM_MIPS_DEBUG_COP0_COUNTERS is enabled.
Fixes: e4de20576986 ("MIPS: KVM: Fix NULL pointer dereference") Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Reviewed-by: Philippe Mathieu-Daudé philmd@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/kvm/stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/mips/kvm/stats.c b/arch/mips/kvm/stats.c index 53f851a61554..3e6682018fbe 100644 --- a/arch/mips/kvm/stats.c +++ b/arch/mips/kvm/stats.c @@ -54,9 +54,9 @@ void kvm_mips_dump_stats(struct kvm_vcpu *vcpu) kvm_info("\nKVM VCPU[%d] COP0 Access Profile:\n", vcpu->vcpu_id); for (i = 0; i < N_MIPS_COPROC_REGS; i++) { for (j = 0; j < N_MIPS_COPROC_SEL; j++) { - if (vcpu->arch.cop0->stat[i][j]) + if (vcpu->arch.cop0.stat[i][j]) kvm_info("%s[%d]: %lu\n", kvm_cop0_str[i], j, - vcpu->arch.cop0->stat[i][j]); + vcpu->arch.cop0.stat[i][j]); } } #endif
From: Pedro Tammela pctammela@mojatatu.com
commit 158810b261d02fc7dd92ca9c392d8f8a211a2401 upstream.
25369891fcef deletes a check for the case where no 'lmax' is specified which 3037933448f6 previously fixed as 'lmax' could be set to the device's MTU without any bound checking for QFQ_LMAX_MIN and QFQ_LMAX_MAX. Therefore, reintroduce the check.
Fixes: 25369891fcef ("net/sched: sch_qfq: refactor parsing of netlink parameters") Acked-by: Jamal Hadi Salim jhs@mojatatu.com Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: Pedro Tammela pctammela@mojatatu.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/sched/sch_qfq.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
--- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -428,10 +428,17 @@ static int qfq_change_class(struct Qdisc else weight = 1;
- if (tb[TCA_QFQ_LMAX]) + if (tb[TCA_QFQ_LMAX]) { lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); - else + } else { + /* MTU size is user controlled */ lmax = psched_mtu(qdisc_dev(sch)); + if (lmax < QFQ_MIN_LMAX || lmax > QFQ_MAX_LMAX) { + NL_SET_ERR_MSG_MOD(extack, + "MTU size out of bounds for qfq"); + return -EINVAL; + } + }
inv_w = ONE_FP / weight; weight = ONE_FP / inv_w;
Hi,
On Fri, 21 Jul 2023 17:58:24 +0200 Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.121 release. There are 532 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 Sun, 23 Jul 2023 16:04:40 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.121-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
I confirmed that this rc kernel passes DAMON functionality test[1] on my test machine. Attaching the test results summary below.
Tested-by: SeongJae Park sj@kernel.org
[1] https://github.com/awslabs/damon-tests/tree/next/corr
Thanks, SJ
[...]
---
ok 1 selftests: damon: debugfs_attrs.sh ok 1 selftests: damon-tests: kunit.sh ok 2 selftests: damon-tests: huge_count_read_write.sh ok 3 selftests: damon-tests: buffer_overflow.sh ok 4 selftests: damon-tests: rm_contexts.sh ok 5 selftests: damon-tests: record_null_deref.sh ok 6 selftests: damon-tests: dbgfs_target_ids_read_before_terminate_race.sh ok 7 selftests: damon-tests: dbgfs_target_ids_pid_leak.sh ok 8 selftests: damon-tests: damo_tests.sh ok 9 selftests: damon-tests: masim-record.sh ok 10 selftests: damon-tests: build_i386.sh ok 11 selftests: damon-tests: build_m68k.sh ok 12 selftests: damon-tests: build_arm64.sh ok 13 selftests: damon-tests: build_i386_idle_flag.sh ok 14 selftests: damon-tests: build_i386_highpte.sh ok 15 selftests: damon-tests: build_nomemcg.sh
PASS
On 7/21/2023 8:58 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.15.121 release. There are 532 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 Sun, 23 Jul 2023 16:04:40 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.121-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.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 florian.fainelli@broadcom.com
On Sat, 22 Jul 2023 at 00:21, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.121 release. There are 532 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 Sun, 23 Jul 2023 16:04:40 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.121-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Tested-by: Linux Kernel Functional Testing lkft@linaro.org
## Build * kernel: 5.15.121-rc1 * git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc * git branch: linux-5.15.y * git commit: 48958c96454b9acda1f1117b5206838864697de8 * git describe: v5.15.120-533-g48958c96454b * test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15....
## Test Regressions (compared to v5.15.120)
## Metric Regressions (compared to v5.15.120)
## Test Fixes (compared to v5.15.120)
## Metric Fixes (compared to v5.15.120)
## Test result summary total: 92345, pass: 74734, fail: 2019, skip: 15525, xfail: 67
## Build Summary * arc: 5 total, 5 passed, 0 failed * arm: 117 total, 116 passed, 1 failed * arm64: 45 total, 43 passed, 2 failed * i386: 35 total, 32 passed, 3 failed * mips: 27 total, 26 passed, 1 failed * parisc: 4 total, 4 passed, 0 failed * powerpc: 27 total, 26 passed, 1 failed * riscv: 11 total, 11 passed, 0 failed * s390: 12 total, 11 passed, 1 failed * sh: 14 total, 12 passed, 2 failed * sparc: 8 total, 8 passed, 0 failed * x86_64: 38 total, 36 passed, 2 failed
## Test suites summary * boot * kselftest-android * kselftest-arm64 * kselftest-breakpoints * kselftest-capabilities * kselftest-cgroup * kselftest-clone3 * kselftest-core * kselftest-cpu-hotplug * kselftest-cpufreq * kselftest-drivers-dma-buf * kselftest-efivarfs * kselftest-exec * kselftest-filesystems * kselftest-filesystems-binderfs * kselftest-filesytems-epoll * kselftest-firmware * kselftest-fpu * kselftest-ftrace * kselftest-futex * kselftest-gpio * kselftest-intel_pstate * kselftest-ipc * kselftest-ir * kselftest-kcmp * kselftest-kexec * kselftest-kvm * kselftest-lib * kselftest-membarrier * kselftest-memfd * kselftest-memory-hotplug * kselftest-mincore * kselftest-mount * kselftest-mqueue * kselftest-net * kselftest-net-forwarding * kselftest-net-mptcp * kselftest-netfilter * kselftest-nsfs * kselftest-openat2 * kselftest-pid_namespace * kselftest-pidfd * kselftest-proc * kselftest-pstore * kselftest-ptrace * kselftest-rseq * kselftest-rtc * kselftest-seccomp * kselftest-sigaltstack * kselftest-size * kselftest-splice * kselftest-static_keys * kselftest-sync * kselftest-sysctl * kselftest-tc-testing * kselftest-timens * kselftest-tmpfs * kselftest-tpm2 * kselftest-user_events * kselftest-vDSO * kselftest-watchdog * kselftest-x86 * kunit * kvm-unit-tests * libgpiod * libhugetlbfs * log-parser-boot * log-parser-test * ltp-cap_bounds * ltp-commands * ltp-containers * ltp-controllers * ltp-cpuhotplug * ltp-crypto * ltp-cve * ltp-dio * ltp-fcntl-locktests * ltp-filecaps * ltp-fs * ltp-fs_bind * ltp-fs_perms_simple * ltp-fsx * ltp-hugetlb * ltp-io * ltp-ipc * ltp-math * ltp-mm * ltp-nptl * ltp-pty * ltp-sched * ltp-securebits * ltp-smoke * ltp-syscalls * ltp-tracing * rcutorture
-- Linaro LKFT https://lkft.linaro.org
On Fri, Jul 21, 2023 at 05:58:24PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.15.121 release. There are 532 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 Sun, 23 Jul 2023 16:04:40 +0000. Anything received after that time might be too late.
Build results: total: 160 pass: 160 fail: 0 Qemu test results: total: 502 pass: 502 fail: 0
Tested-by: Guenter Roeck linux@roeck-us.net
Guenter
On 7/21/23 8:58 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.15.121 release. There are 532 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 Sun, 23 Jul 2023 16:04:40 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.121-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.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 Fri, 21 Jul 2023 17:58:24 +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.15.121 release. There are 532 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 Sun, 23 Jul 2023 16:04:40 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.121-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.15: 11 builds: 11 pass, 0 fail 28 boots: 28 pass, 0 fail 114 tests: 114 pass, 0 fail
Linux version: 5.15.121-rc1-g48958c96454b Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000, tegra20-ventana, tegra210-p2371-2180, tegra210-p3450-0000, tegra30-cardhu-a04
Tested-by: Jon Hunter jonathanh@nvidia.com
Jon
Hi Greg,
On 21/07/23 9:28 pm, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.15.121 release. There are 532 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 Sun, 23 Jul 2023 16:04:40 +0000. Anything received after that time might be too late.
No problems seen on x86_64 and aarch64.
Tested-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
Thanks, Harshit
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.121-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
linux-stable-mirror@lists.linaro.org