This is the start of the stable review cycle for the 5.19.2 release. There are 1157 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Aug 2022 18:01:29 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.19.2-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.19.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 5.19.2-rc1
Luiz Augusto von Dentz luiz.von.dentz@intel.com Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm regression
Pavel Begunkov asml.silence@gmail.com io_uring: mem-account pbuf buckets
Russell Currey ruscur@russell.cc powerpc/kexec: Fix build failure from uninitialised variable
Alexander Gordeev agordeev@linux.ibm.com Revert "s390/smp: enforce lowcore protection on CPU restart"
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: felix: fix min gate len calculation for tc when its first gate is closed
Steven Rostedt (Google) rostedt@goodmis.org tracing: Use a copy of the va_list for __assign_vstr()
Johannes Berg johannes.berg@intel.com wifi: cfg80211: remove chandef check in cfg80211_cac_event()
Johannes Berg johannes.berg@intel.com wifi: nl80211: acquire wdev mutex earlier in start_ap
Johannes Berg johannes.berg@intel.com wifi: nl80211: relax wdev mutex check in wdev_chandef()
Johannes Berg johannes.berg@intel.com wifi: nl80211: hold wdev mutex for tid config
Johannes Berg johannes.berg@intel.com wifi: cfg80211: handle IBSS in channel switch
Paolo Abeni pabeni@redhat.com mptcp: refine memory scheduling
Greg Kroah-Hartman gregkh@linuxfoundation.org Revert "devcoredump: remove the useless gfp_t parameter in dev_coredumpv and dev_coredumpm"
Greg Kroah-Hartman gregkh@linuxfoundation.org Revert "mwifiex: fix sleep in atomic context bugs caused by dev_coredumpv"
Eric Dumazet edumazet@google.com raw: fix a typo in raw_icmp_error()
Eric Dumazet edumazet@google.com raw: remove unused variables from raw6_icmp_error()
Jason A. Donenfeld Jason@zx2c4.com crypto: lib/blake2s - reduce stack frame usage in self test
Eric Dumazet edumazet@google.com tcp: fix over estimation in sk_forced_mem_schedule()
Robert Foss robert.foss@linaro.org Revert "drm/bridge: anx7625: Use DPI bus type"
Thadeu Lima de Souza Cascardo cascardo@canonical.com net_sched: cls_route: remove from list when handle is 0
Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com powerpc64/ftrace: Fix ftrace for clang builds
Christophe Leroy christophe.leroy@csgroup.eu powerpc: Fix eh field when calling lwarx on PPC32
SeongJae Park sj@kernel.org xen-blkfront: Apply 'feature_persistent' parameter when connect
Maximilian Heyne mheyne@amazon.de xen-blkback: Apply 'feature_persistent' parameter when connect
SeongJae Park sj@kernel.org xen-blkback: fix persistent grants negotiation
Mårten Lindahl marten.lindahl@axis.com tpm: Add check for Failure mode for TPM2 modules
Huacai Chen chenhuacai@kernel.org tpm: eventlog: Fix section mismatch for DEBUG_SECTION_MISMATCH
Tianjia Zhang tianjia.zhang@linux.alibaba.com KEYS: asymmetric: enforce SM2 signature use pkey algo
Jan Kara jack@suse.cz ext4: fix race when reusing xattr blocks
Jan Kara jack@suse.cz ext4: unindent codeblock in ext4_xattr_block_set()
Jan Kara jack@suse.cz ext4: remove EA inode entry from mbcache on inode eviction
Lukas Czerner lczerner@redhat.com ext4: make sure ext4_append() always allocates new block
Lukas Czerner lczerner@redhat.com ext4: check if directory block is within i_size
Bagas Sanjaya bagasdotme@gmail.com Documentation: ext4: fix cell spacing of table heading on blockmap table
Ye Bin yebin10@huawei.com ext4: fix warning in ext4_iomap_begin as race between bmap and write
Baokun Li libaokun1@huawei.com ext4: correct the misjudgment in ext4_iget_extra_inode
Baokun Li libaokun1@huawei.com ext4: correct max_inline_xattr_value_size computing
Baokun Li libaokun1@huawei.com ext4: fix use-after-free in ext4_xattr_set_entry
Baokun Li libaokun1@huawei.com ext4: add EXT4_INODE_HAS_XATTR_SPACE macro in xattr.h
Eric Whitney enwlinux@gmail.com ext4: fix extent status tree race in writeback error recovery path
Theodore Ts'o tytso@mit.edu ext4: update s_overhead_clusters in the superblock during an on-line resize
Zhang Yi yi.zhang@huawei.com ext4: fix reading leftover inlined symlinks
Steven Rostedt (Google) rostedt@goodmis.org tracing: Use a struct alignof to determine trace event field alignment
Steven Rostedt (Google) rostedt@goodmis.org batman-adv: tracing: Use the new __vstring() helper
Miaohe Lin linmiaohe@huawei.com hugetlb_cgroup: fix wrong hugetlb cgroup numa stat
Jianglei Nie niejianglei2021@163.com mm/damon/reclaim: fix potential memory leak in damon_reclaim_init()
Mike Snitzer snitzer@kernel.org dm: fix dm-raid crash if md_handle_request() splits bio
Mikulas Patocka mpatocka@redhat.com dm raid: fix address sanitizer warning in raid_resume
Mikulas Patocka mpatocka@redhat.com dm raid: fix address sanitizer warning in raid_status
Sean Christopherson seanjc@google.com KVM: nVMX: Attempt to load PERF_GLOBAL_CTRL on nVMX xfer iff it exists
Sean Christopherson seanjc@google.com KVM: VMX: Add helper to check if the guest PMU has PERF_GLOBAL_CTRL
Sean Christopherson seanjc@google.com Revert "KVM: x86/pmu: Accept 0 for absent PMU MSRs when host-initiated if !enable_pmu"
Like Xu likexu@tencent.com KVM: x86/pmu: Accept 0 for absent PMU MSRs when host-initiated if !enable_pmu
Like Xu likexu@tencent.com KVM: x86/pmu: Ignore pmu->global_ctrl check if vPMU doesn't support global_ctrl
Sean Christopherson seanjc@google.com KVM: VMX: Mark all PERF_GLOBAL_(OVF)_CTRL bits reserved if there's no vPMU
Like Xu like.xu@linux.intel.com KVM: x86/pmu: Introduce the ctrl_mask value for fixed counter
Sumanth Korikkar sumanthk@linux.ibm.com s390/unwind: fix fgraph return address recovery
Jason A. Donenfeld Jason@zx2c4.com powerpc/powernv/kvm: Use darn for H_RANDOM on Power9
Rafael J. Wysocki rafael.j.wysocki@intel.com ACPI: CPPC: Do not prevent CPPC from working in the future
Artem Bityutskiy artem.bityutskiy@linux.intel.com intel_idle: make SPR C1 and C1E be independent
Filipe Manana fdmanana@suse.com btrfs: join running log transaction when logging new name
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: wait until zone is finished when allocation didn't progress
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: write out partially allocated region
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: activate necessary block group
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: activate metadata block group on flush_space
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: introduce space_info->active_total_bytes
Stefan Roesch shr@fb.com btrfs: store chunk size in space-info struct
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: disable metadata overcommit for zoned
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: finish least available block group on data bg allocation
Naohiro Aota naohiro.aota@wdc.com btrfs: let can_allocate_chunk return error
Naohiro Aota naohiro.aota@wdc.com btrfs: convert count_max_extents() to use fs_info->max_extent_size
Naohiro Aota naohiro.aota@wdc.com btrfs: replace BTRFS_MAX_EXTENT_SIZE with fs_info->max_extent_size
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: revive max_zone_append_bytes
Naohiro Aota naohiro.aota@wdc.com block: add bdev_max_segments() helper
Nikolay Borisov nborisov@suse.com btrfs: properly flag filesystem with BTRFS_FEATURE_INCOMPAT_BIG_METADATA
Josef Bacik josef@toxicpanda.com btrfs: reset block group chunk force if we have to wait
Naohiro Aota naohiro.aota@wdc.com btrfs: fix error handling of fallback uncompress write
Naohiro Aota naohiro.aota@wdc.com btrfs: ensure pages are unlocked on cow_file_range() failure
Josef Bacik josef@toxicpanda.com btrfs: tree-log: make the return value for log syncing consistent
Jinke Han hanjinke.666@bytedance.com block: don't allow the same type rq_qos add more than once
Chen Zhongjin chenzhongjin@huawei.com locking/csd_lock: Change csdlock_debug from early_param to __setup
Jason A. Donenfeld Jason@zx2c4.com timekeeping: contribute wall clock to rng on time change
Pali Rohár pali@kernel.org ARM: Marvell: Update PCIe fixup
Tyler Hicks tyhicks@linux.microsoft.com net/9p: Initialize the iounit field during fid creation
Luo Meng luomeng12@huawei.com dm thin: fix use-after-free crash in dm_sm_register_threshold_callback
Steven Rostedt (Google) rostedt@goodmis.org tracing/events: Add __vstring() and __assign_vstr() helper macros
Michal Suchanek msuchanek@suse.de kexec, KEYS, s390: Make use of built-in and secondary keyring for signature verification
Coiby Xu coxu@redhat.com kexec: clean up arch_kexec_kernel_verify_sig
Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com kexec_file: drop weak attribute from functions
Mikulas Patocka mpatocka@redhat.com dm writecache: set a default MAX_WRITEBACK_JOBS
Robert Marko robimarko@gmail.com PCI: qcom: Power on PHY before IPQ8074 DBI register accesses
Mohamed Khalfella mkhalfella@purestorage.com PCI/AER: Iterate over error counters instead of error strings
Alexander Lobakin alexandr.lobakin@intel.com iommu/vt-d: avoid invalid memory access via node_online(NUMA_NO_NODE)
Sean Christopherson seanjc@google.com KVM: x86: Signal #GP, not -EPERM, on bad WRMSR(MCi_CTL/STATUS)
Lev Kujawski lkujaw@member.fsf.org KVM: set_msr_mce: Permit guests to ignore single-bit ECC errors
Alexander Shishkin alexander.shishkin@linux.intel.com intel_th: pci: Add Raptor Lake-S CPU support
Alexander Shishkin alexander.shishkin@linux.intel.com intel_th: pci: Add Raptor Lake-S PCH support
Alexander Shishkin alexander.shishkin@linux.intel.com intel_th: pci: Add Meteor Lake-P support
Sudeep Holla sudeep.holla@arm.com firmware: arm_scpi: Ensure scpi_info is not assigned if the probe fails
Jason A. Donenfeld Jason@zx2c4.com crypto: blake2s - remove shash module
Jitao Shi jitao.shi@mediatek.com drm/mediatek: Keep dsi as LP00 before dcs cmds transfer
Phil Auld pauld@redhat.com drivers/base: fix userspace break from using bin_attributes for cpumap and cpulist
Guo Ren guoren@kernel.org csky: abiv1: Fixup compile error
David Collins quic_collinsd@quicinc.com spmi: trace: fix stack-out-of-bound access in SPMI tracing functions
Al Viro viro@zeniv.linux.org.uk __follow_mount_rcu(): verify that mount_lock remains unchanged
Xie Shaowen studentxswpy@163.com Input: gscps2 - check return value of ioremap() in gscps2_probe()
Thadeu Lima de Souza Cascardo cascardo@canonical.com posix-cpu-timers: Cleanup CPU timers before freeing them during exec
Bharath SM bharathsm@microsoft.com SMB3: fix lease break timeout when multiple deferred close handles for the same file.
Alexander Lobakin alexandr.lobakin@intel.com x86/olpc: fix 'logical not is only applied to the left hand side'
Masami Hiramatsu (Google) mhiramat@kernel.org x86/kprobes: Update kcb status flag after singlestepping
Steven Rostedt (Google) rostedt@goodmis.org ftrace/x86: Add back ftrace_expected assignment
Kim Phillips kim.phillips@amd.com x86/bugs: Enable STIBP for IBPB mitigated RETBleed
Paulo Alcantara pc@cjr.nz cifs: fix lock length calculation
Arun Easi aeasi@marvell.com scsi: qla2xxx: Fix losing FCP-2 targets during port perturbation tests
Arun Easi aeasi@marvell.com scsi: qla2xxx: Fix losing target when it reappears during delete
Arun Easi aeasi@marvell.com scsi: qla2xxx: Fix losing FCP-2 targets on long port disable with I/Os
Quinn Tran qutran@marvell.com scsi: qla2xxx: Wind down adapter after PCIe error
Quinn Tran qutran@marvell.com scsi: qla2xxx: Fix erroneous mailbox timeout after PCI error injection
Arun Easi aeasi@marvell.com scsi: qla2xxx: Fix excessive I/O error messages by default
Arun Easi aeasi@marvell.com scsi: qla2xxx: Fix crash due to stale SRB access around I/O timeouts
Quinn Tran qutran@marvell.com scsi: qla2xxx: Turn off multi-queue for 8G adapters
Arun Easi aeasi@marvell.com scsi: qla2xxx: Fix discovery issues in FC-AL topology
Quinn Tran qutran@marvell.com scsi: qla2xxx: Fix imbalance vha->vref_count
Steffen Maier maier@linux.ibm.com scsi: zfcp: Fix missing auto port scan and thus missing target ports
Peter Wang peter.wang@mediatek.com scsi: ufs: core: Correct ufshcd_shutdown() flow
Zheyu Ma zheyuma97@gmail.com video: fbdev: s3fb: Check the size of screen before memset_io()
Zheyu Ma zheyuma97@gmail.com video: fbdev: arkfb: Check the size of screen before memset_io()
Zheyu Ma zheyuma97@gmail.com video: fbdev: vt8623fb: Check the size of screen before memset_io()
Jaewook Kim jw5454.kim@samsung.com f2fs: do not allow to decompress files have FI_COMPRESS_RELEASED
Andrea Righi andrea.righi@canonical.com x86/entry: Build thunk_$(BITS) only if CONFIG_PREEMPTION=y
Mel Gorman mgorman@techsingularity.net sched/core: Do not requeue task on CPU excluded from cpus_mask
Tianchen Ding dtcccc@linux.alibaba.com sched: Remove the limitation of WF_ON_CPU on wakelist if wakee cpu is idle
Tianchen Ding dtcccc@linux.alibaba.com sched: Fix the check of nr_running at queue wakelist
Florian Fainelli f.fainelli@gmail.com tools/thermal: Fix possible path truncations
Zheyu Ma zheyuma97@gmail.com video: fbdev: arkfb: Fix a divide-by-zero bug in ark_set_pixclock()
Siddh Raman Pant code@siddh.me x86/numa: Use cpumask_available instead of hardcoded NULL check
Waiman Long longman@redhat.com sched, cpuset: Fix dl_cpu_busy() panic due to empty cs->cpus_allowed
Michael Ellerman mpe@ellerman.id.au powerpc/64e: Fix kexec build error
Douglas Anderson dianders@chromium.org tty: serial: qcom-geni-serial: Fix %lu -> %u in print statements
Josh Poimboeuf jpoimboe@kernel.org scripts/faddr2line: Fix vmlinux detection on arm64
Arnaldo Carvalho de Melo acme@redhat.com genelf: Use HAVE_LIBCRYPTO_SUPPORT, not the never defined HAVE_LIBCRYPTO
Michael Ellerman mpe@ellerman.id.au powerpc/pci: Fix PHB numbering when using opal-phbid
Chenyi Qiang chenyi.qiang@intel.com x86/bus_lock: Don't assume the init value of DEBUGCTLMSR.BUS_LOCK_DETECT to be zero
Chen Zhongjin chenzhongjin@huawei.com kprobes: Forbid probing on trampoline and BPF code areas
Ian Rogers irogers@google.com perf symbol: Fail to read phdr workaround
Miaoqian Lin linmq006@gmail.com powerpc/cell/axon_msi: Fix refcount leak in setup_msi_msg_address
Miaoqian Lin linmq006@gmail.com powerpc/xive: Fix refcount leak in xive_get_max_prio
Miaoqian Lin linmq006@gmail.com powerpc/spufs: Fix refcount leak in spufs_init_isolated_loader
Matthew Wilcox (Oracle) willy@infradead.org cifs: Fix memory leak when using fscache
Chao Liu liuchao@coolpad.com f2fs: fix to remove F2FS_COMPR_FL and tag F2FS_NOCOMP_FL at the same time
Chao Yu chao@kernel.org f2fs: fix to check inline_data during compressed inode conversion
Chao Yu chao@kernel.org f2fs: fix to invalidate META_MAPPING before DIO write
Kan Liang kan.liang@linux.intel.com perf stat: Revert "perf stat: Add default hybrid events"
Alexander Gordeev agordeev@linux.ibm.com s390/smp: enforce lowcore protection on CPU restart
Sherry Sun sherry.sun@nxp.com tty: serial: fsl_lpuart: correct the count of break characters
Vijaya Krishna Nivarthi quic_vnivarth@quicinc.com tty: serial: qcom-geni-serial: Fix get_clk_div_rate() which otherwise could return a sub-optimal clock rate.
Guo Mengqi guomengqi3@huawei.com serial: 8250_bcm2835aux: Add missing clk_disable_unprepare()
Rashmica Gupta rashmica@linux.ibm.com selftests/powerpc: Fix matrix multiply assist test
Pali Rohár pali@kernel.org powerpc/pci: Prefer PCI domain assignment via DT 'linux,pci-domain' and alias
Alexey Kardashevskiy aik@ozlabs.ru powerpc/iommu: Fix iommu_table_in_use for a small default DMA window case
Alexey Kardashevskiy aik@ozlabs.ru pseries/iommu/ddw: Fix kdump to work in absence of ibm,dma-window
Christophe Leroy christophe.leroy@csgroup.eu video: fbdev: offb: Include missing linux/platform_device.h
Christophe Leroy christophe.leroy@csgroup.eu powerpc/32: Do not allow selection of e5500 or e6500 CPUs on PPC32
Christophe Leroy christophe.leroy@csgroup.eu powerpc/32s: Fix boot failure with KASAN + SMP + JUMP_LABEL_FEATURE_CHECK_DEBUG
Christophe Leroy christophe.leroy@csgroup.eu powerpc/32: Call mmu_mark_initmem_nx() regardless of data block mapping.
Claudiu Beznea claudiu.beznea@microchip.com ASoC: mchp-spdifrx: disable end of block interrupt on failures
Rustam Subkhankulov subkhankulov@ispras.ru video: fbdev: sis: fix typos in SiS_GetModeID()
Liang He windhl@126.com video: fbdev: amba-clcd: Fix refcount leak bugs
Yong Zhi yong.zhi@intel.com ASoC: Intel: sof_rt5682: Perform quirk check first in card late probe
William Dean williamsukatube@gmail.com watchdog: armada_37xx_wdt: check the return value of devm_ioremap() in armada_37xx_wdt_probe()
Jean Delvare jdelvare@suse.de watchdog: sp5100_tco: Fix a memory leak of EFCH MMIO resource
Jiasheng Jiang jiasheng@iscas.ac.cn watchdog: f71808e_wdt: Add check for platform_driver_register
Liang He windhl@126.com ASoC: audio-graph-card2: Add of_node_put() in fail path
Liang He windhl@126.com ASoC: audio-graph-card: Add of_node_put() in fail path
Xie Yongji xieyongji@bytedance.com fuse: Remove the control interface for virtio-fs
Christophe JAILLET christophe.jaillet@wanadoo.fr ASoC: qcom: q6dsp: Fix an off-by-one in q6adm_alloc_copp()
Shengjiu Wang shengjiu.wang@nxp.com ASoC: imx-card: use snd_pcm_format_t type for asrc_format
Shengjiu Wang shengjiu.wang@nxp.com ASoC: fsl_easrc: use snd_pcm_format_t type for sample_format
Shengjiu Wang shengjiu.wang@nxp.com ASoC: fsl-asoc-card: force cast the asrc_format type
Shengjiu Wang shengjiu.wang@nxp.com ASoC: fsl_asrc: force cast the asrc_format type
Thomas Richter tmricht@linux.ibm.com perf test: Fix test case 83 ('perf stat CSV output linter') on s390
Alexander Gordeev agordeev@linux.ibm.com s390/zcore: fix race when reading from hardware system area
Alexander Gordeev agordeev@linux.ibm.com s390/crash: fix incorrect number of bytes to copy to user space
Sunil V L sunilvl@ventanamicro.com riscv: spinwait: Fix hartid variable type
Adrian Hunter adrian.hunter@intel.com perf tools: Fix dso_id inode generation comparison
Liang He windhl@126.com iommu/arm-smmu: qcom_iommu: Add of_node_put() when breaking out of loop
Mario Limonciello mario.limonciello@amd.com ASoC: amd: yc: Decrease level of error message
Miaoqian Lin linmq006@gmail.com mfd: max77620: Fix refcount leak in max77620_initialise_fps
Uwe Kleine-König u.kleine-koenig@pengutronix.de mfd: t7l66xb: Drop platform disable callback
Sibi Sankar quic_sibis@quicinc.com remoteproc: sysmon: Wait for SSCTL service to come up
Siddharth Gupta sidgup@codeaurora.org remoteproc: qcom: pas: Check if coredump is enabled
Zhihao Cheng chengzhihao1@huawei.com proc: fix a dentry lock race between release_task and lookup
Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp lib/smp_processor_id: fix imbalanced instrumentation_end() call
Dan Carpenter dan.carpenter@oracle.com kfifo: fix kfifo_to_user() return type
Emil Renner Berthing emil.renner.berthing@canonical.com leds: pwm-multicolor: Don't show -EPROBE_DEFER as errors
Miaoqian Lin linmq006@gmail.com rpmsg: qcom_smd: Fix refcount leak in qcom_smd_parse_edge
Florian Fainelli f.fainelli@gmail.com MIPS: Fixed __debug_virt_addr_valid()
Hangyu Hua hbh25y@gmail.com net: 9p: fix refcount leak in p9_read_work() error handling
Kent Overstreet kent.overstreet@gmail.com 9p: Add client parameter to p9_req_put()
Kent Overstreet kent.overstreet@gmail.com 9p: Drop kref usage
Sam Protsenko semen.protsenko@linaro.org iommu/exynos: Handle failed IOMMU device registration properly
Doug Berger opendmb@gmail.com serial: 8250_bcm7271: Save/restore RTS in suspend/resume
Dan Carpenter dan.carpenter@oracle.com ASoC: SOF: ipc-msg-injector: fix copy in sof_msg_inject_ipc4_dfs_write()
Liang He windhl@126.com ASoC: mt6359: Fix refcount leak bug
Liang He windhl@126.com ASoc: audio-graph-card2: Fix refcount leak bug in __graph_get_type()
Yang Yingliang yangyingliang@huawei.com cpufreq: mediatek: fix error return code in mtk_cpu_dvfs_info_init()
Peter Ujfalusi peter.ujfalusi@linux.intel.com ASoC: SOF: ipc3-topology: Prevent double freeing of ipc_control_data via load_bytes
Alexander Lobakin alexandr.lobakin@intel.com lib/bitmap: fix off-by-one in bitmap_to_arr64()
Robin Murphy robin.murphy@arm.com swiotlb: fail map correctly with failed io_tlb_default_mem
YC Hung yc.hung@mediatek.com ASoC: SOF: mediatek: fix mt8195 StatvectorSel wrong setting
Florian Fainelli f.fainelli@gmail.com MIPS: vdso: Utilize __pa() for gic_pfn
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix missing corner cases in gsmld_poll()
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix flow control handling in tx path
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix DM command
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix wrong T1 retry count handling
Uwe Kleine-König u.kleine-koenig@pengutronix.de serial: 8250_fsl: Don't report FE, PE and OE twice
Kuninori Morimoto kuninori.morimoto.gx@renesas.com ASoC: audio-graph-card2.c: use of_property_read_u32() for rate
Eric Farman farman@linux.ibm.com vfio/ccw: Do not change FSM state in subchannel event
Eric Farman farman@linux.ibm.com vfio/ccw: Fix FSM state if mdev probe fails
Michael Kawano mkawano@linux.ibm.com vfio/ccw: Remove UUID from s390 debug log
Sireesh Kodali sireeshkodali1@gmail.com remoteproc: qcom: wcnss: Fix handling of IRQs
Shengjiu Wang shengjiu.wang@nxp.com ASoC: imx-card: Fix DSD/PDM mclk frequency
Tiezhu Yang yangtiezhu@loongson.cn MIPS: Loongson64: Fix section mismatch warning
Liang He windhl@126.com ASoC: qcom: Fix missing of_node_put() in asoc_qcom_lpass_cpu_platform_probe()
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix resource allocation order in gsm_activate_mux()
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix deadlock and link starvation in outgoing data path
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix race condition in gsmld_write()
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix packet re-transmission without open control channel
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix non flow control frames during mux flow off
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix missing timer to handle stalled links
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix wrong queuing behavior in gsm_dlci_data_output()
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix tty registration before control channel open
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix user open not possible at responder until initiator open
Alexander Lobakin alexandr.lobakin@intel.com net/ice: fix initializing the bitmap in the switch code
Yishai Hadas yishaih@nvidia.com vfio: Split migration ops from main device ops
Yishai Hadas yishaih@nvidia.com vfio/mlx5: Protect mlx5vf_disable_fds() upon close device
Srinivas Kandagatla srinivas.kandagatla@linaro.org ASoC: codecs: wsa881x: handle timeouts in resume path
Ilpo Järvinen ilpo.jarvinen@linux.intel.com serial: 8250_dw: Take port lock while accessing LSR
Tom Rix trix@redhat.com ASoC: samsung: change gpiod_speaker_power and rx1950_audio from global to static variables
Kuninori Morimoto kuninori.morimoto.gx@renesas.com ASoC: soc-core.c: fixup snd_soc_of_get_dai_link_cpus()
Athira Rajeev atrajeev@linux.vnet.ibm.com powerpc/perf: Optimize clearing the pending PMI and remove WARN_ON for PMI check in power_pmu_disable
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ASoC: samsung: h1940_uda1380: include proepr GPIO consumer header
Michael Ellerman mpe@ellerman.id.au selftests/powerpc: Skip energy_scale_info test on older firmware
Hangyu Hua hbh25y@gmail.com rpmsg: Fix possible refcount leak in rpmsg_register_device_override()
Alexey Kardashevskiy aik@ozlabs.ru KVM: PPC: Book3s: Fix warning about xics_rm_h_xirr_x
Miaoqian Lin linmq006@gmail.com remoteproc: imx_rproc: Fix refcount leak in imx_rproc_addr_init
Chen Zhongjin chenzhongjin@huawei.com profiling: fix shift too large makes kernel panic
Joe Lawrence joe.lawrence@redhat.com selftests/livepatch: better synchronize test_klp_callbacks_busy
Miaoqian Lin linmq006@gmail.com remoteproc: k3-r5: Fix refcount leak in k3_r5_cluster_of_init
AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com rpmsg: mtk_rpmsg: Fix circular locking dependency
Shengjiu Wang shengjiu.wang@nxp.com rpmsg: char: Add mutex protection for rpmsg_eptdev_open()
Charles Keepax ckeepax@opensource.cirrus.com ASoC: cs35l45: Add endianness flag in snd_soc_component_driver
Srinivas Kandagatla srinivas.kandagatla@linaro.org ASoC: codecs: wcd9335: move gains from SX_TLV to S8_TLV
Srinivas Kandagatla srinivas.kandagatla@linaro.org ASoC: codecs: msm8916-wcd-digital: move gains from SX_TLV to S8_TLV
Peter Ujfalusi peter.ujfalusi@linux.intel.com ASoC: SOF: make ctx_store and ctx_restore as optional
Ilpo Järvinen ilpo.jarvinen@linux.intel.com serial: 8250_dw: Store LSR into lsr_saved_flags in dw8250_tx_wait_empty()
Ilpo Järvinen ilpo.jarvinen@linux.intel.com serial: 8250_dw: Use serial_lsr_in() in dw8250_handle_irq()
Ilpo Järvinen ilpo.jarvinen@linux.intel.com serial: 8250: Get preserved flags using serial_lsr_in()
Ilpo Järvinen ilpo.jarvinen@linux.intel.com serial: 8250: Create serial_lsr_in()
Yang Yingliang yangyingliang@huawei.com serial: pic32: fix missing clk_disable_unprepare() on error in pic32_uart_startup()
Miaoqian Lin linmq006@gmail.com ASoC: mediatek: mt8173-rt5650: Fix refcount leak in mt8173_rt5650_dev_probe
Jiasheng Jiang jiasheng@iscas.ac.cn ASoC: codecs: da7210: add check for i2c_add_driver
Miaoqian Lin linmq006@gmail.com ASoC: mt6797-mt6351: Fix refcount leak in mt6797_mt6351_dev_probe
Randy Dunlap rdunlap@infradead.org ASoC: max98390: use linux/gpio/consumer.h to fix build
Miaoqian Lin linmq006@gmail.com ASoC: mediatek: mt8173: Fix refcount leak in mt8173_rt5650_rt5676_dev_probe
Fabio Estevam festevam@gmail.com ASoC: imx-audmux: Silence a clang warning
Miaoqian Lin linmq006@gmail.com ASoC: samsung: Fix error handling in aries_audio_probe
Miaoqian Lin linmq006@gmail.com ASoC: cros_ec_codec: Fix refcount leak in cros_ec_codec_platform_probe
Tang Bin tangbin@cmss.chinamobile.com opp: Fix error check in dev_pm_opp_attach_genpd()
Nathan Chancellor nathan@kernel.org usb: cdns3: Don't use priv_dev uninitialized in cdns3_gadget_ep_enable()
Zhihao Cheng chengzhihao1@huawei.com jbd2: fix assertion 'jh->b_frozen_data == NULL' failure when journal aborted
Li Lingfeng lilingfeng3@huawei.com ext4: recover csum seed of tmp_inode after migrating to extents
Zhang Yi yi.zhang@huawei.com jbd2: fix outstanding credits assert in jbd2_journal_commit_transaction()
Keith Busch kbusch@kernel.org block: ensure iov_iter advances for added pages
Keith Busch kbusch@kernel.org block/bio: remove duplicate append pages code
Christoph Hellwig hch@lst.de nvme: catch -ENODEV from nvme_revalidate_zones again
Nick Bowler nbowler@draconx.ca nvme: define compat_ioctl again to unbreak 32-bit userspace.
Bean Huo beanhuo@micron.com nvme: use command_id instead of req->tag in trace_nvme_complete_rq()
Christoph Hellwig hch@lst.de mtip32xx: fix device removal
Yu Kuai yukuai3@huawei.com nbd: add missing definition of pr_fmt
Dan Carpenter dan.carpenter@oracle.com null_blk: fix ida error handling in null_add_dev()
Md Haris Iqbal haris.iqbal@ionos.com block/rnbd-srv: Set keep_id to true after mutex_trylock
Zhu Yanjun yanjun.zhu@linux.dev RDMA/rxe: Fix error unwind in rxe_create_qp()
Maor Gottlieb maorg@nvidia.com RDMA/mlx5: Add missing check for return value in get namespace flow
Xu Qiang xuqiang36@huawei.com of/fdt: declared return type does not match actual return type
Andrei Vagin avagin@google.com selftests: kvm: set rax before vmcall
Juergen Gross jgross@suse.com xen: don't require virtio with grants for non-PV guests
Juergen Gross jgross@suse.com virtio: replace restricted mem access flag with callback
Andreas Schwab schwab@suse.de rtla: Fix double free
Daniel Bristot de Oliveira bristot@kernel.org rtla: Fix Makefile when called from -C tools/
Dan Carpenter dan.carpenter@oracle.com selftest/vm: uninitialized variable in main()
Dan Carpenter dan.carpenter@oracle.com tools/testing/selftests/vm/hugetlb-madvise.c: silence uninitialized variable warning
Adam Sindelar adam@wowsignal.io selftests/vm: fix errno handling in mrelease_test
Miaohe Lin linmiaohe@huawei.com mm/mmap.c: fix missing call to vm_unacct_memory in mmap_region
Liam R. Howlett Liam.Howlett@oracle.com android: binder: stop saving a pointer to the VMA
Bart Van Assche bvanassche@acm.org RDMA/srpt: Fix a use-after-free
Bart Van Assche bvanassche@acm.org RDMA/srpt: Introduce a reference count in struct srpt_device
Bart Van Assche bvanassche@acm.org RDMA/srpt: Duplicate port name members
Dan Carpenter dan.carpenter@oracle.com platform/olpc: Fix uninitialized data in debugfs write
Vadim Pasternak vadimp@nvidia.com platform/mellanox: mlxreg-lc: Fix error flow and extend verbosity
Hans de Goede hdegoede@redhat.com platform/x86: pmc_atom: Match all Lex BayTrail boards with critclk_systems DMI table
Dan Carpenter dan.carpenter@oracle.com tools/power/x86/intel-speed-select: Fix off by one check
Sean Christopherson seanjc@google.com KVM: nVMX: Set UMIP bit CR4_FIXED1 MSR when emulating UMIP
Peter Suti peter.suti@streamunlimited.com staging: fbtft: core: set smem_len before fb_deferred_io_init call
Patrice Chotard patrice.chotard@foss.st.com mtd: spi-nor: fix spi_nor_spimem_setup_op() call in spi_nor_erase_{sector,chip}()
Andrey Strachuk strochuk@ispras.ru usb: cdns3: change place of 'priv_ep' assignment in cdns3_gadget_ep_dequeue(), cdns3_gadget_ep_enable()
Alexey Sheplyakov asheplyakov@basealt.ru usb: xhci_plat_remove: avoid NULL dereference
Johan Hovold johan@kernel.org USB: serial: fix tty-port initialized comments
Basavaraj Natikar Basavaraj.Natikar@amd.com HID: amd_sfh: Handle condition of "no sensors"
Vidya Sagar vidyas@nvidia.com PCI: tegra194: Fix link up retry sequence
Vidya Sagar vidyas@nvidia.com PCI: tegra194: Fix Root Port interrupt handling
Bob Pearson rpearsonhpe@gmail.com RDMA/rxe: Fix rnr retry behavior
Md Haris Iqbal haris.phnx@gmail.com RDMA/rxe: For invalidate compare according to set keys in mr
Artem Borisov dedsa2002@gmail.com HID: alps: Declare U1_UNICORN_LEGACY support
Liang He windhl@126.com mmc: cavium-thunderx: Add of_node_put() when breaking out of loop
Liang He windhl@126.com mmc: cavium-octeon: Add of_node_put() when breaking out of loop
Liang He windhl@126.com mmc: core: quirks: Add of_node_put() when breaking out of loop
Bob Pearson rpearsonhpe@gmail.com RDMA/rxe: Fix mw bind to allow any consumer key portion
Antonio Borneo antonio.borneo@foss.st.com scripts/gdb: fix 'lx-dmesg' on 32 bits arch
Fabio Estevam festevam@denx.de dmaengine: imx-dma: Cast of_device_get_match_data() with (uintptr_t)
Basavaraj Natikar Basavaraj.Natikar@amd.com HID: amd_sfh: Add NULL check for hid device
Harshit Mogalapalli harshit.m.mogalapalli@oracle.com HID: mcp2221: prevent a buffer overflow in mcp_smbus_write()
Dan Carpenter dan.carpenter@oracle.com iio: adc: max1027: unlock on error path in max1027_read_single_value()
Liang He windhl@126.com gpio: gpiolib-of: Fix refcount bugs in of_mm_gpiochip_add_data()
Jianglei Nie niejianglei2021@163.com RDMA/hfi1: fix potential memory leak in setup_base_ctxt()
Bryan O'Donoghue bryan.odonoghue@linaro.org clk: qcom: gcc-msm8939: Fix weird field spacing in ftbl_gcc_camss_cci_clk
Bjorn Andersson bjorn.andersson@linaro.org clk: qcom: gdsc: Bump parent usage count when GDSC is found enabled
Abel Vesa abel.vesa@linaro.org clk: qcom: Drop mmcx gdsc supply for dispcc and videocc
Gwendal Grignou gwendal@chromium.org iio: cros: Register FIFO callback after sensor is registered
Zhu Yanjun yanjun.zhu@linux.dev RDMA/rxe: Fix BUG: KASAN: null-ptr-deref in rxe_qp_do_cleanup
Cheng Xu chengyou@linux.alibaba.com RDMA/siw: Fix duplicated reported IW_CM_EVENT_CONNECT_REPLY event
Haoyue Xu xuhaoyue1@hisilicon.com RDMA/hns: Fix incorrect clearing of interrupt status register
Jianglei Nie niejianglei2021@163.com RDMA/qedr: Fix potential memory leak in __qedr_alloc_mr()
Md Haris Iqbal haris.iqbal@ionos.com RDMA/rtrs-clt: Replace list_next_or_null_rr_rcu with an inline function
Jack Wang jinpu.wang@ionos.com RDMA/rtrs-srv: Fix modinfo output for stringify
Mustafa Ismail mustafa.ismail@intel.com RDMA/irdma: Fix setting of QP context err_rq_idx_valid field
Mustafa Ismail mustafa.ismail@intel.com RDMA/irdma: Fix VLAN connection with wildcard address
Mustafa Ismail mustafa.ismail@intel.com RDMA/irdma: Fix a window for use-after-free
Patrick Wang patrick.wang.shcn@gmail.com mm: percpu: use kmemleak_ignore_phys() instead of kmemleak_free()
Christopher Obbard chris.obbard@collabora.com um: random: Don't initialise hwrng struct with zero
Kalesh Singh kaleshsingh@google.com KVM: arm64: Fix hypervisor address symbolization
Peng Fan peng.fan@nxp.com interconnect: imx: fix max_node_id
Samuel Holland samuel@sholland.org phy: rockchip-inno-usb2: Ignore OTG IRQs in host mode
Fabrice Gasnier fabrice.gasnier@foss.st.com phy: stm32: fix error return in stm32_usbphyc_phy_init
Dan Carpenter dan.carpenter@oracle.com eeprom: idt_89hpesx: uninitialized data in idt_dbgfs_csr_write()
Johan Hovold johan+linaro@kernel.org usb: dwc3: qcom: fix missing optional irq warnings
Rohith Kollalsi quic_rkollals@quicinc.com usb: dwc3: core: Do not perform GCTL_CORE_SOFTRESET during bootup
Thinh Nguyen Thinh.Nguyen@synopsys.com usb: dwc3: core: Deprecate GCTL.CORESOFTRESET
Liang He windhl@126.com usb: aspeed-vhub: Fix refcount leak bug in ast_vhub_init_desc()
Randy Dunlap rdunlap@infradead.org usb: gadget: udc: amd5536 depends on HAS_DMA
Yang Yingliang yangyingliang@huawei.com xtensa: iss: fix handling error cases in iss_net_configure()
Max Filippov jcmvbkbc@gmail.com xtensa: iss/network: provide release() callback
Mahesh Rajashekhara Mahesh.Rajashekhara@microchip.com scsi: smartpqi: Fix DMA direction for RAID requests
Christian Marangi ansuelsmth@gmail.com PCI: qcom: Set up rev 2.1.0 PARF_PHY before enabling clocks
Stefan Roese sr@denx.de PCI/portdrv: Don't disable AER reporting in get_port_device_capability()
Claudio Imbrenda imbrenda@linux.ibm.com KVM: s390: pv: leak the topmost page table when destroy fails
Christian Loehle CLoehle@hyperstone.com mmc: block: Add single read for 4k sector cards
Liang He windhl@126.com of: device: Fix missing of_node_put() in of_dma_set_restricted_buffer
Eugen Hristev eugen.hristev@microchip.com mmc: sdhci-of-at91: fix set_uhs_signaling rewriting of MC1R
Christophe JAILLET christophe.jaillet@wanadoo.fr memstick/ms_block: Fix a memory leak
Christophe JAILLET christophe.jaillet@wanadoo.fr memstick/ms_block: Fix some incorrect memory allocation
Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com mmc: renesas_sdhi: Get the reset handle early in the probe
Fabio Estevam festevam@gmail.com mmc: mxcmmc: Silence a clang warning
Miaoqian Lin linmq006@gmail.com mmc: sdhci-of-esdhc: Fix refcount leak in esdhc_signal_voltage_switch
Bhupesh Sharma bhupesh.sharma@linaro.org dt-bindings: mmc: sdhci-msm: Fix issues in yaml bindings
Dan Carpenter dan.carpenter@oracle.com habanalabs: fix double unlock on error in map_device_va()
jianchunfu jianchunfu@cmss.chinamobile.com rtla/utils: Use calloc and check the potential memory allocation failure
Duoming Zhou duoming@zju.edu.cn staging: rtl8192u: Fix sleep in atomic context bug in dm_fsync_timer_callback
Carlos Llamas cmllamas@google.com binder: fix redefinition of seq_file attributes
Alexander Shishkin alexander.shishkin@linux.intel.com intel_th: msu: Fix vmalloced buffers
Jiasheng Jiang jiasheng@iscas.ac.cn intel_th: msu-sink: Potential dereference of null pointer
Christophe JAILLET christophe.jaillet@wanadoo.fr intel_th: Fix a resource leak in an error handling path
James Smart jsmart2021@gmail.com scsi: lpfc: Revert RSCN_MEMENTO workaround for misbehaved configuration
Bart Van Assche bvanassche@acm.org scsi: sd: Rework asynchronous resume support
Dan Carpenter dan.carpenter@oracle.com scsi: qla2xxx: Check correct variable in qla24xx_async_gffid()
Dmitry Baryshkov dmitry.baryshkov@linaro.org phy: qcom-qmp: fix the QSERDES_V5_COM_CMN_MODE register
Shunsuke Mie mie@igel.co.jp PCI: endpoint: Don't stop controller when unbinding endpoint function
Viacheslav Mitrofanov v.v.mitrofanov@yadro.com dmaengine: sf-pdma: Add multithread support for a DMA channel
Quentin Perret qperret@google.com KVM: arm64: Don't return from void function
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com soundwire: revisit driver bind/unbind and callbacks
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com soundwire: bus_type: fix remove and shutdown support
Serge Semin Sergey.Semin@baikalelectronics.ru PCI: dwc: Always enable CDM check if "snps,enable-cdm-check" exists
Serge Semin Sergey.Semin@baikalelectronics.ru PCI: dwc: Deallocate EPC memory on dw_pcie_ep_init() errors
Serge Semin Sergey.Semin@baikalelectronics.ru PCI: dwc: Set INCREASE_REGION_SIZE flag based on limit address
Serge Semin Sergey.Semin@baikalelectronics.ru PCI: dwc: Disable outbound windows only for controllers using iATU
Serge Semin Sergey.Semin@baikalelectronics.ru PCI: dwc: Add unroll iATU space support to dw_pcie_disable_atu()
Serge Semin Sergey.Semin@baikalelectronics.ru PCI: dwc: Stop link on host_init errors and de-initialization
Peter Geis pgwipeout@gmail.com phy: rockchip-inno-usb2: Sync initial otg state
Andy Shevchenko andriy.shevchenko@linux.intel.com phy: ti: tusb1210: Don't check for write errors when powering on
Tianyu Li tianyu.li@arm.com mm/mempolicy: fix get_nodes out of bound access
Andrey Konovalov andreyknvl@gmail.com kasan: fix zeroing vmalloc memory with HW_TAGS
Miaohe Lin linmiaohe@huawei.com mm/migration: fix potential pte_unmap on an not mapped pte
Miaohe Lin linmiaohe@huawei.com mm/migration: return errno when isolate_huge_page failed
Yang Shi shy828301@gmail.com mm: rmap: use the correct parameter name for DEFINE_PAGE_VMA_WALK
Yushan Zhou katrinzhou@tencent.com kernfs: fix potential NULL dereference in __kernfs_remove
Nikita Travkin nikita@trvn.ru clk: qcom: clk-rcg2: Make sure to not write d=0 to the NMD register
Nikita Travkin nikita@trvn.ru clk: qcom: clk-rcg2: Fail Duty-Cycle configuration if MND divider is not enabled.
Vladimir Zapolskiy vladimir.zapolskiy@linaro.org clk: qcom: camcc-sm8250: Fix topology around titan_top power domain
Vladimir Zapolskiy vladimir.zapolskiy@linaro.org clk: qcom: camcc-sdm845: Fix topology around titan_top power domain
Robert Marko robimarko@gmail.com clk: qcom: ipq8074: set BRANCH_HALT_DELAY flag for UBI clocks
Robert Marko robimarko@gmail.com clk: qcom: ipq8074: fix NSS port frequency tables
Robert Marko robimarko@gmail.com clk: qcom: ipq8074: SW workaround for UBI32 PLL lock
Robert Marko robimarko@gmail.com clk: qcom: ipq8074: fix NSS core PLL-s
Bob Pearson rpearsonhpe@gmail.com RDMA/rxe: Fix deadlock in rxe_do_local_ops()
Bob Pearson rpearsonhpe@gmail.com RDMA/rxe: Add a responder state for atomic reply
Sergey Shtylyov s.shtylyov@omp.ru usb: host: xhci: use snprintf() in xhci_decode_trb()
Bryan O'Donoghue bryan.odonoghue@linaro.org clk: qcom: gcc-msm8939: Point MM peripherals to system_mm_noc clock
Bryan O'Donoghue bryan.odonoghue@linaro.org clk: qcom: gcc-msm8939: Add missing system_mm_noc_bfdcd_clk_src
Bryan O'Donoghue bryan.odonoghue@linaro.org clk: qcom: gcc-msm8939: Fix bimc_ddr_clk_src rcgr base address
Bryan O'Donoghue bryan.odonoghue@linaro.org clk: qcom: gcc-msm8939: Add missing SYSTEM_MM_NOC_BFDCD_CLK_SRC
Neal Liu neal_liu@aspeedtech.com usb: gadget: f_mass_storage: Make CD-ROM emulation works with Windows OS
Mike Leach mike.leach@linaro.org coresight: syscfg: Update load and unload operations
Mike Leach mike.leach@linaro.org coresight: configfs: Fix unload of configurations on module exit
Christian Marangi ansuelsmth@gmail.com clk: qcom: clk-krait: unlock spin after mux completion
Zhang Wensheng zhangwensheng5@huawei.com driver core: fix potential deadlock in __driver_attach
Christophe JAILLET christophe.jaillet@wanadoo.fr misc: rtsx: Fix an error handling path in rtsx_pci_probe()
Vladimir Zapolskiy vladimir.zapolskiy@linaro.org clk: qcom: camcc-sm8250: Fix halt on boot by reducing driver's init level
Mark Brown broonie@kernel.org mtd: dataflash: Add SPI ID table
Geert Uytterhoeven geert+renesas@glider.be mtd: hyperbus: rpc-if: Fix RPM imbalance in probe error path
Ben Gardon bgardon@google.com KVM: x86: Fix errant brace in KVM capability handling
Serge Semin Sergey.Semin@baikalelectronics.ru dmaengine: dw-edma: Fix eDMA Rd/Wr-channels and DMA-direction semantics
Mike Christie michael.christie@oracle.com scsi: iscsi: Fix session removal on shutdown
Mike Christie michael.christie@oracle.com scsi: iscsi: Add helper to remove a session from the kernel
Mike Christie michael.christie@oracle.com scsi: iscsi: Allow iscsi_if_stop_conn() to be called from kernel
Duoming Zhou duoming@zju.edu.cn mwifiex: fix sleep in atomic context bugs caused by dev_coredumpv
Duoming Zhou duoming@zju.edu.cn devcoredump: remove the useless gfp_t parameter in dev_coredumpv and dev_coredumpm
Sean Christopherson seanjc@google.com KVM: selftests: Use vm_create_with_vcpus() in max_guest_memory_test
Sean Christopherson seanjc@google.com KVM: selftests: Convert s390x/diag318_test_handler away from VCPU_ID
Sean Christopherson seanjc@google.com KVM: Don't set Accessed/Dirty bits for ZERO_PAGE
Miaohe Lin linmiaohe@huawei.com mm/memremap: fix memunmap_pages() race with get_dev_pagemap()
Miaohe Lin linmiaohe@huawei.com lib/test_hmm: avoid accessing uninitialized pages
Dongliang Mu mudongliangabcd@gmail.com RDMA/rxe: fix xa_alloc_cycle() error return value check again
Peng Fan peng.fan@nxp.com clk: imx: clk-fracn-gppll: correct rdiv
Liu Ying victor.liu@nxp.com clk: imx: clk-fracn-gppll: Return rate in rate table properly in ->recalc_rate()
Peng Fan peng.fan@nxp.com clk: imx: clk-fracn-gppll: fix mfd value
Peng Fan peng.fan@nxp.com clk: imx93: correct nic_media parent
Haibo Chen haibo.chen@nxp.com clk: imx93: use adc_root as the parent clock of adc1
Rex-BC Chen rex-bc.chen@mediatek.com clk: mediatek: reset: Fix written reset bit offset
Jonathan Cameron Jonathan.Cameron@huawei.com iio: temp: maxim_thermocouple: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: temp: max31865: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: temp: ltc2983: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: resolver: ad2s90: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: resolver: ad2s1200: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: proximity: as3935: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: potentiometer: mcp4131: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: potentiometer: mcp41010: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: potentiometer: max5481: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: potentiometer: ad5272: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: potentiometer: ad5110: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: imu: mpu6050: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: imu: inv_icm42600: Fix alignment for DMA safety in buffer code.
Jonathan Cameron Jonathan.Cameron@huawei.com iio: imu: inv_icm42600: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: imu: fxos8700: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: gyro: fxas210002c: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: gyro: adxrs450: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: gyro: adis16130: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: gyro: adis16080: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: frequency: adrf6780: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: frequency: admv4420: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: frequency: admv1014: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: frequency: admv1013: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: frequency: adf4371: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: frequency: adf4350: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: frequency: ad9523: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ti-dac7612: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ti-dac7311: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ti-dac5571: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ti-dac082s085: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: mcp4922: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ltc2688: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad8801: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad7303: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad7293: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5791: Fix alignment for DMA saftey
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5770r: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5766: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5764: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5761: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5755: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5686: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5592r: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5504: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5449: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5421: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5360: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: dac: ad5064: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: common: ssp: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: amplifiers: ad8366: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: addac: ad74413r: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-tlc4541: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-ads8688: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-ads8344: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-ads7950: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-ads131e08: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-ads124s08: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-adc161s626: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-adc128s052: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-adc12138: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-adc108s102: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-adc084s021: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ti-adc0832: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: mcp320x: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: max1241: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: max1118: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: max11100: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: max1027: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ltc2497: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ltc2496: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: hi8435: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7949: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7923: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7887: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7768-1: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7766: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7606: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7476: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7298: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7292: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7280a: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7266: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: accel: sca3300: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: accel: sca3000: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: accel: bma220: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: accel: adxl367: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: accel: adxl355: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: accel: adxl313: Fix alignment for DMA safety
Jonathan Cameron Jonathan.Cameron@huawei.com iio: core: Fix IIO_ALIGN and rename as it was not sufficiently large
Jagath Jog J jagathjog1996@gmail.com iio: accel: bma400: Add triggered buffer support
Jagath Jog J jagathjog1996@gmail.com iio: accel: bma400: conversion to device-managed function
Jagath Jog J jagathjog1996@gmail.com iio: accel: bma400: Reordering of header files
Gwendal Grignou gwendal@chromium.org iio: sx9324: Fix register field spelling
Stephen Boyd swboyd@chromium.org platform/chrome: cros_ec: Always expose last resume result
Jagath Jog J jagathjog1996@gmail.com iio: accel: bma400: Fix the scale min and max macro values
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Reduce N2N thrashing at app_start time
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Fix no logout on delete for N2N
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Fix session thrash
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Tear down session if keys have been removed
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Fix no login after app start
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Reduce disruption due to multiple app start
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Send LOGO for unexpected IKE message
Thomas Gleixner tglx@linutronix.de netfilter: xtables: Bring SPDX identifier back
Miquel Raynal miquel.raynal@bootlin.com dmaengine: dw: dmamux: Fix build without CONFIG_OF
Miquel Raynal miquel.raynal@bootlin.com dmaengine: dw: dmamux: Export the module device table
Tang Bin tangbin@cmss.chinamobile.com usb: xhci: tegra: Fix error check
Clément Léger clement.leger@bootlin.com usb: host: ohci-at91: add support to enter suspend using SMC
Dan Carpenter dan.carpenter@oracle.com usbip: vudc: Don't enable IRQs prematurely
Tang Bin tangbin@cmss.chinamobile.com usb: gadget: tegra-xudc: Fix error check in tegra_xudc_powerdomain_init()
Miaoqian Lin linmq006@gmail.com usb: ohci-nxp: Fix refcount leak in ohci_hcd_nxp_probe
Laurent Pinchart laurent.pinchart@ideasonboard.com usb: gadget: uvc: Fix comment blocks style
Frank Li Frank.Li@nxp.com usb: cdns3: fix random warning message when driver load
Miaoqian Lin linmq006@gmail.com usb: host: Fix refcount leak in ehci_hcd_ppc_of_probe
Marco Pagani marpagan@redhat.com fpga: altera-pr-ip: fix unsigned comparison with less than zero
Miaoqian Lin linmq006@gmail.com PCI: mediatek-gen3: Fix refcount leak in mtk_pcie_init_irq_domains()
Uwe Kleine-König u.kleine-koenig@pengutronix.de mtd: st_spi_fsm: Disable clock only after device was unregistered
Uwe Kleine-König u.kleine-koenig@pengutronix.de mtd: st_spi_fsm: Warn about failure to unregister mtd device
Uwe Kleine-König u.kleine-koenig@pengutronix.de mtd: spear_smi: Drop if with an always false condition
Uwe Kleine-König u.kleine-koenig@pengutronix.de mtd: st_spi_fsm: Add a clk_disable_unprepare() in .probe()'s error path
Uwe Kleine-König u.kleine-koenig@pengutronix.de mtd: spear_smi: Don't skip cleanup after mtd_device_unregister() failed
Miaoqian Lin linmq006@gmail.com mtd: parsers: ofpart: Fix refcount leak in bcm4908_partitions_fw_offset
Miaoqian Lin linmq006@gmail.com mtd: partitions: Fix refcount leak in parse_redboot_of
Duoming Zhou duoming@zju.edu.cn mtd: sm_ftl: Fix deadlock caused by cancel_work_sync in sm_release
Harshit Mogalapalli harshit.m.mogalapalli@oracle.com HID: cp2112: prevent a buffer overflow in cp2112_xfer()
Miaoqian Lin linmq006@gmail.com PCI: tegra194: Fix PM error handling in tegra_pcie_config_ep()
Miaoqian Lin linmq006@gmail.com PCI: microchip: Fix refcount leak in mc_pcie_init_irq_domains()
Chanho Park chanho61.park@samsung.com phy: samsung: exynosautov9-ufs: correct TSRV register configurations
Sean Christopherson seanjc@google.com KVM: x86/mmu: Drop RWX=0 SPTEs during ept_sync_page()
Sean Christopherson seanjc@google.com KVM: SVM: Stuff next_rip on emulated INT3 injection if NRIPS is supported
Sean Christopherson seanjc@google.com KVM: SVM: Unwind "speculative" RIP advancement if INTn injection "fails"
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Fix n2n login retry for secure device
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Fix n2n discovery issue with secure target
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Add retry for ELS passthrough
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Synchronize NPIV deletion with authentication application
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Fix potential stuck session in sa update
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Add bsg interface to read doorbell events
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Wait for app to ack on sess down
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: bsg refactor
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Reduce Initiator-Initiator thrashing
Vaibhav Jain vaibhav@linux.ibm.com of: check previous kernel's ima-kexec-buffer against memory bounds
Biju Das biju.das.jz@bp.renesas.com clk: renesas: rzg2l: Fix reset status function
Christophe JAILLET christophe.jaillet@wanadoo.fr mtd: rawnand: meson: Fix a potential double free issue
Miaoqian Lin linmq006@gmail.com mtd: maps: Fix refcount leak in ap_flash_init
Miaoqian Lin linmq006@gmail.com mtd: maps: Fix refcount leak in of_flash_probe_versatile
Ralph Siemsen ralph.siemsen@linaro.org clk: renesas: r9a06g032: Fix UART clkgrp bitsel
Mario Limonciello mario.limonciello@amd.com HID: amd_sfh: Don't show client init failed as error when discovery fails
Jason A. Donenfeld Jason@zx2c4.com wireguard: allowedips: don't corrupt stack when detecting overflow
Jason A. Donenfeld Jason@zx2c4.com wireguard: ratelimiter: use hrtimer in selftest
Maxim Mikityanskiy maximmi@nvidia.com net/mlx5e: xsk: Discard unaligned XSK frames on striding RQ
Maciej Żenczykowski maze@google.com net: usb: make USB_RTL8153_ECM non user configurable
Hangyu Hua hbh25y@gmail.com dccp: put dccp_qpolicy_full() and dccp_qpolicy_push() in the same lock
Jian Shen shenjian15@huawei.com net: ionic: fix error check for vlan flags in ionic_set_nic_features()
Jian Shen shenjian15@huawei.com net: ice: fix error NETIF_F_HW_VLAN_CTAG_FILTER check in ice_vsi_sync_fltr()
Eric Dumazet edumazet@google.com net: rose: fix netdev reference changes
Jakub Kicinski kuba@kernel.org netdevsim: Avoid allocation warnings triggered from user space
Przemyslaw Patynowski przemyslawx.patynowski@intel.com iavf: Fix 'tc qdisc show' listing too many queues
Przemyslaw Patynowski przemyslawx.patynowski@intel.com iavf: Fix max_rate limiting
William Dean williamsukatube@gmail.com wifi: rtw88: check the return value of alloc_workqueue()
Ido Schimmel idosch@nvidia.com netdevsim: fib: Fix reference count leak on route deletion failure
Mike Manning mvrmanning@gmail.com net: allow unbound socket for packets in VRF when tcp_l3mdev_accept set
Kai Ye yekai13@huawei.com crypto: hisilicon/sec - fix auth key size error
Pali Rohár pali@kernel.org crypto: inside-secure - Add missing MODULE_DEVICE_TABLE for of
Zhengchao Shao shaozhengchao@huawei.com crypto: hisilicon/hpre - don't use GFP_KERNEL to alloc mem during softirq
Eric Dumazet edumazet@google.com ax25: fix incorrect dev_tracker usage
Shay Drory shayd@nvidia.com net/mlx5: Fix driver use of uninitialized timeout
Yevgeny Kliteynik kliteyn@nvidia.com net/mlx5: DR, Fix SMFS steering info dump format
Maher Sanalla msanalla@nvidia.com net/mlx5: Adjust log_max_qp to be 18 at most
Vlad Buslov vladbu@nvidia.com net/mlx5e: Modify slow path rules to go to slow fdb
Maxim Mikityanskiy maximmi@nvidia.com net/mlx5e: Fix calculations related to max MPWQE size
Maxim Mikityanskiy maximmi@nvidia.com net/mlx5e: xsk: Account for XSK RQ UMRs when calculating ICOSQ size
Maxim Mikityanskiy maximmi@nvidia.com net/mlx5e: Fix the value of MLX5E_MAX_RQ_NUM_MTTS
Maor Dickman maord@nvidia.com net/mlx5e: TC, Fix post_act to not match on in_port metadata
Gal Pressman gal@nvidia.com net/mlx5e: Remove WARN_ON when trying to offload an unsupported TLS cipher/version
Dan Carpenter dan.carpenter@oracle.com drm/amd/display: fix signedness bug in execute_synaptics_rc_command()
Ezequiel Garcia ezequiel@vanguardiasur.com.ar hantro: Remove incorrect HEVC SPS validation
Jernej Skrabec jernej.skrabec@gmail.com media: cedrus: hevc: Add check for invalid timestamp
Hangyu Hua hbh25y@gmail.com wifi: libertas: Fix possible refcount leak in if_usb_probe()
Jose Ignacio Tornos Martinez jtornosm@redhat.com wifi: iwlwifi: mvm: fix double list_add at iwl_mvm_mac_wake_tx_queue
Ammar Faizi ammarfaizi2@gnuweeb.org wifi: wil6210: debugfs: fix uninitialized variable use in `wil_write_file_wmi()`
Manikanta Pubbisetty quic_mpubbise@quicinc.com wifi: ath11k: Fix register write failure on QCN9074
Liang He windhl@126.com i2c: mux-gpmux: Add of_node_put() when breaking out of loop
Joanne Koong joannelkoong@gmail.com bpf: Fix bpf_xdp_pointer return pointer
Paul Chaignon paul@isovalent.com bpf: Set flow flag to allow any source IP in bpf_tunnel_key
Paul Chaignon paul@isovalent.com ip_tunnels: Add new flow flags field to ip_tunnel_key
Qu Wenruo wqu@suse.com btrfs: update stripe_sectors::uptodate in steal_rbio
Bjorn Andersson bjorn.andersson@linaro.org i2c: qcom-geni: Use the correct return value
Lars-Peter Clausen lars@metafoo.de i2c: cadence: Support PEC for SMBus block read
Ying Hsu yinghsu@chromium.org Bluetooth: Add default wakeup callback for HCI UART driver
Luiz Augusto von Dentz luiz.von.dentz@intel.com Bluetooth: hci_sync: Fix not updating privacy_mode
Zhengping Jiang jiangzp@google.com Bluetooth: hci_sync: Fix resuming scan after suspend resume
Zhengping Jiang jiangzp@google.com Bluetooth: mgmt: Fix refresh cached connection info
Schspa Shi schspa@gmail.com Bluetooth: When HCI work queue is drained, only queue chained work
Jiasheng Jiang jiasheng@iscas.ac.cn Bluetooth: hci_intel: Add check for platform_driver_register
Vincent Mailhol mailhol.vincent@wanadoo.fr can: pch_can: pch_can_error(): initialize errc before using it
Dan Carpenter dan.carpenter@oracle.com libbpf: Fix str_has_sfx()'s return value
Vincent Mailhol mailhol.vincent@wanadoo.fr can: error: specify the values of data[5..7] of CAN error frames
Vincent Mailhol mailhol.vincent@wanadoo.fr can: usb_8dev: do not report txerr and rxerr during bus-off
Vincent Mailhol mailhol.vincent@wanadoo.fr can: kvaser_usb_leaf: do not report txerr and rxerr during bus-off
Vincent Mailhol mailhol.vincent@wanadoo.fr can: kvaser_usb_hydra: do not report txerr and rxerr during bus-off
Vincent Mailhol mailhol.vincent@wanadoo.fr can: sun4i_can: do not report txerr and rxerr during bus-off
Vincent Mailhol mailhol.vincent@wanadoo.fr can: hi311x: do not report txerr and rxerr during bus-off
Vincent Mailhol mailhol.vincent@wanadoo.fr can: sja1000: do not report txerr and rxerr during bus-off
Vincent Mailhol mailhol.vincent@wanadoo.fr can: rcar_can: do not report txerr and rxerr during bus-off
Vincent Mailhol mailhol.vincent@wanadoo.fr can: pch_can: do not report txerr and rxerr during bus-off
Dan Carpenter dan.carpenter@oracle.com libbpf: fix an snprintf() overflow check
Dan Carpenter dan.carpenter@oracle.com selftests/bpf: fix a test for snprintf() overflow
Andrii Nakryiko andrii@kernel.org libbpf: make RINGBUF map size adjustments more eagerly
Andrii Nakryiko andrii@kernel.org bpf: fix potential 32-bit overflow when accessing ARRAY map element
Alex Deucher alexander.deucher@amd.com drm/amdgpu: restore original stable pstate on ctx fini
Alex Deucher alexander.deucher@amd.com drm/amdgpu: use the same HDP flush registers for all nbio 2.3.x
Alex Deucher alexander.deucher@amd.com drm/amdgpu: use the same HDP flush registers for all nbio 7.4.x
Rustam Subkhankulov subkhankulov@ispras.ru wifi: p54: add missing parentheses in p54_flush()
Christophe JAILLET christophe.jaillet@wanadoo.fr wifi: p54: Fix an error handling path in p54spi_probe()
Dan Carpenter dan.carpenter@oracle.com wifi: wil6210: debugfs: fix info leak in wil_write_file_wmi()
Jernej Skrabec jernej.skrabec@gmail.com media: cedrus: h265: Fix logic for not low delay flag
Benjamin Gaignard benjamin.gaignard@collabora.com media: uapi: HEVC: Change pic_order_cnt definition in v4l2_hevc_dpb_entry
Jernej Skrabec jernej.skrabec@gmail.com media: cedrus: h265: Fix flag name
Jason A. Donenfeld Jason@zx2c4.com fs: check FMODE_LSEEK to control internal pipe splicing
Yang Yingliang yangyingliang@huawei.com media: ov7251: add missing disable functions on error in ov7251_set_power_on()
Sakari Ailus sakari.ailus@linux.intel.com media: v4l: async: Also match secondary fwnode endpoints
Johannes Berg johannes.berg@intel.com wifi: nl80211: acquire wdev mutex for dump_survey
Alexei Starovoitov ast@kernel.org bpf: Fix subprog names in stack traces.
Wolfram Sang wsa+renesas@sang-engineering.com selftests: timers: clocksource-switch: fix passing errors from child
Wolfram Sang wsa+renesas@sang-engineering.com selftests: timers: valid-adjtimex: build fix for newer toolchains
David Gow davidgow@google.com kunit: executor: Fix a memory leak on failure in kunit_filter_tests
Anquan Wu leiqi96@hotmail.com libbpf: Fix the name of a reused map
Yonglong Li liyonglong@chinatelecom.cn tcp: make retransmitted SKB fit into the send window
Song Liu song@kernel.org bpf, x86: fix freeing of not-finalized bpf_prog_pack
Tony Ambardar tony.ambardar@gmail.com bpf, x64: Add predicate for bpf2bpf with tailcalls support in JIT
Jian Zhang zhangjian210@huawei.com drm/exynos/exynos7_drm_decon: free resources when clk_set_parent() failed.
Liu Jian liujian56@huawei.com skmsg: Fix invalid last sg check in sk_msg_recvmsg()
Liang He windhl@126.com mediatek: mt76: eeprom: fix missing of_node_put() in mt76_find_power_limits_node()
Liang He windhl@126.com mediatek: mt76: mac80211: Fix missing of_node_put() in mt76_led_init()
Felix Fietkau nbd@nbd.name mt76: mt7615: fix throughput regression on DFS channels
Shayne Chen shayne.chen@mediatek.com mt76: mt7915: fix incorrect testmode ipg on band 1 caused by wmm_idx
Lorenzo Bianconi lorenzo@kernel.org mt76: connac: move connac2_mac_write_txwi in mt76_connac module
Lorenzo Bianconi lorenzo@kernel.org mt76: connac: move mac connac2 defs in mt76_connac2_mac.h
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7915: rely on mt76_dev in mt7915_mac_write_txwi signature
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7921: rely on mt76_dev in mt7921_mac_write_txwi signature
Deren Wu deren.wu@mediatek.com mt76: mt7921: enlarge maximum VHT MPDU length to 11454
Deren Wu deren.wu@mediatek.com mt76: mt7921: fix aggregation subframes setting to HE max
Deren Wu deren.wu@mediatek.com mt76: mt7921s: fix possible sdio deadlock in command fail
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7921: do not update pm states in case of error
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7615: do not update pm stats in case of error
Johannes Berg johannes.berg@intel.com wifi: mac80211: move some future per-link data to bss_conf
Johannes Berg johannes.berg@intel.com wifi: cfg80211: do some rework towards MLO link APIs
Johannes Berg johannes.berg@intel.com wifi: mac80211: reject WEP or pairwise keys with key ID > 3
Deren Wu deren.wu@mediatek.com mt76: mt7921: not support beacon offload disable command
YN Chen yn.chen@mediatek.com mt76: mt7921s: fix firmware download random fail
Dan Carpenter dan.carpenter@oracle.com mt76: mt7915: fix endian bug in mt7915_rf_regval_set()
Lorenzo Bianconi lorenzo@kernel.org mt76: mt76x02u: fix possible memory leak in __mt76x02u_mcu_send_msg
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7915: fix endianness in mt7915_rf_regval_get
Ming Qian ming.qian@nxp.com media: amphion: only insert the first sequence startcode for vc1l format
Ming Qian ming.qian@nxp.com media: amphion: sync buffer status with firmware during abort
Ezequiel Garcia ezequiel@vanguardiasur.com.ar media: hantro: Fix RK3399 H.264 format advertising
Benjamin Gaignard benjamin.gaignard@collabora.com media: hantro: Be more accurate on pixel formats step_width constraints
Ming Qian ming.qian@nxp.com media: amphion: defer setting last_buffer_dequeued until resolution changes are processed
Chen-Yu Tsai wenst@chromium.org media: mediatek: vcodec: Initialize decoder parameters for each instance
Chen-Yu Tsai wenst@chromium.org media: mediatek: vcodec: decoder: Drop max_{width,height} from mtk_vcodec_ctx
Chen-Yu Tsai wenst@chromium.org media: mediatek: vcodec: decoder: Skip alignment for default resolution
Chen-Yu Tsai wenst@chromium.org media: mediatek: vcodec: decoder: Fix resolution clamping in TRY_FMT
Chen-Yu Tsai wenst@chromium.org media: mediatek: vcodec: decoder: Fix 4K frame size enumeration
Hans de Goede hdegoede@redhat.com media: atomisp: revert "don't pass a pointer to a local variable"
Rob Clark robdclark@chromium.org drm/msm/dpu: Fix for non-visible planes
Ming Qian ming.qian@nxp.com media: amphion: release core lock before reset vpu core
AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com media: platform: mtk-mdp: Fix mdp_ipi_comm structure alignment
Zhengchao Shao shaozhengchao@huawei.com crypto: hisilicon - Kunpeng916 crypto driver don't sleep when in softirq
Zhengchao Shao shaozhengchao@huawei.com crypto: hisilicon/sec - don't sleep when in softirq
Mateusz Jończyk mat.jonczyk@o2.pl drm/radeon: avoid bogus "vram limit (0) must be a power of 2" warning
Rob Clark robdclark@chromium.org drm/msm/mdp5: Fix global state lock backoff
Yixun Lan dlan@gentoo.org libbpf, riscv: Use a0 for RC register
Douglas Anderson dianders@chromium.org drm/msm: Avoid unclocked GMU register access in 6xx gpu_busy
Hsin-Yi Wang hsinyi@chromium.org drm/bridge: anx7625: Fix NULL pointer crash when using edp-panel
Qiao Ma mqaio@linux.alibaba.com net: hinic: avoid kernel hung in hinic_get_stats64()
Qiao Ma mqaio@linux.alibaba.com net: hinic: fix bug that ethtool get wrong stats
Christophe JAILLET christophe.jaillet@wanadoo.fr hinic: Use the bitmap API when applicable
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: felix: build as module when tc-taprio is module
Vladimir Oltean vladimir.oltean@nxp.com net: sched: provide shim definitions for taprio_offload_{get,free}
Rob Clark robdclark@chromium.org drm/msm: Fix fence rollover issue
Hangyu Hua hbh25y@gmail.com drm: bridge: sii8620: fix possible off-by-one
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/hdmi: fill the pwr_regs bulk regulators
Abhinav Kumar quic_abhinavk@quicinc.com drm/msm/dpu: remove hard-coded linewidth limit for writeback
Abhinav Kumar quic_abhinavk@quicinc.com drm/msm/dpu: fix maxlinewidth for writeback block
Abhinav Kumar quic_abhinavk@quicinc.com drm/msm/dpu: move intf and wb assignment to dpu_encoder_setup_display()
Guillaume Ranquet granquet@baylibre.com drm/mediatek: dpi: Only enable dpi after the bridge is enabled
Bo-Chen Chen rex-bc.chen@mediatek.com drm/mediatek: dpi: Remove output format of YUV
Christophe JAILLET christophe.jaillet@wanadoo.fr drm/rockchip: Fix an error handling path rockchip_dp_probe()
Brian Norris briannorris@chromium.org drm/rockchip: vop: Don't crash for invalid duplicate_state()
Alaa Mohamed eng.alaamohamedsoliman.am@gmail.com selftests: net: fib_rule_tests: fix support for running individual tests
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: felix: drop oversized frames with tc-taprio instead of hanging the port
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: felix: keep reference on entire tc-taprio config
Xiaoliang Yang xiaoliang.yang_1@nxp.com net: dsa: felix: update base time of time-aware shaper when adjusting PTP time
Maciej Fijalkowski maciej.fijalkowski@intel.com selftests/xsk: Destroy BPF resources only when ctx refcount drops to 0
Qian Cai quic_qiancai@quicinc.com crypto: arm64/gcm - Select AEAD for GHASH_ARM64_CE
Matthew Wilcox (Oracle) willy@infradead.org mm: Account dirty folios properly during splits
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: hdmi: Move pixel doubling from Pixelvalve to HDMI block
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: hdmi: Correct HDMI timing registers for interlaced modes
Dom Cobley popcornmix@gmail.com drm/vc4: hdmi: Force modeset when bpc or format changes
Mateusz Kwiatkowski kfyatek+publicgit@gmail.com drm/vc4: hdmi: Fix timings for interlaced modes
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: hdmi: Move HDMI reset to pm_resume
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: hdmi: Switch to pm_runtime_status_suspended
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: hdmi: Reset HDMI MISC_CONTROL register
Dom Cobley popcornmix@gmail.com drm/vc4: hdmi: Avoid full hdmi audio fifo writes
Dom Cobley popcornmix@gmail.com drm/vc4: hdmi: Clear unused infoframe packet RAM registers
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: hdmi: Add all the vc5 HDMI registers into the debugfs dumps
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: dsi: Add correct stop condition to vc4_dsi_encoder_disable iteration
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: dsi: Fix dsi0 interrupt support
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: dsi: Register dsi0 as the correct vc4 encoder type
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: dsi: Correct pixel order for DSI0
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: dsi: Correct DSI divider calculations
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: dsi: Release workaround buffer and DMA
Dave Stevenson dave.stevenson@raspberrypi.com drm/vc4: plane: Fix margin calculations for the right/bottom edges
Dom Cobley popcornmix@gmail.com drm/vc4: plane: Remove subpixel positioning check
Maxime Ripard maxime@cerno.tech drm/vc4: kms: Use maximum FIFO load for the HVS clock rate
Yunfei Dong yunfei.dong@mediatek.com media: mediatek: vcodec: Fix non subdev architecture open power fail
Miaoqian Lin linmq006@gmail.com media: tw686x: Fix memory leak in tw686x_video_init
Jian Zhang zhangjian210@huawei.com media: driver/nxp/imx-jpeg: fix a unexpected return value problem
Chen-Yu Tsai wenst@chromium.org media: mediatek: vcodec: Skip SOURCE_CHANGE & EOS events for stateless
Yunfei Dong yunfei.dong@mediatek.com media: mediatek: vcodec: Initialize decoder parameters after getting dec_capability
Arnd Bergmann arnd@arndb.de media: sta2x11: remove VIRT_TO_BUS dependency
Ming Qian ming.qian@nxp.com media: v4l2-mem2mem: prevent pollerr when last_buffer_dequeued is set
Niels Dossche dossche.niels@gmail.com media: hdpvr: fix error value returns in hdpvr_read
Miaoqian Lin linmq006@gmail.com drm/mcde: Fix refcount leak in mcde_dsi_bind
Ming Qian ming.qian@nxp.com media: amphion: output firmware error message
Ming Qian ming.qian@nxp.com media: imx-jpeg: Disable slot interrupt when frame done
Jiasheng Jiang jiasheng@iscas.ac.cn drm: bridge: adv7511: Add check for mipi_dsi_driver_register
Tom Lendacky thomas.lendacky@amd.com crypto: ccp - During shutdown, check SEV data pointer before using
Jörn-Thorben Hinz jthinz@mailbox.tu-berlin.de selftests/bpf: Fix rare segfault in sock_fields prog test
YueHaibing yuehaibing@huawei.com drm/display: Fix build error without CONFIG_OF
Jian Shen shenjian15@huawei.com test_bpf: fix incorrect netdev features
Frederic Weisbecker frederic@kernel.org rcutorture: Fix ksoftirqd boosting timing and iteration
Paul E. McKenney paulmck@kernel.org torture: Adjust to again produce debugging information
Yifan Zhang yifan1.zhang@amd.com drm/amdkfd: correct sdma queue number of sdma 6.0.1
Mario Limonciello mario.limonciello@amd.com drm/amd: Don't show warning on reading vbios values for SMU13 3.1
Alex Deucher alexander.deucher@amd.com drm/radeon: fix incorrrect SPDX-License-Identifiers
Ping-Ke Shih pkshih@realtek.com wifi: rtw89: 8852a: rfk: fix div 0 exception
Alexey Kodanev aleksei.kodanev@bell-sw.com wifi: iwlegacy: 4965: fix potential off-by-one overflow in il4965_rs_fill_link_cmd()
Johannes Berg johannes.berg@intel.com wifi: mac80211: set STA deflink addresses
Pavel Skripkin paskripkin@gmail.com ath9k: fix use-after-free in ath9k_hif_usb_rx_cb
Niklas Söderlund niklas.soderlund+renesas@ragnatech.se media: rcar-vin: Fix channel routing for Ebisu
Ming Qian ming.qian@nxp.com media: imx-jpeg: Implement drain using v4l2-mem2mem helpers
Ming Qian ming.qian@nxp.com media: imx-jpeg: Align upwards buffer size
Ming Qian ming.qian@nxp.com media: imx-jpeg: Leave a blank space before the configuration data
Ming Qian ming.qian@nxp.com media: imx-jpeg: Correct some definition according specification
Benjamin Gaignard benjamin.gaignard@collabora.com media: Hantro: Correct G2 init qp field
Ming Qian ming.qian@nxp.com media: amphion: return error if format is unsupported by vpu
Zheyu Ma zheyuma97@gmail.com media: tw686x: Register the irq at the end of probe
Yang Yingliang yangyingliang@huawei.com media: camss: csid: fix wrong size passed to devm_kmalloc_array()
Eugen Hristev eugen.hristev@microchip.com media: atmel: atmel-sama7g5-isc: fix warning in configs without OF
Kuniyuki Iwashima kuniyu@amazon.com raw: Fix mixed declarations error in raw_icmp_error().
Eric Dumazet edumazet@google.com raw: convert raw sockets to RCU
Eric Dumazet edumazet@google.com raw: use more conventional iterators
Eric Dumazet edumazet@google.com ping: convert to RCU lookups, get rid of rwlock
Oleksij Rempel linux@rempel-privat.de net: ag71xx: fix discards 'const' qualifier warning
Alexey Khoroshilov khoroshilov@ispras.ru crypto: sun8i-ss - fix infinite loop in sun8i_ss_setup_ivs()
Eric Dumazet edumazet@google.com tcp: fix possible freeze in tx path under memory pressure
Andrii Nakryiko andrii@kernel.org selftests/bpf: Don't force lld on non-x86 architectures
Andrii Nakryiko andrii@kernel.org libbpf: Fix internal USDT address translation logic for shared libraries
Xu Wang vulab@iscas.ac.cn i2c: Fix a potential use after free
Zheng Bin zhengbin13@huawei.com drm/bridge: it6505: Add missing CRYPTO_HASH dependency
Nícolas F. R. A. Prado nfraprado@collabora.com drm/bridge: anx7625: Zero error variable when panel bridge not present
Marc Kleine-Budde mkl@pengutronix.de can: netlink: allow configuring of fixed data bit rates without need for do_set_data_bittiming callback
Tales Lelo da Aparecida tales.aparecida@gmail.com drm/vkms: check plane_composer->map[0] before using it
Marc Kleine-Budde mkl@pengutronix.de can: netlink: allow configuring of fixed bit rates without need for do_set_bittiming callback
Eric Dumazet edumazet@google.com net: fix sk_wmem_schedule() and sk_rmem_schedule() errors
Peng Wu wupeng58@huawei.com crypto: sun8i-ss - fix a NULL vs IS_ERR() check in sun8i_ss_hashkey
Dan Carpenter dan.carpenter@oracle.com crypto: sun8i-ss - Fix error codes for dma_mapping_error()
Dan Carpenter dan.carpenter@oracle.com crypto: sun8i-ss - fix error codes in allocate_flows()
Antonio Borneo antonio.borneo@foss.st.com drm: adv7511: override i2c address of cec before accessing it
Andrii Nakryiko andrii@kernel.org libbpf: Fix uprobe symbol file offset calculation logic
Miaoqian Lin linmq006@gmail.com drm/virtio: Fix NULL vs IS_ERR checking in virtio_gpu_object_shmem_init
Xiaomeng Tong xiam0nd.tong@gmail.com virtio-gpu: fix a missing check to avoid NULL dereference
Fabio Estevam festevam@gmail.com i2c: mxs: Silence a clang warning
Tali Perry tali.perry1@gmail.com i2c: npcm: Correct slave role behavior
Tali Perry tali.perry1@gmail.com i2c: npcm: Remove own slave addresses 2:10
Leung, Martin Martin.Leung@amd.com drm/amdgpu/display: Prepare for new interfaces
ZhenGuo Yin zhenguo.yin@amd.com drm/amdgpu: fix scratch register access method in SRIOV
Bjorn Andersson bjorn.andersson@linaro.org drm/bridge: lt9611uxc: Cancel only driver's work
Miaoqian Lin linmq006@gmail.com drm/meson: encoder_hdmi: Fix refcount leak in meson_encoder_hdmi_init
Miaoqian Lin linmq006@gmail.com drm/meson: encoder_cvbs: Fix refcount leak in meson_encoder_cvbs_init
Xinlei Lee xinlei.lee@mediatek.com drm/mediatek: Add pull-down MIPI operation in mtk_dsi_poweroff function
Jitao Shi jitao.shi@mediatek.com drm/mediatek: Separate poweron/poweroff from enable/disable and define new funcs
Xinlei Lee xinlei.lee@mediatek.com drm/mediatek: Modify dsi funcs to atomic operations
Alexey Kodanev aleksei.kodanev@bell-sw.com drm/radeon: fix potential buffer overflow in ni_set_mc_special_registers()
Manikanta Pubbisetty quic_mpubbise@quicinc.com ath11k: Avoid REO CMD failed prints during firmware recovery
Manikanta Pubbisetty quic_mpubbise@quicinc.com ath11k: Fix incorrect debug_mask mappings
Christian Marangi ansuelsmth@gmail.com ath11k: fix missing skb drop on htc_tx_completion error
Yuze Chi chiyuze@google.com libbpf: Fix is_pow_of_2
Martin KaFai Lau kafai@fb.com selftests/bpf: Fix tc_redirect_dtime
Lorenzo Bianconi lorenzo@kernel.org sample: bpf: xdp_router_ipv4: Allow the kernel to send arp requests
Yuntao Wang ytcoode@gmail.com selftests/bpf: Fix test_run logic in fexit_stress.c
Javier Martinez Canillas javierm@redhat.com drm/ssd130x: Only define a SPI device ID table when built as a module
Yunhao Tian t123yh.xyz@gmail.com drm/mipi-dbi: align max_chunk to 2 in spi_transfer
Johan Hovold johan+linaro@kernel.org ath11k: fix IRQ affinity warning on shutdown
Johan Hovold johan+linaro@kernel.org ath11k: fix netdev open race
Ajay Singh ajay.kathat@microchip.com wifi: wilc1000: use correct sequence of RESET for chip Power-UP/Down
Dan Carpenter dan.carpenter@oracle.com wifi: rtlwifi: fix error codes in rtl_debugfs_set_write_h2c()
Fabio Estevam festevam@gmail.com drm: bridge: adv7511: Move CEC definitions to adv7511_cec.c
Gao Chao gaochao49@huawei.com drm/panel: Fix build error when CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=y && CONFIG_DRM_DISPLAY_HELPER=m
Javier Martinez Canillas javierm@redhat.com drm/st7735r: Fix module autoloading for Okaya RH128128T
John Stultz jstultz@google.com drm/bridge: lt9611: Use both bits for HDMI sensing
Jani Nikula jani.nikula@intel.com drm/edid: reset display info in drm_add_edid_modes() for NULL edid
Manikanta Pubbisetty quic_mpubbise@quicinc.com ath11k: Init hw_params before setting up AHB resources
Baochen Qiang quic_bqiang@quicinc.com ath11k: Fix warning on variable 'sar' dereference before check
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ath10k: do not enforce interrupt trigger type
Marek Vasut marex@denx.de drm/bridge: tc358767: Make sure Refclk clock are enabled
Marek Vasut marex@denx.de drm/bridge: tc358767: Handle dsi_lanes == 0 as invalid
Douglas Anderson dianders@chromium.org drm/dp: Export symbol / kerneldoc fixes for DP AUX bus
Miaoqian Lin linmq006@gmail.com drm/meson: Fix refcount leak in meson_encoder_hdmi_init
Thomas Zimmermann tzimmermann@suse.de drm/mgag200: Acquire I/O lock while reading EDID
Xin Ji xji@analogixsemi.com drm/bridge: anx7625: Use DPI bus type
Geert Uytterhoeven geert+renesas@glider.be drm: bridge: DRM_FSL_LDB should depend on ARCH_MXC
Dan Carpenter dan.carpenter@oracle.com drm/rockchip: vop2: unlock on error path in vop2_crtc_atomic_enable()
Jani Nikula jani.nikula@intel.com drm/i915: remove unused GEM_DEBUG_DECL() and GEM_DEBUG_BUG_ON()
Marek Vasut marex@denx.de dt-bindings: display: bridge: ldb: Fill in reg property
Hongnan Li hongnan.li@linux.alibaba.com erofs: update ctx->pos for every emitted dirent
Uwe Kleine-König u.kleine-koenig@pengutronix.de pwm: lpc18xx: Fix period handling
Uwe Kleine-König u.kleine-koenig@pengutronix.de pwm: sifive: Shut down hardware only after pwmchip_remove() completed
Uwe Kleine-König u.kleine-koenig@pengutronix.de pwm: sifive: Ensure the clk is enabled exactly once per running PWM
Uwe Kleine-König u.kleine-koenig@pengutronix.de pwm: sifive: Simplify offset calculation for PWMCMP registers
Mike Snitzer snitzer@kernel.org dm: return early from dm_pr_call() if DM device is suspended
Colin Ian King colin.king@intel.com tools/power turbostat: Fix file pointer leak
Markus Mayer mmayer@broadcom.com thermal/tools/tmon: Include pthread and time headers in tmon.h
YiFei Zhu zhuyifei@google.com selftests/seccomp: Fix compile warning when CC=clang
Michal Koutný mkoutny@suse.com io_uring: Don't require reinitable percpu_ref
Jens Axboe axboe@kernel.dk io_uring: define a 'prep' and 'issue' handler for each opcode
Jens Axboe axboe@kernel.dk io_uring: move to separate directory
Peter Zijlstra peterz@infradead.org x86/extable: Fix ex_handler_msr() print condition
Mel Gorman mgorman@techsingularity.net sched/numa: Initialise numa_migrate_retry
Christian Göttsche cgzones@googlemail.com sched: only perform capability check on privileged operation
Nicolas Saenz Julienne nsaenzju@redhat.com nohz/full, sched/rt: Fix missed tick-reenabling bug in dequeue_task_rt()
Anshuman Khandual anshuman.khandual@arm.com drivers/perf: arm_spe: Fix consistency of SYS_PMSCR_EL1.CX
Liang He windhl@126.com perf: RISC-V: Add of_node_put() when breaking out of for_each_of_cpu_node()
Xu Qiang xuqiang36@huawei.com irqdomain: Report irq number for NOMAP domains
Stephan Gerhold stephan.gerhold@kernkonzept.com ARM: dts: qcom: msm8974: Disable remoteprocs by default
Sumit Garg sumit.garg@linaro.org arm64: dts: qcom: qcs404: Fix incorrect USB2 PHYs assignment
Marijn Suijten marijn.suijten@somainline.org arm64: dts: qcom: msm8998: Make regulator voltages multiple of step-size
Parikshit Pareek quic_ppareek@quicinc.com soc: qcom: socinfo: Fix the id of SA8540P SoC
Konrad Dybcio konrad.dybcio@somainline.org soc: qcom: Make QCOM_RPMPD depend on PM
Liang He windhl@126.com regulator: of: Fix refcount leak bug in of_get_regulation_constraints()
Mikulas Patocka mpatocka@redhat.com dm writecache: count number of blocks discarded, not number of discard bios
Mikulas Patocka mpatocka@redhat.com dm writecache: count number of blocks written, not number of write bios
Mikulas Patocka mpatocka@redhat.com dm writecache: count number of blocks read, not number of read bios
Mikulas Patocka mpatocka@redhat.com dm writecache: return void from functions
Hsin-Yi Wang hsinyi@chromium.org PM: domains: Ensure genpd_debugfs_dir exists before remove
Bart Van Assche bvanassche@acm.org blktrace: Trace remapped requests correctly
Linus Walleij linus.walleij@linaro.org hwmon: (drivetemp) Add module alias
Armin Wolf W_Armin@gmx.de hwmon: (sch56xx-common) Add DMI override table
Yang Yingliang yangyingliang@huawei.com spi: tegra20-slink: fix UAF in tegra_slink_remove()
Yang Yingliang yangyingliang@huawei.com spi: Fix simplification of devm_spi_register_controller
Nandhini Srikandan nandhini.srikandan@intel.com spi: dw: Fix IP-core versions macro
Ming Lei ming.lei@redhat.com blk-mq: don't create hctx debugfs dir until q->debugfs_dir is created
Andy Shevchenko andriy.shevchenko@linux.intel.com spi: Return deferred probe error when controller isn't yet available
Gao Xiang xiang@kernel.org erofs: avoid consecutive detection for Highmem memory
Yuwen Chen chenyuwen1@meizu.com erofs: wake up all waiters after z_erofs_lzma_head ready
Johan Hovold johan+linaro@kernel.org arm64: dts: qcom: sc7280: fix PCIe clock reference
Tamás Szűcs tszucs@protonmail.ch arm64: tegra: Fix SDMMC1 CD on P2888
Mikko Perttunen mperttunen@nvidia.com arm64: tegra: Mark BPMP channels as no-memory-wc
Nick Hainke vincent@systemli.org arm64: dts: mt7622: fix BPI-R64 WPS button
Johan Hovold johan+linaro@kernel.org arm64: dts: qcom: sm8250: add missing PCIe PHY clock-cells
Johan Hovold johan+linaro@kernel.org arm64: dts: qcom: sc7280: drop PCIe PHY clock index
Dmitry Baryshkov dmitry.baryshkov@linaro.org arm64: dts: qcom: msm8996: correct #clock-cells for QMP PHY nodes
Marijn Suijten marijn.suijten@somainline.org arm64: dts: qcom: sm6125: Append -state suffix to pinctrl nodes
Marijn Suijten marijn.suijten@somainline.org arm64: dts: qcom: sm6125: Move sdc2 pinctrl from seine-pdx201 to sm6125
Yang Yingliang yangyingliang@huawei.com m68k: virt: Fix missing platform_device_unregister() on error in virt_platform_init()
Eric Auger eric.auger@redhat.com ACPI: VIOT: Fix ACS setup
Chanho Park chanho61.park@samsung.com arm64: dts: exynosautov9: correct spi11 pin names
Kan Liang kan.liang@linux.intel.com perf/x86/intel: Fix PEBS data source encoding for ADL
Kan Liang kan.liang@linux.intel.com perf/x86/intel: Fix PEBS memory access info encoding for ADL
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: msm8994: add required ranges to OCMEM
Sireesh Kodali sireeshkodali1@gmail.com arm64: dts: qcom: msm8916: Fix typo in pronto remoteproc node
GONG, Ruiqi gongruiqi1@huawei.com stack: Declare {randomize_,}kstack_offset to fix Sparse warnings
Kees Cook keescook@chromium.org lib: overflow: Do not define 64-bit tests on 32-bit
Jason A. Donenfeld Jason@zx2c4.com usercopy: use unsigned long instead of uintptr_t
Yang Yingliang yangyingliang@huawei.com bus: hisi_lpc: fix missing platform_device_put() in hisi_lpc_acpi_probe()
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: qcom: pm8841: add required thermal-sensor-cells
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: qcom: msm8974: add required ranges to OCMEM
Miaoqian Lin linmq006@gmail.com soc: qcom: aoss: Fix refcount leak in qmp_cooling_devices_register
Miaoqian Lin linmq006@gmail.com soc: qcom: ocmem: Fix refcount leak in of_get_ocmem
Luca Weiss luca@z3ntu.xyz ARM: dts: qcom-msm8974: fix irq type on blsp2_uart1
Christian Marangi ansuelsmth@gmail.com ARM: dts: qcom: replace gcc PXO with pxo_board fixed clock
Dan Williams dan.j.williams@intel.com ACPI: APEI: Fix _EINJ vs EFI_MEMORY_SP
Stephan Gerhold stephan.gerhold@kernkonzept.com regulator: qcom_smd: Fix pm8916_pldo range
Chris Paterson chris.paterson2@renesas.com arm64: dts: renesas: r9a07g054l2-smarc: Correct SoC name in comment
Geert Uytterhoeven geert+renesas@glider.be arm64: dts: renesas: r8a779m8: Drop operating points above 1.5 GHz
Miaoqian Lin linmq006@gmail.com cpufreq: zynq: Fix refcount leak in zynq_get_revision
Dmitry Baryshkov dmitry.baryshkov@linaro.org arm64: dts: qcom: sdm636-sony-xperia-ganges-mermaid: correct sdc2 pinconf
Dmitry Baryshkov dmitry.baryshkov@linaro.org arm64: dts: qcom: sdm630: fix gpu's interconnect path
Dmitry Baryshkov dmitry.baryshkov@linaro.org arm64: dts: qcom: sdm630: fix the qusb2phy ref clock
Dmitry Baryshkov dmitry.baryshkov@linaro.org arm64: dts: qcom: sdm630: disable GPU by default
Miaoqian Lin linmq006@gmail.com ARM: OMAP2+: Fix refcount leak in omap3xxx_prm_late_init
Miaoqian Lin linmq006@gmail.com ARM: OMAP2+: Fix refcount leak in omapdss_init_of
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: qcom: mdm9615: add missing PMIC GPIO reg
Marijn Suijten marijn.suijten@somainline.org arm64: dts: qcom: sdm845-akatsuki: Round down l22a regulator voltage
Keith Busch kbusch@kernel.org block: fix infinite loop for invalid zone append
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org spi: s3c64xx: constify fsd_spi_port_config
Michael Walle michael@walle.cc soc: fsl: guts: machine variable might be unset
Stephen Boyd swboyd@chromium.org arm64: dts: qcom: sc7180: Remove ipa_fw_mem node on trogdor
Peter Zijlstra peterz@infradead.org locking/lockdep: Fix lockdep_init_map_*() confusion
Alexandru Elisei alexandru.elisei@arm.com arm64: cpufeature: Allow different PMU versions in ID_DFR0_EL1
Mark Rutland mark.rutland@arm.com arm64: select TRACE_IRQFLAGS_NMI_SUPPORT
Nícolas F. R. A. Prado nfraprado@collabora.com arm64: dts: mt8192: Fix idle-states entry-method
Nícolas F. R. A. Prado nfraprado@collabora.com arm64: dts: mt8192: Fix idle-states nodes naming scheme
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: ast2600-evb-a1: fix board compatible
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: ast2600-evb: fix board compatible
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: ast2500-evb: fix board compatible
Johan Hovold johan@kernel.org x86/pmem: Fix platform-device leak in error path
Max Krummenacher max.krummenacher@toradex.com Revert "ARM: dts: imx6qdl-apalis: Avoid underscore in node name"
Geert Uytterhoeven geert+renesas@glider.be arm64: dts: renesas: Fix thermal-sensors on single-zone sensors
Liang He windhl@126.com soc: amlogic: Fix refcount leak in meson-secure-pwrc.c
Geert Uytterhoeven geert+renesas@glider.be soc: renesas: r8a779a0-sysc: Fix A2DP1 and A2CV[2357] PDR values
Marcel Ziswiler marcel.ziswiler@toradex.com ARM: dts: imx7-colibri-eval-v3: correct can controller comment
Marcel Ziswiler marcel.ziswiler@toradex.com ARM: dts: imx7-colibri: move aliases, chosen, extcon and gpio-keys
Oleksandr Suvorov oleksandr.suvorov@toradex.com ARM: dts: imx7-colibri: improve wake-up with gpio key
Philippe Schenker philippe.schenker@toradex.com ARM: dts: imx7-colibri: add usb dual-role switching using extcon
Marcel Ziswiler marcel.ziswiler@toradex.com ARM: dts: imx7-colibri: overhaul display/touch functionality
Marcel Ziswiler marcel.ziswiler@toradex.com ARM: dts: imx7d-colibri-emmc: add cpu1 supply
Guilherme G. Piccoli gpiccoli@igalia.com ACPI: processor/idle: Annotate more functions to live in cpuidle section
Miaoqian Lin linmq006@gmail.com ARM: bcm: Fix refcount leak in bcm_kona_smc_init
Christophe JAILLET christophe.jaillet@wanadoo.fr spi: spi-altera-dfl: Fix an error handling path
Geert Uytterhoeven geert+renesas@glider.be arm64: dts: renesas: beacon: Fix regulator node names
Miaoqian Lin linmq006@gmail.com meson-mx-socinfo: Fix refcount leak in meson_mx_socinfo_init
Juri Lelli juri.lelli@redhat.com wait: Fix __wait_event_hrtimeout for RT/DL tasks
Kees Cook keescook@chromium.org kasan: test: Silence GCC 12 warnings
Dylan Yudaken dylany@fb.com io_uring: fix io_uring_cqe_overflow trace format
Xiu Jianfeng xiujianfeng@huawei.com selinux: Add boundary check in put_entry()
Xiu Jianfeng xiujianfeng@huawei.com selinux: fix memleak in security_read_state_kernel()
Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp PM: hibernate: defer device probing when resuming from hibernation
Uwe Kleine-König u.kleine-koenig@pengutronix.de hwmon: (sht15) Fix wrong assumptions in device remove callback
Hans de Goede hdegoede@redhat.com ACPI: video: Use native backlight on Dell Inspiron N4010
Lukasz Luba lukasz.luba@arm.com PM: EM: convert power field to micro-Watts precision and align drivers
Armin Wolf W_Armin@gmx.de hwmon: (dell-smm) Add Dell XPS 13 7390 to fan control whitelist
Lv Ruyi lv.ruyi@zte.com.cn firmware: tegra: Fix error check return value of debugfs_create_file()
Liang He windhl@126.com ARM: shmobile: rcar-gen2: Increase refcount for new reference
Samuel Holland samuel@sholland.org arm64: dts: allwinner: a64: orangepi-win: Fix LED node name
Robert Marko robimarko@gmail.com arm64: dts: qcom: ipq8074: fix NAND node name
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org arm64: dts: qcom: add missing AOSS QMP compatible fallback
Gwendal Grignou gwendal@chromium.org arm64: dts: qcom: sc7280: Rename sar sensor labels
Manivannan Sadhasivam mani@kernel.org ARM: dts: qcom: sdx55: Fix the IRQ trigger type for UART
huhai huhai@kylinos.cn ACPI: LPSS: Fix missing check in register_device_clock()
Manyi Li limanyi@uniontech.com ACPI: PM: save NVS memory for Lenovo G40-45
Hans de Goede hdegoede@redhat.com ACPI: EC: Drop the EC_FLAGS_IGNORE_DSDT_GPE quirk
Hans de Goede hdegoede@redhat.com ACPI: EC: Remove duplicate ThinkPad X1 Carbon 6th entry from DMI quirks
Liang He windhl@126.com ARM: OMAP2+: pdata-quirks: Fix refcount leak bug
Liang He windhl@126.com ARM: OMAP2+: display: Fix refcount leak bug
Guo Mengqi guomengqi3@huawei.com spi: synquacer: Add missing clk_disable_unprepare()
David Heidelberg david@ixit.cz arm64: dts: qcom: timer should use only 32-bit size
Linus Walleij linus.walleij@linaro.org ARM: dts: ux500: Fix Gavini accelerometer mounting matrix
Linus Walleij linus.walleij@linaro.org ARM: dts: ux500: Fix Codina accelerometer mounting matrix
Linus Walleij linus.walleij@linaro.org ARM: dts: ux500: Fix Janice accelerometer mounting matrix
Christian Lamparter chunkeey@gmail.com ARM: dts: BCM5301X: Add DT for Meraki MR26
Alexander Stein alexander.stein@ew.tq-group.com ARM: dts: imx6ul: fix qspi node compatible
Alexander Stein alexander.stein@ew.tq-group.com ARM: dts: imx6ul: fix lcdif node compatible
Alexander Stein alexander.stein@ew.tq-group.com ARM: dts: imx6ul: fix csi node compatible
Alexander Stein alexander.stein@ew.tq-group.com ARM: dts: imx6ul: fix keypad compatible
Alexander Stein alexander.stein@ew.tq-group.com ARM: dts: imx6ul: change operating-points to uint32-matrix
Alexander Stein alexander.stein@ew.tq-group.com ARM: dts: imx6ul: add missing properties for sram
William Dean williamsukatube@163.com irqchip/mips-gic: Check the return value of ioremap() in gic_of_init()
John Keeping john@metanate.com sched/core: Always flush pending blk_plug
Vincent Guittot vincent.guittot@linaro.org sched/fair: fix case with reduced capacity CPU
Samuel Holland samuel@sholland.org genirq: GENERIC_IRQ_IPI depends on SMP
Samuel Holland samuel@sholland.org irqchip/mips-gic: Only register IPI domain when SMP is enabled
Antonio Borneo antonio.borneo@foss.st.com genirq: Don't return error on missing optional irq_request_resources()
Chen Yu yu.c.chen@intel.com sched/fair: Introduce SIS_UTIL to search idle CPU based on sum of util_avg
Jan Kara jack@suse.cz ext2: Add more validity checks for inode counts
James Morse james.morse@arm.com arm64: errata: Remove AES hwcap for COMPAT tasks
Catalin Marinas catalin.marinas@arm.com arm64: kasan: Revert "arm64: mte: reset the page tag in page->flags"
haibinzhang (张海斌) haibinzhang@tencent.com arm64: fix oops in concurrently setting insn_emulation sysctls
Francis Laniel flaniel@linux.microsoft.com arm64: Do not forget syscall when starting a new thread.
Andrey Konovalov andreyknvl@gmail.com arm64: stacktrace: use non-atomic __set_bit
Andrey Konovalov andreyknvl@gmail.com arm64: kasan: do not instrument stacktrace.c
Mark Rutland mark.rutland@arm.com arch: make TRACE_IRQFLAGS_NMI_SUPPORT generic
Wyes Karny wyes.karny@amd.com x86: Handle idle=nomwait cmdline properly for x86_idle
Benjamin Segall bsegall@google.com epoll: autoremove wakers even more aggressively
Florian Westphal fw@strlen.de netfilter: nf_tables: fix null deref due to zeroed list head
Pablo Neira Ayuso pablo@netfilter.org netfilter: nf_tables: disallow jump to implicit chain from set element
Pablo Neira Ayuso pablo@netfilter.org netfilter: nf_tables: upfront validation of data via nft_data_init()
Thadeu Lima de Souza Cascardo cascardo@canonical.com netfilter: nf_tables: do not allow RULE_ID to refer to another chain
Thadeu Lima de Souza Cascardo cascardo@canonical.com netfilter: nf_tables: do not allow CHAIN_ID to refer to another table
Thadeu Lima de Souza Cascardo cascardo@canonical.com netfilter: nf_tables: do not allow SET_ID to refer to another table
Michael Grzeschik m.grzeschik@pengutronix.de usb: dwc3: gadget: fix high speed multiplier setting
Michael Grzeschik m.grzeschik@pengutronix.de usb: dwc3: gadget: refactor dwc3_repare_one_trb
Alan Stern stern@rowland.harvard.edu USB: gadget: Fix use-after-free Read in usb_udc_uevent()
Kunihiko Hayashi hayashi.kunihiko@socionext.com arm64: dts: uniphier: Fix USB interrupts for PXs3 SoC
Kunihiko Hayashi hayashi.kunihiko@socionext.com ARM: dts: uniphier: Fix USB interrupts for PXs2 SoC
Jose Alonso joalonsof@gmail.com Revert "net: usb: ax88179_178a needs FLAG_SEND_ZLP"
Weitao Wang WeitaoWang-oc@zhaoxin.com USB: HCD: Fix URB giveback issue in tasklet function
Linyu Yuan quic_linyyuan@quicinc.com usb: typec: ucsi: Acknowledge the GET_ERROR_STATUS command completion
Suzuki K Poulose suzuki.poulose@arm.com coresight: Clear the connection field properly
Huacai Chen chenhuacai@kernel.org MIPS: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK
Michael Ellerman mpe@ellerman.id.au powerpc/powernv: Avoid crashing if rng is NULL
Christophe Leroy christophe.leroy@csgroup.eu powerpc/ptdump: Fix display of RW pages on FSL_BOOK3E
Pali Rohár pali@kernel.org powerpc/fsl-pci: Fix Class Code of PCIe Root Port
Christophe Leroy christophe.leroy@csgroup.eu powerpc/64e: Fix early TLB miss with KUAP
Christophe Leroy christophe.leroy@csgroup.eu powerpc: Restore CONFIG_DEBUG_INFO in defconfigs
Alexander Lobakin alexandr.lobakin@intel.com ia64, processor: fix -Wincompatible-pointer-types in ia64_get_irr()
Xiaomeng Tong xiam0nd.tong@gmail.com media: [PATCH] pci: atomisp_cmd: fix three missing checks on list iterator
Randy Dunlap rdunlap@infradead.org media: isl7998x: select V4L2_FWNODE to fix build error
Jan Kara jack@suse.cz mbcache: add functions to delete entry if unused
Jan Kara jack@suse.cz mbcache: don't reclaim used entries
Mikulas Patocka mpatocka@redhat.com md-raid10: fix KASAN warning
Mikulas Patocka mpatocka@redhat.com md-raid: destroy the bitmap after destroying the thread
Narendra Hadke nhadke@marvell.com serial: mvebu-uart: uart2 error bits clearing
Miklos Szeredi mszeredi@redhat.com fuse: fix deadlock between atomic O_TRUNC and page invalidation
Miklos Szeredi mszeredi@redhat.com fuse: write inode in fuse_release()
Miklos Szeredi mszeredi@redhat.com fuse: ioctl: translate ENOSYS
Miklos Szeredi mszeredi@redhat.com fuse: limit nsec
Namjae Jeon linkinjeon@kernel.org ksmbd: fix heap-based overflow in set_ntacl_dacl()
Namjae Jeon linkinjeon@kernel.org ksmbd: fix use-after-free bug in smb2_tree_disconect
Hyunchul Lee hyc.lee@gmail.com ksmbd: prevent out of bound read for SMB2_WRITE
Hyunchul Lee hyc.lee@gmail.com ksmbd: prevent out of bound read for SMB2_TREE_CONNNECT
Namjae Jeon linkinjeon@kernel.org ksmbd: fix memory leak in smb2_handle_negotiate
Srinivas Kandagatla srinivas.kandagatla@linaro.org soundwire: qcom: Check device status before reading devid
Bikash Hazarika bhazarika@marvell.com scsi: qla2xxx: Zero undefined mailbox IN registers
Bikash Hazarika bhazarika@marvell.com scsi: qla2xxx: Fix incorrect display of max frame size
Tony Battersby tonyb@cybernetics.com scsi: sg: Allow waiting for commands to complete on removed device
James Smart jsmart2021@gmail.com scsi: lpfc: Remove extra atomic_inc on cmd_pending in queuecommand after VMID
Zheyu Ma zheyuma97@gmail.com iio: light: isl29028: Fix the warning in isl29028_remove()
Fawzi Khaber fawzi.khaber@tdk.com iio: fix iio_format_avail_range() printing for none IIO_VAL_INT
Jason A. Donenfeld Jason@zx2c4.com um: seed rng using host OS rng
Benjamin Beichler benjamin.beichler@uni-rostock.de um: Remove straying parenthesis
Amit Kumar Mahapatra amit.kumar-mahapatra@xilinx.com mtd: rawnand: arasan: Update NAND bus clock instead of system clock
Olga Kitaina okitain@gmail.com mtd: rawnand: arasan: Fix clock rate in NV-DDR
Qu Wenruo wqu@suse.com btrfs: reject log replay if there is unsupported RO compat flag
Tadeusz Struk tadeusz.struk@linaro.org bpf: Fix KASAN use-after-free Read in compute_effective_progs
Leo Li sunpeng.li@amd.com drm/amdgpu: Check BO's requested pinning domains against its preferred_domains
Dmitry Osipenko dmitry.osipenko@collabora.com drm/tegra: Fix vmapping of prime buffers
Lyude Paul lyude@redhat.com drm/nouveau/kms: Fix failure path for creating DP connectors
Lyude Paul lyude@redhat.com drm/nouveau/acpi: Don't print error when we get -EINPROGRESS from pm_runtime
Lyude Paul lyude@redhat.com drm/nouveau: Don't pm_runtime_put_sync(), only pm_runtime_put_autosuspend()
Timur Tabi ttabi@nvidia.com drm/nouveau: fix another off-by-one in nvbios_addr
Imre Deak imre.deak@intel.com drm/dp/mst: Read the extended DPCD capabilities during system resume
Thomas Zimmermann tzimmermann@suse.de drm/hyperv-drm: Include framebuffer and EDID headers
Thomas Zimmermann tzimmermann@suse.de drm/fb-helper: Fix out-of-bounds access
Paul Cercueil paul@crapouillou.net drm/ingenic: Use the highest possible DMA burst size
Phil Elwell phil@raspberrypi.org drm/vc4: hdmi: Disable audio if dmas property is present but empty
Dmitry Osipenko dmitry.osipenko@collabora.com drm/shmem-helper: Add missing vunmap on error
Dmitry Osipenko dmitry.osipenko@collabora.com drm/gem: Properly annotate WW context on drm_gem_lock_reservations() error
Mathew McBride matt@traverse.com.au rtc: rx8025: fix 12/24 hour mode detection on RX-8035
Jason A. Donenfeld Jason@zx2c4.com wireguard: selftests: set CONFIG_NONPORTABLE on riscv32
Atish Patra atishp@rivosinc.com RISC-V: Update user page mapping only once during start
Atish Patra atishp@rivosinc.com RISC-V: Fix SBI PMU calls for RV32
Atish Patra atishp@rivosinc.com RISC-V: Fix counter restart during overflow for RV32
Xianting Tian xianting.tian@linux.alibaba.com RISC-V: Add modules to virtual kernel memory layout dump
Xianting Tian xianting.tian@linux.alibaba.com RISC-V: Fixup schedule out issue in machine_crash_shutdown()
Xianting Tian xianting.tian@linux.alibaba.com RISC-V: Fixup get incorrect user mode PC for kernel mode regs
Xianting Tian xianting.tian@linux.alibaba.com RISC-V: kexec: Fixup use of smp_processor_id() in preemptible context
Ben Dooks ben.dooks@sifive.com RISC-V: Declare cpu_ops_spinwait in <asm/cpu_ops.h>
Ben Dooks ben.dooks@sifive.com RISC-V: cpu_ops_spinwait.c should include head.h
Mark Kettenis kettenis@openbsd.org riscv: dts: starfive: correct number of external interrupts
Conor Dooley conor.dooley@microchip.com dt-bindings: riscv: fix SiFive l2-cache's cache-sets
Chen Lifu chenlifu@huawei.com riscv: lib: uaccess: fix CSR_STATUS SR_SUM bit
Yipeng Zou zouyipeng@huawei.com riscv:uprobe fix SR_SPIE set/clear handling
Helge Deller deller@gmx.de parisc: io_pgetevents_time64() needs compat syscall in 32-bit compat mode
William Dean williamsukatube@gmail.com parisc: Check the return value of ioremap() in lba_driver_probe()
Helge Deller deller@gmx.de parisc: Drop pa_swapper_pg_lock spinlock
Helge Deller deller@gmx.de parisc: Fix device names in /proc/iomem
Jiachen Zhang zhangjiachen.jaycee@bytedance.com ovl: drop WARN_ON() dentry is NULL in ovl_encode_fh()
John Allen john.allen@amd.com crypto: ccp - Use kzalloc for sev ioctl interfaces to prevent kernel memory leak
Al Viro viro@zeniv.linux.org.uk fix short copy handling in copy_mc_pipe_to_iter()
Lukas Wunner lukas@wunner.de usbnet: smsc95xx: Fix deadlock on runtime resume
Lukas Wunner lukas@wunner.de usbnet: Fix linkwatch use-after-free on disconnect
Helge Deller deller@gmx.de fbcon: Fix accelerated fbdev scrolling while logo is still shown
Helge Deller deller@gmx.de fbcon: Fix boundary checks for fbcon=vc:n1-n2 parameters
Rafael J. Wysocki rafael.j.wysocki@intel.com thermal: sysfs: Fix cooling_device_stats_setup() error code path
Yang Xu xuyang2018.jy@fujitsu.com fs: Add missing umask strip in vfs_tmpfile
David Howells dhowells@redhat.com vfs: Check the truncate maximum size in inode_newsize_ok()
Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp tty: vt: initialize unicode screen buffer
Cameron Williams cang1@live.co.uk tty: 8250: Add support for Brainboxes PX cards.
Huacai Chen chenhuacai@kernel.org LoongArch: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK
Bedant Patnaik bedant.patnaik@gmail.com ALSA: hda/realtek: Add a quirk for HP OMEN 15 (8786) mute LED
Meng Tang tangmeng@uniontech.com ALSA: hda/realtek: Add quirk for another Asus K42JZ model
Allen Ballway ballway@chromium.org ALSA: hda/cirrus - support for iMac 12,1 model
Meng Tang tangmeng@uniontech.com ALSA: hda/conexant: Add quirk for LENOVO 20149 Notebook model
Coleman Dietsch dietschc@csp.edu KVM: x86/xen: Stop Xen timer before changing IRQ
Coleman Dietsch dietschc@csp.edu KVM: x86/xen: Initialize Xen timer only once
Paolo Bonzini pbonzini@redhat.com KVM: x86: revalidate steal time cache if MSR value changes
Paolo Bonzini pbonzini@redhat.com KVM: x86: do not report preemption if the steal time cache is stale
Sean Christopherson seanjc@google.com KVM: x86/mmu: Fully re-evaluate MMIO caching when SPTE masks change
Sean Christopherson seanjc@google.com KVM: x86: Tag kvm_mmu_x86_module_init() with __init
Sean Christopherson seanjc@google.com KVM: SVM: Disable SEV-ES support if MMIO caching is disable
Sean Christopherson seanjc@google.com KVM: x86/mmu: Treat NX as a valid SPTE bit for NPT
Sean Christopherson seanjc@google.com KVM: x86: Set error code to segment selector on LLDT/LTR non-canonical #GP
Sean Christopherson seanjc@google.com KVM: x86: Mark TSS busy during LTR emulation _after_ all fault checks
Sean Christopherson seanjc@google.com KVM: nVMX: Inject #UD if VMXON is attempted with incompatible CR0/CR4
Sean Christopherson seanjc@google.com KVM: nVMX: Account for KVM reserved CR4 bits in consistency checks
Sean Christopherson seanjc@google.com KVM: nVMX: Let userspace set nVMX MSR to any _host_ supported value
Sean Christopherson seanjc@google.com KVM: x86: Split kvm_is_valid_cr4() and export only the non-vendor bits
Sean Christopherson seanjc@google.com KVM: Do not incorporate page offset into gfn=>pfn cache user address
Sean Christopherson seanjc@google.com KVM: Fix multiple races in gfn=>pfn cache refresh
Sean Christopherson seanjc@google.com KVM: Fully serialize gfn=>pfn cache refresh via mutex
Sean Christopherson seanjc@google.com KVM: Put the extra pfn reference when reusing a pfn in the gpc cache
Sean Christopherson seanjc@google.com KVM: Drop unused @gpa param from gfn=>pfn cache's __release_gpc() helper
Nico Boehr nrb@linux.ibm.com KVM: s390: pv: don't present the ecall interrupt twice
Maciej S. Szmigiero maciej.szmigiero@oracle.com KVM: SVM: Don't BUG if userspace injects an interrupt with GIF=0
Sean Christopherson seanjc@google.com KVM: nVMX: Snapshot pre-VM-Enter DEBUGCTL for !nested_run_pending case
Sean Christopherson seanjc@google.com KVM: nVMX: Snapshot pre-VM-Enter BNDCFGS for !nested_run_pending case
Ping Cheng pinglinux@gmail.com HID: wacom: Don't register pad_input for touch switch
Ping Cheng pinglinux@gmail.com HID: wacom: Only report rotation for art pen
Guenter Roeck linux@roeck-us.net HID: nintendo: Add missing array termination
Maximilian Luz luzmaximilian@gmail.com HID: hid-input: add Surface Go battery quirk
Jeff Layton jlayton@kernel.org lockd: detect and reject lock arguments that overflow
Mikulas Patocka mpatocka@redhat.com add barriers to buffer_uptodate and set_buffer_uptodate
Johannes Berg johannes.berg@intel.com wifi: mac80211_hwsim: use 32-bit skb cookie
Johannes Berg johannes.berg@intel.com wifi: mac80211_hwsim: add back erroneously removed cast
Jeongik Cha jeongik@google.com wifi: mac80211_hwsim: fix race condition in pending packet
Zev Weiss zev@bewilderbeest.net hwmon: (nct6775) Fix platform driver suspend regression
syed sabakareem Syed.SabaKareem@amd.com ASoC: amd: yc: Update DMI table entries
Philipp Jungkamp p.jungkamp@gmx.net ALSA: hda/realtek: Add quirk for Lenovo Yoga9 14IAP7
Ivan Hasenkampf ivan.hasenkampf@gmail.com ALSA: hda/realtek: Add quirk for HP Spectre x360 15-eb0xxx
Tim Crawford tcrawford@system76.com ALSA: hda/realtek: Add quirk for Clevo NV45PZ
Zheyu Ma zheyuma97@gmail.com ALSA: bcd2000: Fix a UAF bug on the error path of probing
Takashi Iwai tiwai@suse.de ALSA: usb-audio: Add quirk for Behringer UMC202HD
Jeff Layton jlayton@kernel.org nfsd: eliminate the NFSD_FILE_BREAK_* flags
Trond Myklebust trond.myklebust@hammerspace.com pNFS/flexfiles: Report RDMA connection errors to the server
Nilesh Javali njavali@marvell.com scsi: Revert "scsi: qla2xxx: Fix disk failure to rediscover"
Trond Myklebust trond.myklebust@hammerspace.com Revert "pNFS: nfs3_set_ds_client should set NFS_CS_NOPING"
Nick Desaulniers ndesaulniers@google.com x86: link vdso and boot with -z noexecstack --no-warn-rwx-segments
Nick Desaulniers ndesaulniers@google.com Makefile: link with -z noexecstack --no-warn-rwx-segments
-------------
Diffstat:
Documentation/ABI/testing/sysfs-driver-xen-blkback | 2 +- .../ABI/testing/sysfs-driver-xen-blkfront | 2 +- .../admin-guide/device-mapper/writecache.rst | 16 +- Documentation/admin-guide/kernel-parameters.txt | 29 +- Documentation/admin-guide/pm/cpuidle.rst | 15 +- Documentation/arm64/silicon-errata.rst | 4 + .../bindings/display/bridge/fsl,ldb.yaml | 16 +- .../devicetree/bindings/mmc/sdhci-msm.yaml | 52 +- .../devicetree/bindings/riscv/sifive-l2-cache.yaml | 6 +- Documentation/filesystems/ext4/blockmap.rst | 2 +- .../userspace-api/media/v4l/ext-ctrls-codec.rst | 2 +- MAINTAINERS | 7 +- Makefile | 10 +- arch/Kconfig | 3 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/aspeed-ast2500-evb.dts | 2 +- arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts | 1 + arch/arm/boot/dts/aspeed-ast2600-evb.dts | 2 +- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 166 ++++ arch/arm/boot/dts/imx6qdl-apalis.dtsi | 4 +- arch/arm/boot/dts/imx6ul.dtsi | 33 +- arch/arm/boot/dts/imx7-colibri-aster.dtsi | 71 -- arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi | 91 +-- arch/arm/boot/dts/imx7-colibri.dtsi | 130 +++- arch/arm/boot/dts/imx7d-colibri-aster.dts | 20 + arch/arm/boot/dts/imx7d-colibri-emmc.dtsi | 4 + arch/arm/boot/dts/imx7d-colibri-eval-v3.dts | 32 + arch/arm/boot/dts/imx7s-colibri-aster.dts | 20 + arch/arm/boot/dts/imx7s-colibri-eval-v3.dts | 32 + arch/arm/boot/dts/qcom-ipq8064.dtsi | 2 +- arch/arm/boot/dts/qcom-mdm9615.dtsi | 1 + arch/arm/boot/dts/qcom-msm8974.dtsi | 7 +- .../arm/boot/dts/qcom-msm8974pro-fairphone-fp2.dts | 2 + arch/arm/boot/dts/qcom-msm8974pro-samsung-klte.dts | 2 + arch/arm/boot/dts/qcom-pm8841.dtsi | 1 + arch/arm/boot/dts/qcom-sdx55.dtsi | 2 +- arch/arm/boot/dts/ste-ux500-samsung-codina.dts | 4 +- arch/arm/boot/dts/ste-ux500-samsung-gavini.dts | 4 +- arch/arm/boot/dts/ste-ux500-samsung-janice.dts | 4 +- arch/arm/boot/dts/uniphier-pxs2.dtsi | 8 +- arch/arm/crypto/Kconfig | 2 +- arch/arm/crypto/Makefile | 4 +- arch/arm/crypto/blake2s-shash.c | 75 -- arch/arm/mach-bcm/bcm_kona_smc.c | 1 + arch/arm/mach-dove/Kconfig | 1 + arch/arm/mach-dove/pcie.c | 11 +- arch/arm/mach-mv78xx0/pcie.c | 11 +- arch/arm/mach-omap2/display.c | 3 + arch/arm/mach-omap2/pdata-quirks.c | 2 + arch/arm/mach-omap2/prm3xxx.c | 1 + arch/arm/mach-orion5x/Kconfig | 1 + arch/arm/mach-orion5x/pci.c | 12 +- arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c | 5 +- arch/arm/mach-zynq/common.c | 1 + arch/arm/xen/enlighten.c | 4 +- arch/arm64/Kconfig | 17 + .../boot/dts/allwinner/sun50i-a64-orangepi-win.dts | 2 +- .../boot/dts/exynos/exynosautov9-pinctrl.dtsi | 6 +- .../boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 2 +- arch/arm64/boot/dts/mediatek/mt8192.dtsi | 26 +- arch/arm64/boot/dts/nvidia/tegra186.dtsi | 1 + arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 2 +- arch/arm64/boot/dts/nvidia/tegra194.dtsi | 1 + arch/arm64/boot/dts/nvidia/tegra234.dtsi | 1 + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 22 +- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 +- arch/arm64/boot/dts/qcom/msm8994.dtsi | 1 + arch/arm64/boot/dts/qcom/msm8996.dtsi | 6 +- .../qcom/msm8998-sony-xperia-yoshino-poplar.dts | 10 +- arch/arm64/boot/dts/qcom/qcs404.dtsi | 4 +- arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 1 + arch/arm64/boot/dts/qcom/sc7180.dtsi | 24 +- arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi | 4 +- arch/arm64/boot/dts/qcom/sc7280.dtsi | 30 +- arch/arm64/boot/dts/qcom/sdm630.dtsi | 7 +- .../dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts | 2 +- .../dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts | 5 +- arch/arm64/boot/dts/qcom/sdm845.dtsi | 22 +- .../dts/qcom/sm6125-sony-xperia-seine-pdx201.dts | 36 +- arch/arm64/boot/dts/qcom/sm6125.dtsi | 30 +- arch/arm64/boot/dts/qcom/sm6350.dtsi | 22 +- arch/arm64/boot/dts/qcom/sm8150.dtsi | 24 +- arch/arm64/boot/dts/qcom/sm8250.dtsi | 30 +- arch/arm64/boot/dts/qcom/sm8350.dtsi | 24 +- arch/arm64/boot/dts/qcom/sm8450.dtsi | 22 +- .../boot/dts/renesas/beacon-renesom-baseboard.dtsi | 6 +- arch/arm64/boot/dts/renesas/r8a774c0.dtsi | 2 +- arch/arm64/boot/dts/renesas/r8a77990.dtsi | 2 +- arch/arm64/boot/dts/renesas/r8a779m8.dtsi | 5 + arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts | 2 +- arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi | 8 +- arch/arm64/crypto/Kconfig | 1 + arch/arm64/include/asm/kexec.h | 4 +- arch/arm64/include/asm/processor.h | 3 +- arch/arm64/kernel/Makefile | 5 + arch/arm64/kernel/armv8_deprecated.c | 9 +- arch/arm64/kernel/cpu_errata.c | 16 + arch/arm64/kernel/cpufeature.c | 16 +- arch/arm64/kernel/hibernate.c | 5 - arch/arm64/kernel/mte.c | 9 - arch/arm64/kernel/stacktrace.c | 6 +- arch/arm64/kvm/handle_exit.c | 4 +- arch/arm64/kvm/hyp/nvhe/switch.c | 2 +- arch/arm64/kvm/hyp/vhe/switch.c | 2 +- arch/arm64/mm/copypage.c | 9 - arch/arm64/mm/mteswap.c | 9 - arch/arm64/tools/cpucaps | 1 + arch/csky/abiv1/inc/abi/string.h | 6 + arch/ia64/include/asm/processor.h | 2 +- arch/loongarch/kernel/proc.c | 2 +- arch/m68k/virt/platform.c | 58 +- arch/mips/kernel/proc.c | 2 +- arch/mips/kernel/vdso.c | 2 +- arch/mips/loongson64/numa.c | 1 - arch/mips/mm/physaddr.c | 14 +- arch/parisc/kernel/cache.c | 3 - arch/parisc/kernel/drivers.c | 9 +- arch/parisc/kernel/syscalls/syscall.tbl | 2 +- arch/powerpc/configs/44x/akebono_defconfig | 2 +- arch/powerpc/configs/44x/currituck_defconfig | 2 +- arch/powerpc/configs/44x/fsp2_defconfig | 2 +- arch/powerpc/configs/44x/iss476-smp_defconfig | 2 +- arch/powerpc/configs/44x/warp_defconfig | 2 +- arch/powerpc/configs/52xx/lite5200b_defconfig | 2 +- arch/powerpc/configs/52xx/motionpro_defconfig | 2 +- arch/powerpc/configs/52xx/tqm5200_defconfig | 2 +- arch/powerpc/configs/adder875_defconfig | 2 +- arch/powerpc/configs/ep8248e_defconfig | 2 +- arch/powerpc/configs/ep88xc_defconfig | 2 +- arch/powerpc/configs/fsl-emb-nonhw.config | 2 +- arch/powerpc/configs/mgcoge_defconfig | 2 +- arch/powerpc/configs/mpc5200_defconfig | 2 +- arch/powerpc/configs/mpc8272_ads_defconfig | 2 +- arch/powerpc/configs/mpc885_ads_defconfig | 2 +- arch/powerpc/configs/ppc6xx_defconfig | 2 +- arch/powerpc/configs/pq2fads_defconfig | 2 +- arch/powerpc/configs/ps3_defconfig | 2 +- arch/powerpc/configs/tqm8xx_defconfig | 2 +- arch/powerpc/include/asm/archrandom.h | 5 - arch/powerpc/include/asm/kexec.h | 9 + arch/powerpc/include/asm/simple_spinlock.h | 15 +- arch/powerpc/kernel/iommu.c | 5 + arch/powerpc/kernel/pci-common.c | 29 +- arch/powerpc/kernel/trace/ftrace.c | 8 +- arch/powerpc/kexec/file_load_64.c | 55 ++ arch/powerpc/kvm/book3s_hv_builtin.c | 7 +- arch/powerpc/kvm/book3s_xics.h | 1 + arch/powerpc/mm/kasan/init_32.c | 2 +- arch/powerpc/mm/nohash/8xx.c | 4 +- arch/powerpc/mm/nohash/tlb_low_64e.S | 17 +- arch/powerpc/mm/pgtable_32.c | 6 +- arch/powerpc/mm/ptdump/shared.c | 6 +- arch/powerpc/perf/core-book3s.c | 35 +- arch/powerpc/platforms/Kconfig.cputype | 4 +- arch/powerpc/platforms/cell/axon_msi.c | 1 + arch/powerpc/platforms/cell/spufs/inode.c | 1 + arch/powerpc/platforms/powernv/rng.c | 34 +- arch/powerpc/platforms/pseries/iommu.c | 89 ++- arch/powerpc/sysdev/fsl_pci.c | 8 + arch/powerpc/sysdev/fsl_pci.h | 1 + arch/powerpc/sysdev/xive/spapr.c | 1 + arch/riscv/boot/dts/starfive/jh7100.dtsi | 2 +- arch/riscv/include/asm/cpu_ops.h | 1 + arch/riscv/kernel/cpu_ops.c | 4 +- arch/riscv/kernel/cpu_ops_spinwait.c | 6 +- arch/riscv/kernel/crash_save_regs.S | 2 +- arch/riscv/kernel/machine_kexec.c | 28 +- arch/riscv/kernel/probes/uprobes.c | 6 - arch/riscv/lib/uaccess.S | 4 +- arch/riscv/mm/init.c | 4 + arch/s390/include/asm/gmap.h | 2 + arch/s390/include/asm/kexec.h | 3 + arch/s390/include/asm/unwind.h | 2 +- arch/s390/kernel/crash_dump.c | 2 +- arch/s390/kernel/machine_kexec_file.c | 18 +- arch/s390/kvm/intercept.c | 15 + arch/s390/kvm/pv.c | 9 +- arch/s390/kvm/sigp.c | 4 +- arch/s390/mm/gmap.c | 86 +++ arch/s390/mm/init.c | 4 +- arch/um/drivers/random.c | 2 +- arch/um/include/asm/archrandom.h | 30 + arch/um/include/asm/xor.h | 2 +- arch/um/include/shared/os.h | 7 + arch/um/kernel/um_arch.c | 8 + arch/um/os-Linux/util.c | 6 + arch/x86/Kconfig | 1 + arch/x86/Kconfig.debug | 3 - arch/x86/boot/Makefile | 2 +- arch/x86/boot/compressed/Makefile | 4 + arch/x86/crypto/Makefile | 4 +- arch/x86/crypto/blake2s-glue.c | 3 +- arch/x86/crypto/blake2s-shash.c | 77 -- arch/x86/entry/Makefile | 3 +- arch/x86/entry/thunk_32.S | 2 - arch/x86/entry/thunk_64.S | 4 - arch/x86/entry/vdso/Makefile | 2 +- arch/x86/events/intel/core.c | 7 +- arch/x86/events/intel/ds.c | 129 ++-- arch/x86/events/perf_event.h | 14 + arch/x86/include/asm/kexec.h | 6 + arch/x86/include/asm/kvm_host.h | 3 +- arch/x86/kernel/cpu/bugs.c | 10 +- arch/x86/kernel/cpu/intel.c | 27 +- arch/x86/kernel/ftrace.c | 1 + arch/x86/kernel/kprobes/core.c | 18 +- arch/x86/kernel/pmem.c | 7 +- arch/x86/kernel/process.c | 9 +- arch/x86/kvm/emulate.c | 23 +- arch/x86/kvm/mmu.h | 2 + arch/x86/kvm/mmu/mmu.c | 8 +- arch/x86/kvm/mmu/paging_tmpl.h | 9 +- arch/x86/kvm/mmu/spte.c | 22 + arch/x86/kvm/mmu/spte.h | 3 +- arch/x86/kvm/svm/nested.c | 3 +- arch/x86/kvm/svm/sev.c | 10 + arch/x86/kvm/svm/svm.c | 38 +- arch/x86/kvm/vmx/nested.c | 106 +-- arch/x86/kvm/vmx/nested.h | 3 +- arch/x86/kvm/vmx/pmu_intel.c | 13 +- arch/x86/kvm/vmx/vmx.c | 4 +- arch/x86/kvm/vmx/vmx.h | 12 + arch/x86/kvm/x86.c | 33 +- arch/x86/kvm/x86.h | 2 +- arch/x86/kvm/xen.c | 31 +- arch/x86/mm/extable.c | 16 +- arch/x86/mm/mem_encrypt_amd.c | 4 +- arch/x86/mm/numa.c | 4 +- arch/x86/net/bpf_jit_comp.c | 31 + arch/x86/platform/olpc/olpc-xo1-sci.c | 2 +- arch/x86/um/Makefile | 3 +- arch/x86/xen/enlighten_hvm.c | 4 +- arch/x86/xen/enlighten_pv.c | 5 +- arch/xtensa/platforms/iss/network.c | 42 +- block/bio.c | 99 +-- block/blk-iocost.c | 20 +- block/blk-iolatency.c | 18 +- block/blk-mq-debugfs.c | 3 + block/blk-rq-qos.h | 11 +- block/blk-wbt.c | 12 +- crypto/Kconfig | 20 +- crypto/Makefile | 1 - crypto/asymmetric_keys/public_key.c | 7 +- crypto/blake2s_generic.c | 75 -- crypto/tcrypt.c | 12 - crypto/testmgr.c | 24 - crypto/testmgr.h | 217 ------ drivers/acpi/acpi_lpss.c | 3 + drivers/acpi/apei/einj.c | 2 + drivers/acpi/bus.c | 1 + drivers/acpi/cppc_acpi.c | 54 +- drivers/acpi/ec.c | 82 +- drivers/acpi/processor_idle.c | 6 +- drivers/acpi/sleep.c | 8 + drivers/acpi/video_detect.c | 8 + drivers/acpi/viot.c | 26 +- drivers/android/binder.c | 114 ++- drivers/android/binder_alloc.c | 30 +- drivers/android/binder_alloc.h | 2 +- drivers/android/binder_alloc_selftest.c | 2 +- drivers/android/binder_internal.h | 46 +- drivers/android/binderfs.c | 47 +- drivers/base/dd.c | 5 +- drivers/base/node.c | 4 +- drivers/base/power/domain.c | 3 + drivers/base/topology.c | 32 +- drivers/block/mtip32xx/mtip32xx.c | 157 ++-- drivers/block/mtip32xx/mtip32xx.h | 1 - drivers/block/nbd.c | 6 +- drivers/block/null_blk/main.c | 14 +- drivers/block/rnbd/rnbd-srv.c | 3 +- drivers/block/xen-blkback/xenbus.c | 20 +- drivers/block/xen-blkfront.c | 4 +- drivers/bluetooth/hci_intel.c | 6 +- drivers/bluetooth/hci_serdev.c | 11 + drivers/bus/hisi_lpc.c | 10 +- drivers/char/tpm/tpm2-cmd.c | 6 + drivers/clk/imx/clk-fracn-gppll.c | 33 +- drivers/clk/imx/clk-imx93.c | 4 +- drivers/clk/mediatek/reset.c | 4 +- drivers/clk/qcom/camcc-sdm845.c | 4 + drivers/clk/qcom/camcc-sm8250.c | 16 +- drivers/clk/qcom/clk-krait.c | 7 +- drivers/clk/qcom/clk-rcg2.c | 16 +- drivers/clk/qcom/dispcc-sm8250.c | 1 - drivers/clk/qcom/gcc-ipq8074.c | 60 +- drivers/clk/qcom/gcc-msm8939.c | 33 +- drivers/clk/qcom/gdsc.c | 8 + drivers/clk/qcom/videocc-sm8250.c | 4 - drivers/clk/renesas/r9a06g032-clocks.c | 8 +- drivers/clk/renesas/rzg2l-cpg.c | 2 +- drivers/cpufreq/mediatek-cpufreq-hw.c | 7 +- drivers/cpufreq/mediatek-cpufreq.c | 1 + drivers/cpufreq/scmi-cpufreq.c | 6 + .../crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 1 + drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 16 +- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 10 +- drivers/crypto/ccp/sev-dev.c | 12 +- drivers/crypto/hisilicon/hpre/hpre_crypto.c | 2 +- drivers/crypto/hisilicon/sec/sec_algs.c | 14 +- drivers/crypto/hisilicon/sec/sec_drv.h | 2 +- drivers/crypto/hisilicon/sec2/sec.h | 2 +- drivers/crypto/hisilicon/sec2/sec_crypto.c | 26 +- drivers/crypto/hisilicon/sec2/sec_crypto.h | 1 + drivers/crypto/inside-secure/safexcel.c | 2 + drivers/dma/dw-edma/dw-edma-core.c | 2 +- drivers/dma/dw/rzn1-dmamux.c | 3 + drivers/dma/imx-dma.c | 2 +- drivers/dma/sf-pdma/sf-pdma.c | 44 +- drivers/firmware/arm_scpi.c | 61 +- drivers/firmware/tegra/bpmp-debugfs.c | 10 +- drivers/fpga/altera-pr-ip-core.c | 2 +- drivers/gpio/gpiolib-of.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 60 +- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 10 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 4 + drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 7 +- drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c | 21 - drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h | 1 - drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 21 - drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h | 1 - drivers/gpu/drm/amd/amdkfd/kfd_device.c | 2 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 + .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 17 +- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 52 +- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../amd/display/dc/dce110/dce110_hw_sequencer.c | 23 +- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c | 13 +- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h | 2 +- drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 4 +- drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 5 + .../drm/amd/display/dc/inc/hw_sequencer_private.h | 2 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 2 + drivers/gpu/drm/bridge/Kconfig | 3 + drivers/gpu/drm/bridge/adv7511/adv7511.h | 12 - drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 12 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 24 +- drivers/gpu/drm/bridge/analogix/anx7625.c | 21 +- drivers/gpu/drm/bridge/lontium-lt9611.c | 2 +- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 2 +- drivers/gpu/drm/bridge/sil-sii8620.c | 4 +- drivers/gpu/drm/bridge/tc358767.c | 34 +- drivers/gpu/drm/display/Kconfig | 2 +- drivers/gpu/drm/display/drm_dp_aux_bus.c | 4 +- drivers/gpu/drm/display/drm_dp_mst_topology.c | 7 +- drivers/gpu/drm/drm_edid.c | 1 + drivers/gpu/drm/drm_fb_helper.c | 27 +- drivers/gpu/drm/drm_gem.c | 4 +- drivers/gpu/drm/drm_gem_shmem_helper.c | 1 + drivers/gpu/drm/drm_mipi_dbi.c | 7 + drivers/gpu/drm/exynos/exynos7_drm_decon.c | 17 +- drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 2 + drivers/gpu/drm/i915/i915_gem.h | 4 - drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 10 +- drivers/gpu/drm/ingenic/ingenic-drm.h | 3 + drivers/gpu/drm/mcde/mcde_dsi.c | 1 + drivers/gpu/drm/mediatek/mtk_dpi.c | 33 +- drivers/gpu/drm/mediatek/mtk_dsi.c | 93 ++- drivers/gpu/drm/meson/meson_encoder_cvbs.c | 1 + drivers/gpu/drm/meson/meson_encoder_hdmi.c | 19 +- drivers/gpu/drm/mgag200/mgag200_mode.c | 10 + drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 - drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 13 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 12 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 36 +- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 6 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 6 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c | 3 +- drivers/gpu/drm/msm/hdmi/hdmi.c | 3 + drivers/gpu/drm/msm/msm_fence.c | 11 +- drivers/gpu/drm/msm/msm_gpu.h | 11 +- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 39 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 8 +- drivers/gpu/drm/nouveau/nouveau_display.c | 4 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c | 2 +- drivers/gpu/drm/panel/Kconfig | 2 + drivers/gpu/drm/radeon/.gitignore | 2 +- drivers/gpu/drm/radeon/Kconfig | 2 +- drivers/gpu/drm/radeon/Makefile | 2 +- drivers/gpu/drm/radeon/ni_dpm.c | 6 +- drivers/gpu/drm/radeon/radeon_device.c | 2 +- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 10 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 1 + drivers/gpu/drm/solomon/ssd130x-spi.c | 2 + drivers/gpu/drm/tegra/gem.c | 11 +- drivers/gpu/drm/tiny/st7735r.c | 1 + drivers/gpu/drm/vc4/vc4_crtc.c | 14 +- drivers/gpu/drm/vc4/vc4_dsi.c | 152 +++- drivers/gpu/drm/vc4/vc4_hdmi.c | 169 ++++- drivers/gpu/drm/vc4/vc4_hdmi.h | 8 + drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 7 +- drivers/gpu/drm/vc4/vc4_kms.c | 4 +- drivers/gpu/drm/vc4/vc4_plane.c | 30 +- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 6 +- drivers/gpu/drm/virtio/virtgpu_object.c | 4 +- drivers/gpu/drm/vkms/vkms_composer.c | 2 +- drivers/hid/amd-sfh-hid/amd_sfh_client.c | 2 + drivers/hid/amd-sfh-hid/amd_sfh_hid.c | 12 +- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 3 +- drivers/hid/hid-alps.c | 2 + drivers/hid/hid-cp2112.c | 5 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-input.c | 2 + drivers/hid/hid-mcp2221.c | 3 + drivers/hid/hid-nintendo.c | 1 + drivers/hid/wacom_sys.c | 2 +- drivers/hid/wacom_wac.c | 72 +- drivers/hwmon/dell-smm-hwmon.c | 8 + drivers/hwmon/drivetemp.c | 1 + drivers/hwmon/nct6775-core.c | 3 +- drivers/hwmon/nct6775-platform.c | 2 +- drivers/hwmon/nct6775.h | 2 + drivers/hwmon/sch56xx-common.c | 44 +- drivers/hwmon/sht15.c | 17 +- drivers/hwtracing/coresight/coresight-config.h | 2 + drivers/hwtracing/coresight/coresight-core.c | 1 + drivers/hwtracing/coresight/coresight-syscfg.c | 295 +++++-- drivers/hwtracing/coresight/coresight-syscfg.h | 13 + drivers/hwtracing/intel_th/msu-sink.c | 3 + drivers/hwtracing/intel_th/msu.c | 14 +- drivers/hwtracing/intel_th/pci.c | 25 +- drivers/i2c/busses/i2c-cadence.c | 10 +- drivers/i2c/busses/i2c-mxs.c | 2 +- drivers/i2c/busses/i2c-npcm7xx.c | 50 +- drivers/i2c/busses/i2c-qcom-geni.c | 2 +- drivers/i2c/i2c-core-base.c | 3 +- drivers/i2c/muxes/i2c-mux-gpmux.c | 1 + drivers/idle/intel_idle.c | 24 +- drivers/iio/accel/Kconfig | 2 + drivers/iio/accel/adxl313_core.c | 2 +- drivers/iio/accel/adxl355_core.c | 2 +- drivers/iio/accel/adxl367.c | 2 +- drivers/iio/accel/adxl367_spi.c | 8 +- drivers/iio/accel/bma220_spi.c | 2 +- drivers/iio/accel/bma400.h | 35 +- drivers/iio/accel/bma400_core.c | 250 +++++- drivers/iio/accel/bma400_i2c.c | 10 +- drivers/iio/accel/bma400_spi.c | 8 +- drivers/iio/accel/cros_ec_accel_legacy.c | 4 +- drivers/iio/accel/sca3000.c | 4 +- drivers/iio/accel/sca3300.c | 2 +- drivers/iio/adc/ad7266.c | 4 +- drivers/iio/adc/ad7280a.c | 2 +- drivers/iio/adc/ad7292.c | 2 +- drivers/iio/adc/ad7298.c | 2 +- drivers/iio/adc/ad7476.c | 5 +- drivers/iio/adc/ad7606.h | 4 +- drivers/iio/adc/ad7766.c | 5 +- drivers/iio/adc/ad7768-1.c | 4 +- drivers/iio/adc/ad7887.c | 5 +- drivers/iio/adc/ad7923.c | 4 +- drivers/iio/adc/ad7949.c | 2 +- drivers/iio/adc/adi-axi-adc.c | 7 +- drivers/iio/adc/hi8435.c | 2 +- drivers/iio/adc/ltc2496.c | 4 +- drivers/iio/adc/ltc2497.c | 4 +- drivers/iio/adc/max1027.c | 8 +- drivers/iio/adc/max11100.c | 4 +- drivers/iio/adc/max1118.c | 2 +- drivers/iio/adc/max1241.c | 2 +- drivers/iio/adc/mcp320x.c | 2 +- drivers/iio/adc/ti-adc0832.c | 2 +- drivers/iio/adc/ti-adc084s021.c | 4 +- drivers/iio/adc/ti-adc108s102.c | 4 +- drivers/iio/adc/ti-adc12138.c | 2 +- drivers/iio/adc/ti-adc128s052.c | 2 +- drivers/iio/adc/ti-adc161s626.c | 2 +- drivers/iio/adc/ti-ads124s08.c | 2 +- drivers/iio/adc/ti-ads131e08.c | 2 +- drivers/iio/adc/ti-ads7950.c | 4 +- drivers/iio/adc/ti-ads8344.c | 2 +- drivers/iio/adc/ti-ads8688.c | 2 +- drivers/iio/adc/ti-tlc4541.c | 4 +- drivers/iio/addac/ad74413r.c | 4 +- drivers/iio/amplifiers/ad8366.c | 4 +- .../iio/common/cros_ec_sensors/cros_ec_lid_angle.c | 4 +- .../iio/common/cros_ec_sensors/cros_ec_sensors.c | 6 +- .../common/cros_ec_sensors/cros_ec_sensors_core.c | 58 +- drivers/iio/common/ssp_sensors/ssp.h | 3 +- drivers/iio/dac/ad5064.c | 4 +- drivers/iio/dac/ad5360.c | 4 +- drivers/iio/dac/ad5421.c | 4 +- drivers/iio/dac/ad5449.c | 4 +- drivers/iio/dac/ad5504.c | 2 +- drivers/iio/dac/ad5592r-base.h | 4 +- drivers/iio/dac/ad5686.h | 6 +- drivers/iio/dac/ad5755.c | 4 +- drivers/iio/dac/ad5761.c | 4 +- drivers/iio/dac/ad5764.c | 4 +- drivers/iio/dac/ad5766.c | 2 +- drivers/iio/dac/ad5770r.c | 2 +- drivers/iio/dac/ad5791.c | 2 +- drivers/iio/dac/ad7293.c | 2 +- drivers/iio/dac/ad7303.c | 4 +- drivers/iio/dac/ad8801.c | 2 +- drivers/iio/dac/ltc2688.c | 4 +- drivers/iio/dac/mcp4922.c | 2 +- drivers/iio/dac/ti-dac082s085.c | 2 +- drivers/iio/dac/ti-dac5571.c | 2 +- drivers/iio/dac/ti-dac7311.c | 2 +- drivers/iio/dac/ti-dac7612.c | 4 +- drivers/iio/frequency/ad9523.c | 6 +- drivers/iio/frequency/adf4350.c | 6 +- drivers/iio/frequency/adf4371.c | 2 +- drivers/iio/frequency/admv1013.c | 2 +- drivers/iio/frequency/admv1014.c | 2 +- drivers/iio/frequency/admv4420.c | 2 +- drivers/iio/frequency/adrf6780.c | 2 +- drivers/iio/gyro/adis16080.c | 2 +- drivers/iio/gyro/adis16130.c | 2 +- drivers/iio/gyro/adxrs450.c | 2 +- drivers/iio/gyro/fxas21002c_core.c | 6 +- drivers/iio/imu/fxos8700_core.c | 2 +- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 2 +- drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h | 2 +- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 2 +- drivers/iio/industrialio-core.c | 22 +- drivers/iio/light/cros_ec_light_prox.c | 6 +- drivers/iio/light/isl29028.c | 2 +- drivers/iio/potentiometer/ad5110.c | 4 +- drivers/iio/potentiometer/ad5272.c | 2 +- drivers/iio/potentiometer/max5481.c | 2 +- drivers/iio/potentiometer/mcp41010.c | 2 +- drivers/iio/potentiometer/mcp4131.c | 2 +- drivers/iio/pressure/cros_ec_baro.c | 6 +- drivers/iio/proximity/as3935.c | 2 +- drivers/iio/proximity/sx9324.c | 4 +- drivers/iio/resolver/ad2s1200.c | 2 +- drivers/iio/resolver/ad2s90.c | 2 +- drivers/iio/temperature/ltc2983.c | 4 +- drivers/iio/temperature/max31865.c | 2 +- drivers/iio/temperature/maxim_thermocouple.c | 2 +- drivers/infiniband/hw/hfi1/file_ops.c | 4 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 +- drivers/infiniband/hw/irdma/cm.c | 11 +- drivers/infiniband/hw/irdma/hw.c | 15 +- drivers/infiniband/hw/irdma/verbs.c | 2 +- drivers/infiniband/hw/mlx5/fs.c | 6 +- drivers/infiniband/hw/qedr/verbs.c | 8 +- drivers/infiniband/sw/rxe/rxe_comp.c | 8 +- drivers/infiniband/sw/rxe/rxe_loc.h | 2 +- drivers/infiniband/sw/rxe/rxe_mr.c | 12 +- drivers/infiniband/sw/rxe/rxe_mw.c | 7 - drivers/infiniband/sw/rxe/rxe_pool.c | 4 +- drivers/infiniband/sw/rxe/rxe_qp.c | 23 +- drivers/infiniband/sw/rxe/rxe_req.c | 23 +- drivers/infiniband/sw/rxe/rxe_resp.c | 24 +- drivers/infiniband/sw/rxe/rxe_verbs.h | 1 + drivers/infiniband/sw/siw/siw_cm.c | 7 +- drivers/infiniband/ulp/iser/iscsi_iser.c | 4 +- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 35 +- drivers/infiniband/ulp/rtrs/rtrs-pri.h | 21 +- drivers/infiniband/ulp/srpt/ib_srpt.c | 148 +++- drivers/infiniband/ulp/srpt/ib_srpt.h | 18 +- drivers/input/serio/gscps2.c | 4 + drivers/interconnect/imx/imx.c | 8 +- drivers/iommu/arm/arm-smmu/qcom_iommu.c | 7 +- drivers/iommu/exynos-iommu.c | 6 +- drivers/iommu/intel/dmar.c | 2 +- drivers/irqchip/Kconfig | 5 +- drivers/irqchip/irq-mips-gic.c | 84 +- drivers/leds/rgb/leds-pwm-multicolor.c | 3 +- drivers/md/dm-raid.c | 5 +- drivers/md/dm-thin-metadata.c | 7 +- drivers/md/dm-thin.c | 4 +- drivers/md/dm-writecache.c | 43 +- drivers/md/dm.c | 18 +- drivers/md/md.c | 2 +- drivers/md/raid10.c | 5 +- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/ov7251.c | 2 + drivers/media/pci/sta2x11/Kconfig | 2 +- drivers/media/pci/tw686x/tw686x-core.c | 18 +- drivers/media/pci/tw686x/tw686x-video.c | 4 +- drivers/media/platform/amphion/vdec.c | 47 +- drivers/media/platform/amphion/vpu.h | 1 + drivers/media/platform/amphion/vpu_core.c | 7 +- drivers/media/platform/amphion/vpu_malone.c | 4 + drivers/media/platform/amphion/vpu_msgs.c | 7 +- drivers/media/platform/amphion/vpu_rpc.h | 7 +- drivers/media/platform/amphion/vpu_v4l2.c | 6 +- drivers/media/platform/atmel/atmel-sama7g5-isc.c | 2 + drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h | 2 + .../platform/mediatek/vcodec/mtk_vcodec_dec.c | 73 +- .../platform/mediatek/vcodec/mtk_vcodec_dec_drv.c | 5 + .../mediatek/vcodec/mtk_vcodec_dec_stateless.c | 7 + .../platform/mediatek/vcodec/mtk_vcodec_drv.h | 4 - drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c | 5 + drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h | 9 +- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 264 +++---- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h | 2 - drivers/media/platform/qcom/camss/camss-csid.c | 2 +- .../media/platform/renesas/rcar-vin/rcar-core.c | 2 +- drivers/media/usb/hdpvr/hdpvr-video.c | 2 +- drivers/media/v4l2-core/v4l2-async.c | 35 +- drivers/media/v4l2-core/v4l2-mem2mem.c | 2 +- drivers/memstick/core/ms_block.c | 11 +- drivers/mfd/max77620.c | 2 + drivers/mfd/t7l66xb.c | 6 +- drivers/misc/cardreader/rtsx_pcr.c | 6 +- drivers/misc/eeprom/idt_89hpesx.c | 8 +- drivers/misc/habanalabs/common/memory.c | 6 +- drivers/mmc/core/block.c | 28 +- drivers/mmc/core/quirks.h | 4 +- drivers/mmc/host/cavium-octeon.c | 1 + drivers/mmc/host/cavium-thunderx.c | 4 +- drivers/mmc/host/mxcmmc.c | 2 +- drivers/mmc/host/renesas_sdhi_core.c | 8 +- drivers/mmc/host/sdhci-of-at91.c | 9 +- drivers/mmc/host/sdhci-of-esdhc.c | 1 + drivers/mtd/devices/mtd_dataflash.c | 8 + drivers/mtd/devices/spear_smi.c | 10 +- drivers/mtd/devices/st_spi_fsm.c | 12 +- drivers/mtd/hyperbus/rpc-if.c | 8 +- drivers/mtd/maps/physmap-versatile.c | 2 + drivers/mtd/nand/raw/arasan-nand-controller.c | 16 +- drivers/mtd/nand/raw/meson_nand.c | 1 - drivers/mtd/parsers/ofpart_bcm4908.c | 3 + drivers/mtd/parsers/redboot.c | 1 + drivers/mtd/sm_ftl.c | 2 +- drivers/mtd/spi-nor/core.c | 6 +- drivers/net/can/dev/netlink.c | 6 +- drivers/net/can/pch_can.c | 8 +- drivers/net/can/rcar/rcar_can.c | 8 +- drivers/net/can/sja1000/sja1000.c | 7 +- drivers/net/can/spi/hi311x.c | 5 +- drivers/net/can/sun4i_can.c | 9 +- drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 12 +- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 6 +- drivers/net/can/usb/usb_8dev.c | 7 +- drivers/net/dsa/ocelot/Kconfig | 1 + drivers/net/dsa/ocelot/felix.c | 9 + drivers/net/dsa/ocelot/felix.h | 1 + drivers/net/dsa/ocelot/felix_vsc9959.c | 300 +++++++- drivers/net/ethernet/atheros/ag71xx.c | 2 +- drivers/net/ethernet/huawei/hinic/hinic_dev.h | 3 - drivers/net/ethernet/huawei/hinic/hinic_main.c | 68 +- drivers/net/ethernet/huawei/hinic/hinic_rx.c | 2 - drivers/net/ethernet/huawei/hinic/hinic_tx.c | 2 - drivers/net/ethernet/intel/iavf/iavf.h | 6 + drivers/net/ethernet/intel/iavf/iavf_main.c | 46 +- drivers/net/ethernet/intel/ice/ice_main.c | 2 +- drivers/net/ethernet/intel/ice/ice_switch.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/en.h | 21 +- .../net/ethernet/mellanox/mlx5/core/en/params.c | 12 + .../ethernet/mellanox/mlx5/core/en/tc/post_act.c | 1 + .../net/ethernet/mellanox/mlx5/core/en/xsk/rx.h | 14 + .../ethernet/mellanox/mlx5/core/en_accel/ktls.c | 2 +- .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 23 +- drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c | 11 +- drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h | 1 - drivers/net/ethernet/mellanox/mlx5/core/main.c | 4 +- .../ethernet/mellanox/mlx5/core/steering/dr_dbg.c | 13 +- drivers/net/ethernet/mscc/ocelot.c | 1 + drivers/net/ethernet/mscc/ocelot_ptp.c | 8 + drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 +- drivers/net/netdevsim/bpf.c | 8 +- drivers/net/netdevsim/fib.c | 27 +- drivers/net/usb/Kconfig | 3 +- drivers/net/usb/ax88179_178a.c | 26 +- drivers/net/usb/smsc95xx.c | 26 +- drivers/net/usb/usbnet.c | 8 +- drivers/net/wireguard/allowedips.c | 9 +- drivers/net/wireguard/selftest/allowedips.c | 6 +- drivers/net/wireguard/selftest/ratelimiter.c | 25 +- drivers/net/wireless/ath/ath10k/htt_rx.c | 2 +- drivers/net/wireless/ath/ath10k/mac.c | 8 +- drivers/net/wireless/ath/ath10k/snoc.c | 5 +- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 +- drivers/net/wireless/ath/ath10k/wmi.c | 2 +- drivers/net/wireless/ath/ath11k/ahb.c | 56 +- drivers/net/wireless/ath/ath11k/core.c | 30 +- drivers/net/wireless/ath/ath11k/debug.h | 4 +- drivers/net/wireless/ath/ath11k/dp_rx.c | 5 +- drivers/net/wireless/ath/ath11k/htc.c | 4 +- drivers/net/wireless/ath/ath11k/hw.h | 2 - drivers/net/wireless/ath/ath11k/mac.c | 25 +- drivers/net/wireless/ath/ath11k/pci.c | 72 +- drivers/net/wireless/ath/ath11k/pcic.c | 57 +- drivers/net/wireless/ath/ath11k/pcic.h | 2 + drivers/net/wireless/ath/ath11k/wmi.c | 4 +- drivers/net/wireless/ath/ath6kl/cfg80211.c | 6 +- drivers/net/wireless/ath/ath9k/beacon.c | 2 +- drivers/net/wireless/ath/ath9k/htc.h | 10 +- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 +- drivers/net/wireless/ath/wil6210/cfg80211.c | 9 +- drivers/net/wireless/ath/wil6210/debugfs.c | 18 +- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 4 +- drivers/net/wireless/intel/iwlegacy/4965-rs.c | 5 +- drivers/net/wireless/intel/iwlwifi/mvm/coex.c | 6 +- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 +- .../net/wireless/intel/iwlwifi/mvm/debugfs-vif.c | 4 +- .../net/wireless/intel/iwlwifi/mvm/ftm-responder.c | 4 +- drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 10 +- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 10 +- drivers/net/wireless/intel/iwlwifi/mvm/power.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 1 + drivers/net/wireless/intel/iwlwifi/mvm/tdls.c | 4 +- .../net/wireless/intel/iwlwifi/mvm/time-event.c | 4 +- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 2 +- drivers/net/wireless/intersil/p54/main.c | 2 +- drivers/net/wireless/intersil/p54/p54spi.c | 3 +- drivers/net/wireless/mac80211_hwsim.c | 36 +- drivers/net/wireless/marvell/libertas/if_usb.c | 1 + drivers/net/wireless/marvell/libertas/mesh.c | 10 +- drivers/net/wireless/marvell/mwifiex/11h.c | 2 +- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 18 +- drivers/net/wireless/mediatek/mt76/eeprom.c | 5 +- drivers/net/wireless/mediatek/mt76/mac80211.c | 5 +- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 7 +- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 21 - drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 14 +- drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h | 1 - drivers/net/wireless/mediatek/mt76/mt76_connac.h | 6 + .../net/wireless/mediatek/mt76/mt76_connac2_mac.h | 167 ++++ .../net/wireless/mediatek/mt76/mt76_connac_mac.c | 284 +++++++ .../net/wireless/mediatek/mt76/mt76x02_usb_mcu.c | 2 +- .../net/wireless/mediatek/mt76/mt7915/debugfs.c | 5 +- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 260 +------ drivers/net/wireless/mediatek/mt76/mt7915/mac.h | 142 +--- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 16 +- drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h | 17 +- .../net/wireless/mediatek/mt76/mt7915/testmode.c | 9 +- drivers/net/wireless/mediatek/mt76/mt7921/init.c | 6 +- drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 213 +----- drivers/net/wireless/mediatek/mt76/mt7921/mac.h | 123 +-- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 25 +- drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h | 15 - .../net/wireless/mediatek/mt76/mt7921/pci_mac.c | 4 +- .../net/wireless/mediatek/mt76/mt7921/pci_mcu.c | 6 +- .../net/wireless/mediatek/mt76/mt7921/sdio_mcu.c | 10 +- drivers/net/wireless/microchip/wilc1000/cfg80211.c | 3 +- drivers/net/wireless/microchip/wilc1000/spi.c | 6 +- drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 14 +- drivers/net/wireless/quantenna/qtnfmac/commands.c | 2 +- drivers/net/wireless/quantenna/qtnfmac/event.c | 15 +- drivers/net/wireless/realtek/rtlwifi/debug.c | 8 +- drivers/net/wireless/realtek/rtw88/main.c | 4 + drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c | 4 +- drivers/net/wireless/ti/wlcore/main.c | 2 +- drivers/nvme/host/core.c | 14 +- drivers/nvme/host/multipath.c | 1 + drivers/nvme/host/trace.h | 2 +- drivers/of/device.c | 5 +- drivers/of/fdt.c | 2 +- drivers/of/kexec.c | 17 + drivers/opp/core.c | 4 +- drivers/opp/of.c | 15 +- drivers/parisc/lba_pci.c | 6 +- drivers/pci/controller/dwc/pcie-designware-ep.c | 18 +- drivers/pci/controller/dwc/pcie-designware-host.c | 30 +- drivers/pci/controller/dwc/pcie-designware.c | 46 +- drivers/pci/controller/dwc/pcie-qcom.c | 58 +- drivers/pci/controller/dwc/pcie-tegra194.c | 49 +- drivers/pci/controller/pcie-mediatek-gen3.c | 7 +- drivers/pci/controller/pcie-microchip-host.c | 2 + drivers/pci/endpoint/functions/pci-epf-test.c | 1 - drivers/pci/pcie/aer.c | 7 +- drivers/pci/pcie/portdrv_core.c | 9 +- drivers/perf/arm_spe_pmu.c | 22 +- drivers/perf/riscv_pmu.c | 1 - drivers/perf/riscv_pmu_sbi.c | 21 +- drivers/phy/qualcomm/phy-qcom-qmp.h | 3 +- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 10 +- drivers/phy/samsung/phy-exynosautov9-ufs.c | 18 +- drivers/phy/st/phy-stm32-usbphyc.c | 4 +- drivers/phy/ti/phy-tusb1210.c | 5 +- drivers/platform/chrome/cros_ec.c | 8 +- drivers/platform/mellanox/mlxreg-lc.c | 82 +- drivers/platform/olpc/olpc-ec.c | 2 +- drivers/platform/x86/pmc_atom.c | 19 +- drivers/powercap/dtpm_cpu.c | 5 +- drivers/pwm/pwm-lpc18xx-sct.c | 55 +- drivers/pwm/pwm-sifive.c | 61 +- drivers/regulator/of_regulator.c | 6 +- drivers/regulator/qcom_smd-regulator.c | 4 +- drivers/remoteproc/imx_rproc.c | 7 +- drivers/remoteproc/qcom_q6v5_pas.c | 3 + drivers/remoteproc/qcom_sysmon.c | 10 + drivers/remoteproc/qcom_wcnss.c | 10 +- drivers/remoteproc/ti_k3_r5_remoteproc.c | 2 + drivers/rpmsg/mtk_rpmsg.c | 2 + drivers/rpmsg/qcom_smd.c | 1 + drivers/rpmsg/rpmsg_char.c | 7 +- drivers/rpmsg/rpmsg_core.c | 1 + drivers/rtc/rtc-rx8025.c | 22 +- drivers/s390/char/zcore.c | 11 +- drivers/s390/cio/vfio_ccw_drv.c | 24 +- drivers/s390/cio/vfio_ccw_fsm.c | 26 +- drivers/s390/cio/vfio_ccw_ops.c | 10 +- drivers/s390/scsi/zfcp_fc.c | 29 +- drivers/s390/scsi/zfcp_fc.h | 6 +- drivers/s390/scsi/zfcp_fsf.c | 4 +- drivers/scsi/be2iscsi/be_main.c | 2 +- drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +- drivers/scsi/cxgbi/libcxgbi.c | 2 +- drivers/scsi/iscsi_tcp.c | 4 +- drivers/scsi/libiscsi.c | 9 +- drivers/scsi/lpfc/lpfc.h | 1 - drivers/scsi/lpfc/lpfc_els.c | 8 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 3 +- drivers/scsi/lpfc/lpfc_scsi.c | 1 - drivers/scsi/qedi/qedi_main.c | 9 +- drivers/scsi/qla2xxx/qla_attr.c | 24 +- drivers/scsi/qla2xxx/qla_bsg.c | 10 +- drivers/scsi/qla2xxx/qla_dbg.h | 2 +- drivers/scsi/qla2xxx/qla_def.h | 18 +- drivers/scsi/qla2xxx/qla_edif.c | 502 +++++++++--- drivers/scsi/qla2xxx/qla_edif.h | 7 +- drivers/scsi/qla2xxx/qla_edif_bsg.h | 106 ++- drivers/scsi/qla2xxx/qla_fw.h | 2 +- drivers/scsi/qla2xxx/qla_gbl.h | 6 +- drivers/scsi/qla2xxx/qla_gs.c | 129 +++- drivers/scsi/qla2xxx/qla_init.c | 93 ++- drivers/scsi/qla2xxx/qla_iocb.c | 5 +- drivers/scsi/qla2xxx/qla_isr.c | 25 +- drivers/scsi/qla2xxx/qla_mbx.c | 19 +- drivers/scsi/qla2xxx/qla_mid.c | 6 +- drivers/scsi/qla2xxx/qla_nvme.c | 5 - drivers/scsi/qla2xxx/qla_os.c | 93 ++- drivers/scsi/qla2xxx/qla_target.c | 35 +- drivers/scsi/scsi_transport_iscsi.c | 66 +- drivers/scsi/sd.c | 84 +- drivers/scsi/sd.h | 5 + drivers/scsi/sg.c | 53 +- drivers/scsi/smartpqi/smartpqi_init.c | 4 +- drivers/soc/amlogic/meson-mx-socinfo.c | 1 + drivers/soc/amlogic/meson-secure-pwrc.c | 4 +- drivers/soc/fsl/guts.c | 2 +- drivers/soc/qcom/Kconfig | 1 + drivers/soc/qcom/ocmem.c | 3 + drivers/soc/qcom/qcom_aoss.c | 4 +- drivers/soc/qcom/socinfo.c | 3 +- drivers/soc/renesas/r8a779a0-sysc.c | 10 +- drivers/soundwire/bus.c | 75 +- drivers/soundwire/bus_type.c | 38 +- drivers/soundwire/qcom.c | 4 + drivers/soundwire/slave.c | 3 +- drivers/soundwire/stream.c | 53 +- drivers/spi/spi-altera-dfl.c | 14 +- drivers/spi/spi-dw.h | 2 +- drivers/spi/spi-s3c64xx.c | 2 +- drivers/spi/spi-synquacer.c | 1 + drivers/spi/spi-tegra20-slink.c | 3 +- drivers/spi/spi.c | 21 +- drivers/staging/fbtft/fbtft-core.c | 2 +- drivers/staging/media/atomisp/pci/atomisp_cmd.c | 57 +- .../media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c | 4 +- drivers/staging/media/hantro/hantro_g2_hevc_dec.c | 7 +- drivers/staging/media/hantro/hantro_g2_regs.h | 2 +- drivers/staging/media/hantro/hantro_hevc.c | 25 +- drivers/staging/media/hantro/hantro_hw.h | 17 +- drivers/staging/media/hantro/hantro_v4l2.c | 2 +- drivers/staging/media/hantro/imx8m_vpu_hw.c | 80 +- drivers/staging/media/hantro/rockchip_vpu_hw.c | 164 ++-- drivers/staging/media/hantro/sama5d4_vdec_hw.c | 40 +- drivers/staging/media/hantro/sunxi_vpu_hw.c | 24 +- drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 36 +- drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 3 +- drivers/staging/rtl8192u/r8192U.h | 2 +- drivers/staging/rtl8192u/r8192U_dm.c | 38 +- drivers/staging/rtl8192u/r8192U_dm.h | 2 +- drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 4 +- drivers/thermal/cpufreq_cooling.c | 13 +- drivers/thermal/devfreq_cooling.c | 19 +- drivers/thermal/thermal_sysfs.c | 10 +- drivers/tty/n_gsm.c | 757 ++++++++++++------ drivers/tty/serial/8250/8250.h | 20 + drivers/tty/serial/8250/8250_bcm2835aux.c | 6 +- drivers/tty/serial/8250/8250_bcm7271.c | 24 +- drivers/tty/serial/8250/8250_core.c | 3 +- drivers/tty/serial/8250/8250_dw.c | 10 +- drivers/tty/serial/8250/8250_fsl.c | 2 +- drivers/tty/serial/8250/8250_pci.c | 109 +++ drivers/tty/serial/8250/8250_port.c | 17 +- drivers/tty/serial/fsl_lpuart.c | 12 +- drivers/tty/serial/mvebu-uart.c | 11 + drivers/tty/serial/pic32_uart.c | 4 +- drivers/tty/serial/qcom_geni_serial.c | 88 ++- drivers/tty/vt/vt.c | 2 +- drivers/ufs/core/ufshcd.c | 6 +- drivers/usb/cdns3/cdns3-gadget.c | 13 +- drivers/usb/core/hcd.c | 34 +- drivers/usb/dwc3/core.c | 9 +- drivers/usb/dwc3/dwc3-qcom.c | 4 +- drivers/usb/dwc3/gadget.c | 92 +-- drivers/usb/gadget/function/f_mass_storage.c | 11 +- drivers/usb/gadget/function/f_uvc.c | 30 +- drivers/usb/gadget/function/uvc_queue.c | 6 +- drivers/usb/gadget/function/uvc_video.c | 12 +- drivers/usb/gadget/udc/Kconfig | 2 +- drivers/usb/gadget/udc/aspeed-vhub/hub.c | 4 +- drivers/usb/gadget/udc/core.c | 11 +- drivers/usb/gadget/udc/tegra-xudc.c | 8 +- drivers/usb/host/ehci-ppc-of.c | 1 + drivers/usb/host/ohci-at91.c | 69 +- drivers/usb/host/ohci-nxp.c | 1 + drivers/usb/host/xhci-tegra.c | 8 +- drivers/usb/host/xhci.h | 2 +- drivers/usb/serial/sierra.c | 3 +- drivers/usb/serial/usb-serial.c | 2 +- drivers/usb/serial/usb_wwan.c | 3 +- drivers/usb/typec/ucsi/ucsi.c | 4 + drivers/usb/usbip/vudc_sysfs.c | 14 +- drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 11 +- drivers/vfio/pci/mlx5/cmd.c | 14 +- drivers/vfio/pci/mlx5/cmd.h | 4 +- drivers/vfio/pci/mlx5/main.c | 11 +- drivers/vfio/pci/vfio_pci_core.c | 7 + drivers/vfio/vfio.c | 11 +- drivers/video/fbdev/amba-clcd.c | 24 +- drivers/video/fbdev/arkfb.c | 9 +- drivers/video/fbdev/core/fbcon.c | 12 +- drivers/video/fbdev/offb.c | 1 + drivers/video/fbdev/s3fb.c | 2 + drivers/video/fbdev/sis/init.c | 4 +- drivers/video/fbdev/vt8623fb.c | 2 + drivers/virtio/Kconfig | 4 + drivers/virtio/Makefile | 1 + drivers/virtio/virtio.c | 4 +- drivers/virtio/virtio_anchor.c | 18 + drivers/watchdog/armada_37xx_wdt.c | 2 + drivers/watchdog/f71808e_wdt.c | 4 +- drivers/watchdog/sp5100_tco.c | 1 + drivers/xen/Kconfig | 9 + drivers/xen/grant-dma-ops.c | 10 + fs/Makefile | 2 - fs/attr.c | 2 + fs/btrfs/block-group.c | 29 +- fs/btrfs/ctree.h | 34 +- fs/btrfs/delalloc-space.c | 6 +- fs/btrfs/disk-io.c | 38 +- fs/btrfs/extent-tree.c | 71 +- fs/btrfs/extent_io.c | 4 +- fs/btrfs/file.c | 2 +- fs/btrfs/inode.c | 177 ++++- fs/btrfs/raid56.c | 26 +- fs/btrfs/space-info.c | 108 ++- fs/btrfs/space-info.h | 8 +- fs/btrfs/tree-log.c | 27 +- fs/btrfs/tree-log.h | 3 + fs/btrfs/volumes.c | 28 +- fs/btrfs/zoned.c | 125 +++ fs/btrfs/zoned.h | 18 + fs/cifs/cifsglob.h | 4 +- fs/cifs/file.c | 34 +- fs/erofs/decompressor.c | 16 +- fs/erofs/decompressor_lzma.c | 1 + fs/erofs/dir.c | 16 +- fs/eventpoll.c | 22 + fs/exec.c | 3 + fs/ext2/super.c | 12 +- fs/ext4/ext4.h | 1 + fs/ext4/inline.c | 33 + fs/ext4/inode.c | 24 +- fs/ext4/migrate.c | 4 +- fs/ext4/namei.c | 23 + fs/ext4/resize.c | 1 + fs/ext4/symlink.c | 15 + fs/ext4/xattr.c | 168 ++-- fs/ext4/xattr.h | 14 + fs/f2fs/data.c | 7 +- fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 19 +- fs/fuse/control.c | 4 +- fs/fuse/dir.c | 7 +- fs/fuse/file.c | 39 +- fs/fuse/inode.c | 6 + fs/fuse/ioctl.c | 15 +- fs/jbd2/commit.c | 2 +- fs/jbd2/transaction.c | 14 +- fs/kernfs/dir.c | 7 +- fs/ksmbd/smb2misc.c | 12 +- fs/ksmbd/smb2pdu.c | 52 +- fs/ksmbd/smbacl.c | 130 +++- fs/ksmbd/smbacl.h | 2 +- fs/ksmbd/vfs.c | 5 + fs/lockd/svc4proc.c | 8 + fs/lockd/xdr4.c | 19 +- fs/mbcache.c | 76 +- fs/namei.c | 4 + fs/nfs/flexfilelayout/flexfilelayout.c | 4 + fs/nfs/nfs3client.c | 1 - fs/nfsd/filecache.c | 22 +- fs/nfsd/filecache.h | 4 +- fs/nfsd/trace.h | 2 - fs/overlayfs/export.c | 2 +- fs/proc/base.c | 46 +- fs/splice.c | 10 +- include/acpi/cppc_acpi.h | 2 +- include/crypto/internal/blake2s.h | 108 --- include/dt-bindings/clock/qcom,gcc-msm8939.h | 1 + include/linux/acpi_viot.h | 2 + include/linux/blkdev.h | 5 + include/linux/bpf.h | 1 - include/linux/buffer_head.h | 25 +- include/linux/cpumask.h | 18 + include/linux/device-mapper.h | 6 + include/linux/energy_model.h | 54 +- include/linux/filter.h | 9 + include/linux/hugetlb.h | 6 +- include/linux/ieee80211.h | 3 + include/linux/iio/common/cros_ec_sensors_core.h | 7 +- include/linux/iio/iio.h | 10 +- include/linux/kexec.h | 45 +- include/linux/kfifo.h | 2 +- include/linux/kvm_types.h | 2 + include/linux/lockd/xdr.h | 2 + include/linux/lockdep.h | 30 +- include/linux/mbcache.h | 10 +- include/linux/mdev.h | 5 - include/linux/mfd/t7l66xb.h | 1 - include/linux/once_lite.h | 20 +- include/linux/pipe_fs_i.h | 9 + include/linux/platform-feature.h | 6 +- include/linux/rmap.h | 4 +- include/linux/sched.h | 2 +- include/linux/sched/rt.h | 8 - include/linux/sched/topology.h | 1 + include/linux/soundwire/sdw.h | 6 +- include/linux/swapops.h | 12 +- include/linux/tpm_eventlog.h | 2 +- include/linux/trace_events.h | 18 + include/linux/usb/hcd.h | 1 + include/linux/vfio.h | 30 +- include/linux/virtio_anchor.h | 19 + include/linux/wait.h | 9 +- include/media/hevc-ctrls.h | 4 +- include/net/9p/client.h | 8 +- include/net/ax25.h | 1 + include/net/bluetooth/hci.h | 1 + include/net/cfg80211.h | 99 ++- include/net/inet6_hashtables.h | 7 +- include/net/inet_hashtables.h | 19 +- include/net/inet_sock.h | 11 + include/net/ip_tunnels.h | 1 + include/net/mac80211.h | 40 +- include/net/netfilter/nf_tables.h | 9 +- include/net/pkt_sched.h | 17 + include/net/raw.h | 16 +- include/net/rawv6.h | 7 +- include/net/sock.h | 12 +- include/net/xdp_sock_drv.h | 11 + include/scsi/libiscsi.h | 2 +- include/scsi/scsi_transport_iscsi.h | 1 + include/soc/mscc/ocelot.h | 6 + include/trace/events/io_uring.h | 2 +- include/trace/events/spmi.h | 12 +- include/trace/stages/stage1_struct_define.h | 3 + include/trace/stages/stage2_data_offsets.h | 3 + include/trace/stages/stage4_event_fields.h | 11 +- include/trace/stages/stage5_get_offsets.h | 4 + include/trace/stages/stage6_event_callback.h | 12 + include/uapi/linux/can/error.h | 5 +- include/uapi/linux/dm-ioctl.h | 4 +- include/uapi/linux/netfilter/xt_IDLETIMER.h | 17 +- include/uapi/linux/nl80211.h | 28 + include/xen/xen-ops.h | 9 + include/xen/xen.h | 8 - init/main.c | 1 + io_uring/Makefile | 6 + {fs => io_uring}/io-wq.c | 0 {fs => io_uring}/io-wq.h | 0 {fs => io_uring}/io_uring.c | 844 +++++++++------------ kernel/bpf/arraymap.c | 20 +- kernel/bpf/cgroup.c | 70 +- kernel/bpf/core.c | 35 +- kernel/bpf/verifier.c | 7 +- kernel/cgroup/cpuset.c | 2 +- kernel/dma/swiotlb.c | 2 +- kernel/irq/Kconfig | 1 + kernel/irq/chip.c | 3 +- kernel/irq/irqdomain.c | 2 + kernel/kexec_file.c | 66 +- kernel/kprobes.c | 3 +- kernel/locking/lockdep.c | 7 +- kernel/power/energy_model.c | 24 +- kernel/power/user.c | 13 +- kernel/profile.c | 7 + kernel/rcu/rcutorture.c | 28 +- kernel/sched/core.c | 190 +++-- kernel/sched/fair.c | 142 +++- kernel/sched/features.h | 3 +- kernel/sched/rt.c | 15 +- kernel/sched/sched.h | 1 - kernel/smp.c | 4 +- kernel/time/hrtimer.c | 1 + kernel/time/timekeeping.c | 7 +- kernel/trace/blktrace.c | 2 +- lib/bitmap.c | 2 +- lib/crypto/blake2s-selftest.c | 41 + lib/crypto/blake2s.c | 37 +- lib/iov_iter.c | 15 +- lib/kunit/executor.c | 4 +- lib/livepatch/test_klp_callbacks_busy.c | 8 + lib/overflow_kunit.c | 6 + lib/smp_processor_id.c | 2 +- lib/test_bpf.c | 4 +- lib/test_hmm.c | 10 +- lib/test_kasan.c | 10 + mm/damon/reclaim.c | 4 +- mm/gup.c | 2 +- mm/huge_memory.c | 11 +- mm/hugetlb.c | 15 +- mm/hugetlb_cgroup.c | 1 + mm/kasan/hw_tags.c | 32 +- mm/memory-failure.c | 2 +- mm/memory_hotplug.c | 2 +- mm/mempolicy.c | 4 +- mm/memremap.c | 2 +- mm/migrate.c | 30 +- mm/mmap.c | 1 - mm/percpu.c | 6 +- mm/usercopy.c | 2 +- mm/vmalloc.c | 10 +- net/9p/client.c | 36 +- net/9p/trans_fd.c | 13 +- net/9p/trans_rdma.c | 2 +- net/9p/trans_virtio.c | 4 +- net/9p/trans_xen.c | 2 +- net/ax25/af_ax25.c | 4 +- net/batman-adv/trace.h | 9 +- net/bluetooth/hci_core.c | 10 +- net/bluetooth/hci_event.c | 5 +- net/bluetooth/hci_sync.c | 8 +- net/bluetooth/l2cap_core.c | 13 +- net/bluetooth/mgmt.c | 10 +- net/core/filter.c | 3 +- net/core/skmsg.c | 4 +- net/dccp/proto.c | 10 +- net/ipv4/af_inet.c | 2 + net/ipv4/ping.c | 36 +- net/ipv4/raw.c | 164 ++-- net/ipv4/raw_diag.c | 53 +- net/ipv4/tcp.c | 33 +- net/ipv4/tcp_output.c | 30 +- net/ipv6/af_inet6.c | 3 + net/ipv6/raw.c | 120 ++- net/mac80211/airtime.c | 4 +- net/mac80211/cfg.c | 48 +- net/mac80211/chan.c | 39 +- net/mac80211/driver-ops.h | 2 +- net/mac80211/ethtool.c | 4 +- net/mac80211/ibss.c | 10 +- net/mac80211/ieee80211_i.h | 6 +- net/mac80211/iface.c | 8 +- net/mac80211/key.c | 18 +- net/mac80211/main.c | 4 +- net/mac80211/mesh.c | 14 +- net/mac80211/mlme.c | 44 +- net/mac80211/ocb.c | 3 +- net/mac80211/offchannel.c | 6 +- net/mac80211/rate.c | 5 +- net/mac80211/rx.c | 2 +- net/mac80211/sta_info.c | 4 +- net/mac80211/tdls.c | 6 +- net/mac80211/tx.c | 28 +- net/mac80211/util.c | 16 +- net/mac80211/vht.c | 6 +- net/mptcp/protocol.c | 3 +- net/netfilter/nf_tables_api.c | 100 +-- net/netfilter/nft_bitwise.c | 66 +- net/netfilter/nft_cmp.c | 44 +- net/netfilter/nft_immediate.c | 22 +- net/netfilter/nft_range.c | 27 +- net/rose/af_rose.c | 11 +- net/rose/rose_route.c | 2 + net/sched/cls_route.c | 2 +- net/wireless/ap.c | 46 +- net/wireless/chan.c | 206 +++-- net/wireless/core.c | 28 +- net/wireless/core.h | 13 +- net/wireless/ibss.c | 57 +- net/wireless/mesh.c | 31 +- net/wireless/mlme.c | 75 +- net/wireless/nl80211.c | 656 +++++++++++----- net/wireless/ocb.c | 5 +- net/wireless/rdev-ops.h | 32 +- net/wireless/reg.c | 139 ++-- net/wireless/scan.c | 8 +- net/wireless/sme.c | 102 +-- net/wireless/trace.h | 86 ++- net/wireless/util.c | 44 +- net/wireless/wext-compat.c | 48 +- net/wireless/wext-sme.c | 29 +- samples/bpf/xdp_router_ipv4.bpf.c | 9 + scripts/faddr2line | 4 +- scripts/gdb/linux/dmesg.py | 9 +- scripts/gdb/linux/utils.py | 14 +- security/selinux/ss/policydb.h | 2 + security/selinux/ss/services.c | 9 +- sound/pci/hda/patch_cirrus.c | 1 + sound/pci/hda/patch_conexant.c | 11 +- sound/pci/hda/patch_realtek.c | 124 +++ sound/soc/amd/yc/acp6x-mach.c | 32 +- sound/soc/amd/yc/pci-acp6x.c | 2 +- sound/soc/atmel/mchp-spdifrx.c | 9 +- sound/soc/codecs/cros_ec_codec.c | 1 + sound/soc/codecs/cs35l45.c | 2 + sound/soc/codecs/da7210.c | 2 + sound/soc/codecs/max98390.c | 2 +- sound/soc/codecs/msm8916-wcd-digital.c | 46 +- sound/soc/codecs/mt6359-accdet.c | 1 + sound/soc/codecs/mt6359.c | 1 + sound/soc/codecs/wcd9335.c | 81 +- sound/soc/codecs/wsa881x.c | 10 +- sound/soc/fsl/fsl-asoc-card.c | 5 +- sound/soc/fsl/fsl_asrc.c | 6 +- sound/soc/fsl/fsl_easrc.c | 9 +- sound/soc/fsl/fsl_easrc.h | 2 +- sound/soc/fsl/imx-audmux.c | 2 +- sound/soc/fsl/imx-card.c | 22 +- sound/soc/generic/audio-graph-card.c | 4 +- sound/soc/generic/audio-graph-card2.c | 44 +- sound/soc/intel/boards/sof_rt5682.c | 18 +- sound/soc/mediatek/mt6797/mt6797-mt6351.c | 6 +- sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 10 +- sound/soc/mediatek/mt8173/mt8173-rt5650.c | 9 +- sound/soc/qcom/lpass-cpu.c | 1 + sound/soc/qcom/qdsp6/q6adm.c | 2 +- sound/soc/samsung/aries_wm8994.c | 6 +- sound/soc/samsung/h1940_uda1380.c | 2 +- sound/soc/samsung/rx1950_uda1380.c | 4 +- sound/soc/soc-core.c | 18 +- sound/soc/sof/ipc3-topology.c | 1 + sound/soc/sof/mediatek/mt8195/mt8195-loader.c | 2 +- sound/soc/sof/sof-client-ipc-msg-injector.c | 29 +- sound/soc/sof/sof-priv.h | 4 +- sound/usb/bcd2000/bcd2000.c | 3 +- sound/usb/quirks.c | 2 + tools/lib/bpf/bpf_tracing.h | 2 +- tools/lib/bpf/gen_loader.c | 2 +- tools/lib/bpf/libbpf.c | 154 ++-- tools/lib/bpf/libbpf_internal.h | 11 +- tools/lib/bpf/linker.c | 5 - tools/lib/bpf/usdt.c | 123 +-- tools/lib/bpf/xsk.c | 9 +- tools/perf/builtin-stat.c | 30 - tools/perf/tests/shell/stat+csv_output.sh | 7 +- tools/perf/util/dsos.c | 15 +- tools/perf/util/genelf.c | 6 +- tools/perf/util/symbol-elf.c | 27 +- tools/power/x86/intel-speed-select/isst-daemon.c | 2 +- tools/power/x86/turbostat/turbostat.c | 2 +- tools/testing/selftests/bpf/Makefile | 21 +- tools/testing/selftests/bpf/prog_tests/btf.c | 2 +- .../selftests/bpf/prog_tests/fexit_stress.c | 32 +- .../testing/selftests/bpf/prog_tests/sock_fields.c | 1 - .../testing/selftests/bpf/prog_tests/tc_redirect.c | 8 +- tools/testing/selftests/bpf/progs/test_tc_dtime.c | 53 +- .../selftests/kvm/lib/s390x/diag318_test_handler.c | 9 +- tools/testing/selftests/kvm/lib/x86_64/processor.c | 2 +- .../testing/selftests/kvm/max_guest_memory_test.c | 26 +- tools/testing/selftests/net/fib_rule_tests.sh | 23 + tools/testing/selftests/powerpc/math/mma.S | 3 + .../selftests/powerpc/papr_attributes/attr_test.c | 30 +- tools/testing/selftests/rcutorture/bin/kvm.sh | 6 +- tools/testing/selftests/seccomp/seccomp_bpf.c | 2 +- .../testing/selftests/timers/clocksource-switch.c | 6 +- tools/testing/selftests/timers/valid-adjtimex.c | 2 +- tools/testing/selftests/vm/hugepage-mremap.c | 2 +- tools/testing/selftests/vm/hugetlb-madvise.c | 5 +- tools/testing/selftests/vm/mrelease_test.c | 16 +- .../selftests/wireguard/qemu/arch/riscv32.config | 1 + tools/thermal/tmon/sysfs.c | 24 +- tools/thermal/tmon/tmon.h | 3 + tools/tracing/rtla/Makefile | 2 +- tools/tracing/rtla/src/trace.c | 9 +- tools/tracing/rtla/src/utils.c | 5 +- virt/kvm/kvm_main.c | 25 +- virt/kvm/pfncache.c | 207 +++-- 1280 files changed, 15051 insertions(+), 9078 deletions(-)
From: Nick Desaulniers ndesaulniers@google.com
commit 0d362be5b14200b77ecc2127936a5ff82fbffe41 upstream.
Users of GNU ld (BFD) from binutils 2.39+ will observe multiple instances of a new warning when linking kernels in the form:
ld: warning: vmlinux: missing .note.GNU-stack section implies executable stack ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker ld: warning: vmlinux has a LOAD segment with RWX permissions
Generally, we would like to avoid the stack being executable. Because there could be a need for the stack to be executable, assembler sources have to opt-in to this security feature via explicit creation of the .note.GNU-stack feature (which compilers create by default) or command line flag --noexecstack. Or we can simply tell the linker the production of such sections is irrelevant and to link the stack as --noexecstack.
LLVM's LLD linker defaults to -z noexecstack, so this flag isn't strictly necessary when linking with LLD, only BFD, but it doesn't hurt to be explicit here for all linkers IMO. --no-warn-rwx-segments is currently BFD specific and only available in the current latest release, so it's wrapped in an ld-option check.
While the kernel makes extensive usage of ELF sections, it doesn't use permissions from ELF segments.
Link: https://lore.kernel.org/linux-block/3af4127a-f453-4cf7-f133-a181cce06f73@ker... Link: https://sourceware.org/git/?p=binutils-gdb.git%3Ba=commit%3Bh=ba951afb99912d... Link: https://github.com/llvm/llvm-project/issues/57009 Reported-and-tested-by: Jens Axboe axboe@kernel.dk Suggested-by: Fangrui Song maskray@google.com Signed-off-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Makefile | 5 +++++ 1 file changed, 5 insertions(+)
--- a/Makefile +++ b/Makefile @@ -1033,6 +1033,11 @@ KBUILD_CFLAGS += $(KCFLAGS) KBUILD_LDFLAGS_MODULE += --build-id=sha1 LDFLAGS_vmlinux += --build-id=sha1
+KBUILD_LDFLAGS += -z noexecstack +ifeq ($(CONFIG_LD_IS_BFD),y) +KBUILD_LDFLAGS += $(call ld-option,--no-warn-rwx-segments) +endif + ifeq ($(CONFIG_STRIP_ASM_SYMS),y) LDFLAGS_vmlinux += $(call ld-option, -X,) endif
From: Nick Desaulniers ndesaulniers@google.com
commit ffcf9c5700e49c0aee42dcba9a12ba21338e8136 upstream.
Users of GNU ld (BFD) from binutils 2.39+ will observe multiple instances of a new warning when linking kernels in the form:
ld: warning: arch/x86/boot/pmjump.o: missing .note.GNU-stack section implies executable stack ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker ld: warning: arch/x86/boot/compressed/vmlinux has a LOAD segment with RWX permissions
Generally, we would like to avoid the stack being executable. Because there could be a need for the stack to be executable, assembler sources have to opt-in to this security feature via explicit creation of the .note.GNU-stack feature (which compilers create by default) or command line flag --noexecstack. Or we can simply tell the linker the production of such sections is irrelevant and to link the stack as --noexecstack.
LLVM's LLD linker defaults to -z noexecstack, so this flag isn't strictly necessary when linking with LLD, only BFD, but it doesn't hurt to be explicit here for all linkers IMO. --no-warn-rwx-segments is currently BFD specific and only available in the current latest release, so it's wrapped in an ld-option check.
While the kernel makes extensive usage of ELF sections, it doesn't use permissions from ELF segments.
Link: https://lore.kernel.org/linux-block/3af4127a-f453-4cf7-f133-a181cce06f73@ker... Link: https://sourceware.org/git/?p=binutils-gdb.git%3Ba=commit%3Bh=ba951afb99912d... Link: https://github.com/llvm/llvm-project/issues/57009 Reported-and-tested-by: Jens Axboe axboe@kernel.dk Suggested-by: Fangrui Song maskray@google.com Signed-off-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/boot/Makefile | 2 +- arch/x86/boot/compressed/Makefile | 4 ++++ arch/x86/entry/vdso/Makefile | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-)
--- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -103,7 +103,7 @@ $(obj)/zoffset.h: $(obj)/compressed/vmli AFLAGS_header.o += -I$(objtree)/$(obj) $(obj)/header.o: $(obj)/zoffset.h
-LDFLAGS_setup.elf := -m elf_i386 -T +LDFLAGS_setup.elf := -m elf_i386 -z noexecstack -T $(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE $(call if_changed,ld)
--- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -69,6 +69,10 @@ LDFLAGS_vmlinux := -pie $(call ld-option ifdef CONFIG_LD_ORPHAN_WARN LDFLAGS_vmlinux += --orphan-handling=warn endif +LDFLAGS_vmlinux += -z noexecstack +ifeq ($(CONFIG_LD_IS_BFD),y) +LDFLAGS_vmlinux += $(call ld-option,--no-warn-rwx-segments) +endif LDFLAGS_vmlinux += -T
hostprogs := mkpiggy --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -180,7 +180,7 @@ quiet_cmd_vdso = VDSO $@ sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 \ - $(call ld-option, --eh-frame-hdr) -Bsymbolic + $(call ld-option, --eh-frame-hdr) -Bsymbolic -z noexecstack GCOV_PROFILE := n
quiet_cmd_vdso_and_check = VDSO $@
From: Trond Myklebust trond.myklebust@hammerspace.com
commit 9597152d98840c2517230740952df97cfcc07e2f upstream.
This reverts commit c6eb58435b98bd843d3179664a0195ff25adb2c3. If a transport is down, then we want to fail over to other transports if they are listed in the GETDEVICEINFO reply.
Fixes: c6eb58435b98 ("pNFS: nfs3_set_ds_client should set NFS_CS_NOPING") Cc: stable@vger.kernel.org # 5.11.x Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/nfs/nfs3client.c | 1 - 1 file changed, 1 deletion(-)
--- a/fs/nfs/nfs3client.c +++ b/fs/nfs/nfs3client.c @@ -108,7 +108,6 @@ struct nfs_client *nfs3_set_ds_client(st if (mds_srv->flags & NFS_MOUNT_NORESVPORT) __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
- __set_bit(NFS_CS_NOPING, &cl_init.init_flags); __set_bit(NFS_CS_DS, &cl_init.init_flags);
/* Use the MDS nfs_client cl_ipaddr. */
From: Nilesh Javali njavali@marvell.com
commit 5bc7b01c513a4a9b4cfe306e8d1720cfcfd3b8a3 upstream.
This fixes the regression of NVMe discovery failure during driver load time.
This reverts commit 6a45c8e137d4e2c72eecf1ac7cf64f2fdfcead99.
Link: https://lore.kernel.org/r/20220713052045.10683-2-njavali@marvell.com Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_init.c | 5 ++--- drivers/scsi/qla2xxx/qla_nvme.c | 5 ----- 2 files changed, 2 insertions(+), 8 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5767,8 +5767,6 @@ qla2x00_reg_remote_port(scsi_qla_host_t if (atomic_read(&fcport->state) == FCS_ONLINE) return;
- qla2x00_set_fcport_state(fcport, FCS_ONLINE); - rport_ids.node_name = wwn_to_u64(fcport->node_name); rport_ids.port_name = wwn_to_u64(fcport->port_name); rport_ids.port_id = fcport->d_id.b.domain << 16 | @@ -5869,7 +5867,6 @@ qla2x00_update_fcport(scsi_qla_host_t *v qla2x00_reg_remote_port(vha, fcport); break; case MODE_TARGET: - qla2x00_set_fcport_state(fcport, FCS_ONLINE); if (!vha->vha_tgt.qla_tgt->tgt_stop && !vha->vha_tgt.qla_tgt->tgt_stopped) qlt_fc_port_added(vha, fcport); @@ -5887,6 +5884,8 @@ qla2x00_update_fcport(scsi_qla_host_t *v if (NVME_TARGET(vha->hw, fcport)) qla_nvme_register_remote(vha, fcport);
+ qla2x00_set_fcport_state(fcport, FCS_ONLINE); + if (IS_IIDMA_CAPABLE(vha->hw) && vha->hw->flags.gpsc_supported) { if (fcport->id_changed) { fcport->id_changed = 0; --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -37,11 +37,6 @@ int qla_nvme_register_remote(struct scsi (fcport->nvme_flag & NVME_FLAG_REGISTERED)) return 0;
- if (atomic_read(&fcport->state) == FCS_ONLINE) - return 0; - - qla2x00_set_fcport_state(fcport, FCS_ONLINE); - fcport->nvme_flag &= ~NVME_FLAG_RESETTING;
memset(&req, 0, sizeof(struct nvme_fc_port_info));
From: Trond Myklebust trond.myklebust@hammerspace.com
commit 7836d75467e9d214bdf5c693b32721de729a6e38 upstream.
The RPC/RDMA driver will return -EPROTO and -ENODEV as connection errors under certain circumstances. Make sure that we handle them and report them to the server. If not, we can end up cycling forever in a LAYOUTGET/LAYOUTRETURN loop.
Fixes: a12f996d3413 ("NFSv4/pNFS: Use connections to a DS that are all of the same protocol family") Cc: stable@vger.kernel.org # 5.11.x Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/nfs/flexfilelayout/flexfilelayout.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -1131,6 +1131,8 @@ static int ff_layout_async_handle_error_ case -EIO: case -ETIMEDOUT: case -EPIPE: + case -EPROTO: + case -ENODEV: dprintk("%s DS connection error %d\n", __func__, task->tk_status); nfs4_delete_deviceid(devid->ld, devid->nfs_client, @@ -1236,6 +1238,8 @@ static void ff_layout_io_track_ds_error( case -ENOBUFS: case -EPIPE: case -EPERM: + case -EPROTO: + case -ENODEV: *op_status = status = NFS4ERR_NXIO; break; case -EACCES:
From: Jeff Layton jlayton@kernel.org
commit 23ba98de6dcec665e15c0ca19244379bb0d30932 upstream.
We had a report from the spring Bake-a-thon of data corruption in some nfstest_interop tests. Looking at the traces showed the NFS server allowing a v3 WRITE to proceed while a read delegation was still outstanding.
Currently, we only set NFSD_FILE_BREAK_* flags if NFSD_MAY_NOT_BREAK_LEASE was set when we call nfsd_file_alloc. NFSD_MAY_NOT_BREAK_LEASE was intended to be set when finding files for COMMIT ops, where we need a writeable filehandle but don't need to break read leases.
It doesn't make any sense to consult that flag when allocating a file since the file may be used on subsequent calls where we do want to break the lease (and the usage of it here seems to be reverse from what it should be anyway).
Also, after calling nfsd_open_break_lease, we don't want to clear the BREAK_* bits. A lease could end up being set on it later (more than once) and we need to be able to break those leases as well.
This means that the NFSD_FILE_BREAK_* flags now just mirror NFSD_MAY_{READ,WRITE} flags, so there's no need for them at all. Just drop those flags and unconditionally call nfsd_open_break_lease every time.
Reported-by: Olga Kornieskaia kolga@netapp.com Link: https://bugzilla.redhat.com/show_bug.cgi?id=2107360 Fixes: 65294c1f2c5e (nfsd: add a new struct file caching facility to nfsd) Cc: stable@vger.kernel.org # 5.4.x : bb283ca18d1e NFSD: Clean up the show_nf_flags() macro Cc: stable@vger.kernel.org # 5.4.x Signed-off-by: Jeff Layton jlayton@kernel.org Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/nfsd/filecache.c | 22 +--------------------- fs/nfsd/filecache.h | 4 +--- fs/nfsd/trace.h | 2 -- 3 files changed, 2 insertions(+), 26 deletions(-)
--- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -184,12 +184,6 @@ nfsd_file_alloc(struct inode *inode, uns nf->nf_hashval = hashval; refcount_set(&nf->nf_ref, 1); nf->nf_may = may & NFSD_FILE_MAY_MASK; - if (may & NFSD_MAY_NOT_BREAK_LEASE) { - if (may & NFSD_MAY_WRITE) - __set_bit(NFSD_FILE_BREAK_WRITE, &nf->nf_flags); - if (may & NFSD_MAY_READ) - __set_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags); - } nf->nf_mark = NULL; trace_nfsd_file_alloc(nf); } @@ -958,21 +952,7 @@ wait_for_construction:
this_cpu_inc(nfsd_file_cache_hits);
- if (!(may_flags & NFSD_MAY_NOT_BREAK_LEASE)) { - bool write = (may_flags & NFSD_MAY_WRITE); - - if (test_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags) || - (test_bit(NFSD_FILE_BREAK_WRITE, &nf->nf_flags) && write)) { - status = nfserrno(nfsd_open_break_lease( - file_inode(nf->nf_file), may_flags)); - if (status == nfs_ok) { - clear_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags); - if (write) - clear_bit(NFSD_FILE_BREAK_WRITE, - &nf->nf_flags); - } - } - } + status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags)); out: if (status == nfs_ok) { *pnf = nf; --- a/fs/nfsd/filecache.h +++ b/fs/nfsd/filecache.h @@ -37,9 +37,7 @@ struct nfsd_file { struct net *nf_net; #define NFSD_FILE_HASHED (0) #define NFSD_FILE_PENDING (1) -#define NFSD_FILE_BREAK_READ (2) -#define NFSD_FILE_BREAK_WRITE (3) -#define NFSD_FILE_REFERENCED (4) +#define NFSD_FILE_REFERENCED (2) unsigned long nf_flags; struct inode *nf_inode; unsigned int nf_hashval; --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -696,8 +696,6 @@ DEFINE_CLID_EVENT(confirmed_r); __print_flags(val, "|", \ { 1 << NFSD_FILE_HASHED, "HASHED" }, \ { 1 << NFSD_FILE_PENDING, "PENDING" }, \ - { 1 << NFSD_FILE_BREAK_READ, "BREAK_READ" }, \ - { 1 << NFSD_FILE_BREAK_WRITE, "BREAK_WRITE" }, \ { 1 << NFSD_FILE_REFERENCED, "REFERENCED"})
DECLARE_EVENT_CLASS(nfsd_file_class,
From: Takashi Iwai tiwai@suse.de
commit e086c37f876fd1f551e2b4f9be97d4a1923cd219 upstream.
Just like other Behringer models, UMC202HD (USB ID 1397:0507) requires the quirk for the stable streaming, too.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215934 Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220722143948.29804-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1843,6 +1843,8 @@ static const struct usb_audio_quirk_flag QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x1397, 0x0507, /* Behringer UMC202HD */ + QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB), DEVICE_FLG(0x1397, 0x0508, /* Behringer UMC204HD */ QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB), DEVICE_FLG(0x1397, 0x0509, /* Behringer UMC404HD */
From: Zheyu Ma zheyuma97@gmail.com
commit ffb2759df7efbc00187bfd9d1072434a13a54139 upstream.
When the driver fails in snd_card_register() at probe time, it will free the 'bcd2k->midi_out_urb' before killing it, which may cause a UAF bug.
The following log can reveal it:
[ 50.727020] BUG: KASAN: use-after-free in bcd2000_input_complete+0x1f1/0x2e0 [snd_bcd2000] [ 50.727623] Read of size 8 at addr ffff88810fab0e88 by task swapper/4/0 [ 50.729530] Call Trace: [ 50.732899] bcd2000_input_complete+0x1f1/0x2e0 [snd_bcd2000]
Fix this by adding usb_kill_urb() before usb_free_urb().
Fixes: b47a22290d58 ("ALSA: MIDI driver for Behringer BCD2000 USB device") Signed-off-by: Zheyu Ma zheyuma97@gmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220715010515.2087925-1-zheyuma97@gmail.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/usb/bcd2000/bcd2000.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/sound/usb/bcd2000/bcd2000.c +++ b/sound/usb/bcd2000/bcd2000.c @@ -348,7 +348,8 @@ static int bcd2000_init_midi(struct bcd2 static void bcd2000_free_usb_related_resources(struct bcd2000 *bcd2k, struct usb_interface *interface) { - /* usb_kill_urb not necessary, urb is aborted automatically */ + usb_kill_urb(bcd2k->midi_out_urb); + usb_kill_urb(bcd2k->midi_in_urb);
usb_free_urb(bcd2k->midi_out_urb); usb_free_urb(bcd2k->midi_in_urb);
From: Tim Crawford tcrawford@system76.com
commit be561ffad708f0cee18aee4231f80ffafaf7a419 upstream.
Fixes headset detection on Clevo NV45PZ.
Signed-off-by: Tim Crawford tcrawford@system76.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220731032243.4300-1-tcrawford@system76.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 @@ -9203,6 +9203,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x1558, 0x4018, "Clevo NV40M[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x4019, "Clevo NV40MZ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x4020, "Clevo NV40MB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1558, 0x4041, "Clevo NV4[15]PZ", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x40a1, "Clevo NL40GU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x40c1, "Clevo NL40[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x40d1, "Clevo NL41DU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
From: Ivan Hasenkampf ivan.hasenkampf@gmail.com
commit 24df5428ef9d1ca1edd54eca7eb667110f2dfae3 upstream.
Fixes speaker output on HP Spectre x360 15-eb0xxx
[ re-sorted in SSID order by tiwai ]
Signed-off-by: Ivan Hasenkampf ivan.hasenkampf@gmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220803164001.290394-1-ivan.hasenkampf@gmail.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9044,6 +9044,8 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x103c, 0x861f, "HP Elite Dragonfly G1", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x86c7, "HP Envy AiO 32", ALC274_FIXUP_HP_ENVY_GPIO), + SND_PCI_QUIRK(0x103c, 0x86e7, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1), + SND_PCI_QUIRK(0x103c, 0x86e8, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1), SND_PCI_QUIRK(0x103c, 0x8716, "HP Elite Dragonfly G2 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8720, "HP EliteBook x360 1040 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED),
From: Philipp Jungkamp p.jungkamp@gmx.net
commit 3790a3d6dbbc48e30586e9c3fc752a00e2e11946 upstream.
The Lenovo Yoga 9 14IAP7 is set up similarly to the Thinkpad X1 7th and 8th Gen. It also has the speakers attached to NID 0x14 and the bass speakers to NID 0x17, but here the codec misreports the NID 0x17 as unconnected.
The pincfg and hda verbs connect and activate the bass speaker amplifiers, but the generic driver will connect them to NID 0x06 which has no volume control. Set connection list/preferred connections is required to gain volume control.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=208555 Signed-off-by: Philipp Jungkamp p.jungkamp@gmx.net Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220729162103.6062-1-p.jungkamp@gmx.net Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 109 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6787,6 +6787,43 @@ static void alc_fixup_dell4_mic_no_prese } }
+static void alc287_fixup_yoga9_14iap7_bass_spk_pin(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + /* + * The Pin Complex 0x17 for the bass speakers is wrongly reported as + * unconnected. + */ + static const struct hda_pintbl pincfgs[] = { + { 0x17, 0x90170121 }, + { } + }; + /* + * Avoid DAC 0x06 and 0x08, as they have no volume controls. + * DAC 0x02 and 0x03 would be fine. + */ + static const hda_nid_t conn[] = { 0x02, 0x03 }; + /* + * Prefer both speakerbar (0x14) and bass speakers (0x17) connected to DAC 0x02. + * Headphones (0x21) are connected to DAC 0x03. + */ + static const hda_nid_t preferred_pairs[] = { + 0x14, 0x02, + 0x17, 0x02, + 0x21, 0x03, + 0 + }; + struct alc_spec *spec = codec->spec; + + switch (action) { + case HDA_FIXUP_ACT_PRE_PROBE: + snd_hda_apply_pincfgs(codec, pincfgs); + snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn); + spec->gen.preferred_dacs = preferred_pairs; + break; + } +} + enum { ALC269_FIXUP_GPIO2, ALC269_FIXUP_SONY_VAIO, @@ -7023,6 +7060,8 @@ enum { ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED, ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE, + ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK, + ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN, };
/* A special fixup for Lenovo C940 and Yoga Duet 7; @@ -8865,6 +8904,74 @@ static const struct hda_fixup alc269_fix .chained = true, .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC }, + [ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + // enable left speaker + { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x41 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xc }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x1a }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xf }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x42 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x10 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x40 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x2 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + // enable right speaker + { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x46 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xc }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x2a }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xf }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x46 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x10 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x44 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x2 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { }, + }, + }, + [ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc287_fixup_yoga9_14iap7_bass_spk_pin, + .chained = true, + .chain_id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK, + }, };
static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -9318,6 +9425,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x17aa, 0x31af, "ThinkCentre Station", ALC623_FIXUP_LENOVO_THINKSTATION_P340), + SND_PCI_QUIRK(0x17aa, 0x3801, "Lenovo Yoga9 14IAP7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga DuetITL 2021", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7), @@ -9563,6 +9671,7 @@ static const struct hda_model_fixup alc2 {.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"}, {.id = ALC285_FIXUP_HP_SPECTRE_X360_EB1, .name = "alc285-hp-spectre-x360-eb1"}, {.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"}, + {.id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN, .name = "alc287-yoga9-bass-spk-pin"}, {.id = ALC623_FIXUP_LENOVO_THINKSTATION_P340, .name = "alc623-lenovo-thinkstation-p340"}, {.id = ALC255_FIXUP_ACER_HEADPHONE_AND_MIC, .name = "alc255-acer-headphone-and-mic"}, {.id = ALC285_FIXUP_HP_GPIO_AMP_INIT, .name = "alc285-hp-amp-init"},
From: syed sabakareem Syed.SabaKareem@amd.com
commit be0aa8d4b0fcb4532bf7973141e911998ab39508 upstream.
Removed intel DMI product id's 21AW/21AX/21D8/21D9/21BN/21BQ in DMI table and updated DMI entry for AMD platform X13 Gen 3 platform 21CM/21CN.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216267
Signed-off-by: syed sabakareem Syed.SabaKareem@amd.com Reviewed-by: Mario Limonciello mario.limonciello@amd.com Reported-by: David Korth gerbilsoft@gerbilsoft.com Fixes: fa991481b8b2 ("ASoC: amd: add YC machine driver using dmic") Link: https://lore.kernel.org/r/20220722134603.316668-1-Syed.SabaKareem@amd.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/amd/yc/acp6x-mach.c | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-)
--- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -105,28 +105,14 @@ static const struct dmi_system_id yc_acp .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "21AW"), + DMI_MATCH(DMI_PRODUCT_NAME, "21CM"), } }, { .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "21AX"), - } - }, - { - .driver_data = &acp6x_card, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "21BN"), - } - }, - { - .driver_data = &acp6x_card, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "21BQ"), + DMI_MATCH(DMI_PRODUCT_NAME, "21CN"), } }, { @@ -157,20 +143,6 @@ static const struct dmi_system_id yc_acp DMI_MATCH(DMI_PRODUCT_NAME, "21CL"), } }, - { - .driver_data = &acp6x_card, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "21D8"), - } - }, - { - .driver_data = &acp6x_card, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "21D9"), - } - }, {} };
From: Zev Weiss zev@bewilderbeest.net
commit f4e6960f4f16b1ca5da16cec7612ecc86402ac05 upstream.
Commit c3963bc0a0cf ("hwmon: (nct6775) Split core and platform driver") introduced a slight change in nct6775_suspend() in order to avoid an otherwise-needless symbol export for nct6775_update_device(), replacing a call to that function with a simple dev_get_drvdata() instead.
As it turns out, there is no guarantee that nct6775_update_device() is ever called prior to suspend. If this happens, the resume function ends up writing bad data into the various chip registers, which results in a crash shortly after resume.
To fix the problem, just add the symbol export and return to using nct6775_update_device() as was employed previously.
Reported-by: Zoltán Kővágó dirty.ice.hu@gmail.com Tested-by: Zoltán Kővágó dirty.ice.hu@gmail.com Fixes: c3963bc0a0cf ("hwmon: (nct6775) Split core and platform driver") Cc: stable@kernel.org Signed-off-by: Zev Weiss zev@bewilderbeest.net Link: https://lore.kernel.org/r/20220810052646.13825-1-zev@bewilderbeest.net [groeck: Updated description] Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hwmon/nct6775-core.c | 3 ++- drivers/hwmon/nct6775-platform.c | 2 +- drivers/hwmon/nct6775.h | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/nct6775-core.c b/drivers/hwmon/nct6775-core.c index 446964cbae4c..da9ec6983e13 100644 --- a/drivers/hwmon/nct6775-core.c +++ b/drivers/hwmon/nct6775-core.c @@ -1480,7 +1480,7 @@ static int nct6775_update_pwm_limits(struct device *dev) return 0; }
-static struct nct6775_data *nct6775_update_device(struct device *dev) +struct nct6775_data *nct6775_update_device(struct device *dev) { struct nct6775_data *data = dev_get_drvdata(dev); int i, j, err = 0; @@ -1615,6 +1615,7 @@ static struct nct6775_data *nct6775_update_device(struct device *dev) mutex_unlock(&data->update_lock); return err ? ERR_PTR(err) : data; } +EXPORT_SYMBOL_GPL(nct6775_update_device);
/* * Sysfs callback functions diff --git a/drivers/hwmon/nct6775-platform.c b/drivers/hwmon/nct6775-platform.c index ab30437221ce..41c97cfacfb8 100644 --- a/drivers/hwmon/nct6775-platform.c +++ b/drivers/hwmon/nct6775-platform.c @@ -359,7 +359,7 @@ static int __maybe_unused nct6775_suspend(struct device *dev) { int err; u16 tmp; - struct nct6775_data *data = dev_get_drvdata(dev); + struct nct6775_data *data = nct6775_update_device(dev);
if (IS_ERR(data)) return PTR_ERR(data); diff --git a/drivers/hwmon/nct6775.h b/drivers/hwmon/nct6775.h index 93f708148e65..be41848c3cd2 100644 --- a/drivers/hwmon/nct6775.h +++ b/drivers/hwmon/nct6775.h @@ -196,6 +196,8 @@ static inline int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 va return regmap_write(data->regmap, reg, value); }
+struct nct6775_data *nct6775_update_device(struct device *dev); + bool nct6775_reg_is_word_sized(struct nct6775_data *data, u16 reg); int nct6775_probe(struct device *dev, struct nct6775_data *data, const struct regmap_config *regmapcfg);
From: Jeongik Cha jeongik@google.com
commit 4ee186fa7e40ae06ebbfbad77e249e3746e14114 upstream.
A pending packet uses a cookie as an unique key, but it can be duplicated because it didn't use atomic operators.
And also, a pending packet can be null in hwsim_tx_info_frame_received_nl due to race condition with mac80211_hwsim_stop.
For this, * Use an atomic type and operator for a cookie * Add a lock around the loop for pending packets
Signed-off-by: Jeongik Cha jeongik@google.com Link: https://lore.kernel.org/r/20220704084354.3556326-1-jeongik@google.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/mac80211_hwsim.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
--- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -680,7 +680,7 @@ struct mac80211_hwsim_data { bool ps_poll_pending; struct dentry *debugfs;
- uintptr_t pending_cookie; + atomic64_t pending_cookie; struct sk_buff_head pending; /* packets pending */ /* * Only radios in the same group can communicate together (the @@ -1347,7 +1347,7 @@ static void mac80211_hwsim_tx_frame_nl(s int i; struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; struct hwsim_tx_rate_flag tx_attempts_flags[IEEE80211_TX_MAX_RATES]; - uintptr_t cookie; + u64 cookie;
if (data->ps != PS_DISABLED) hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); @@ -1416,8 +1416,7 @@ static void mac80211_hwsim_tx_frame_nl(s goto nla_put_failure;
/* We create a cookie to identify this skb */ - data->pending_cookie++; - cookie = data->pending_cookie; + cookie = (u64)atomic64_inc_return(&data->pending_cookie); info->rate_driver_data[0] = (void *)cookie; if (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD)) goto nla_put_failure; @@ -4080,6 +4079,7 @@ static int hwsim_tx_info_frame_received_ const u8 *src; unsigned int hwsim_flags; int i; + unsigned long flags; bool found = false;
if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] || @@ -4107,18 +4107,20 @@ static int hwsim_tx_info_frame_received_ }
/* look for the skb matching the cookie passed back from user */ + spin_lock_irqsave(&data2->pending.lock, flags); skb_queue_walk_safe(&data2->pending, skb, tmp) { u64 skb_cookie;
txi = IEEE80211_SKB_CB(skb); - skb_cookie = (u64)(uintptr_t)txi->rate_driver_data[0]; + skb_cookie = (u64)txi->rate_driver_data[0];
if (skb_cookie == ret_skb_cookie) { - skb_unlink(skb, &data2->pending); + __skb_unlink(skb, &data2->pending); found = true; break; } } + spin_unlock_irqrestore(&data2->pending.lock, flags);
/* not found */ if (!found)
From: Johannes Berg johannes.berg@intel.com
commit 58b6259d820d63c2adf1c7541b54cce5a2ae6073 upstream.
The robots report that we're now casting to a differently sized integer, which is correct, and the previous patch had erroneously removed it.
Reported-by: kernel test robot lkp@intel.com Fixes: 4ee186fa7e40 ("wifi: mac80211_hwsim: fix race condition in pending packet") Signed-off-by: Johannes Berg johannes.berg@intel.com Cc: Jeongik Cha jeongik@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/mac80211_hwsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -4112,7 +4112,7 @@ static int hwsim_tx_info_frame_received_ u64 skb_cookie;
txi = IEEE80211_SKB_CB(skb); - skb_cookie = (u64)txi->rate_driver_data[0]; + skb_cookie = (u64)(uintptr_t)txi->rate_driver_data[0];
if (skb_cookie == ret_skb_cookie) { __skb_unlink(skb, &data2->pending);
From: Johannes Berg johannes.berg@intel.com
commit cc5250cdb43d444061412df7fae72d2b4acbdf97 upstream.
We won't really have enough skbs to need a 64-bit cookie, and on 32-bit platforms storing the 64-bit cookie into the void *rate_driver_data doesn't work anyway. Switch back to using just a 32-bit cookie and uintptr_t for the type to avoid compiler warnings about all this.
Fixes: 4ee186fa7e40 ("wifi: mac80211_hwsim: fix race condition in pending packet") Signed-off-by: Johannes Berg johannes.berg@intel.com Cc: Jeongik Cha jeongik@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/mac80211_hwsim.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
--- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -680,7 +680,7 @@ struct mac80211_hwsim_data { bool ps_poll_pending; struct dentry *debugfs;
- atomic64_t pending_cookie; + atomic_t pending_cookie; struct sk_buff_head pending; /* packets pending */ /* * Only radios in the same group can communicate together (the @@ -1347,7 +1347,7 @@ static void mac80211_hwsim_tx_frame_nl(s int i; struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; struct hwsim_tx_rate_flag tx_attempts_flags[IEEE80211_TX_MAX_RATES]; - u64 cookie; + uintptr_t cookie;
if (data->ps != PS_DISABLED) hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); @@ -1416,7 +1416,7 @@ static void mac80211_hwsim_tx_frame_nl(s goto nla_put_failure;
/* We create a cookie to identify this skb */ - cookie = (u64)atomic64_inc_return(&data->pending_cookie); + cookie = atomic_inc_return(&data->pending_cookie); info->rate_driver_data[0] = (void *)cookie; if (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD)) goto nla_put_failure; @@ -4109,10 +4109,10 @@ static int hwsim_tx_info_frame_received_ /* look for the skb matching the cookie passed back from user */ spin_lock_irqsave(&data2->pending.lock, flags); skb_queue_walk_safe(&data2->pending, skb, tmp) { - u64 skb_cookie; + uintptr_t skb_cookie;
txi = IEEE80211_SKB_CB(skb); - skb_cookie = (u64)(uintptr_t)txi->rate_driver_data[0]; + skb_cookie = (uintptr_t)txi->rate_driver_data[0];
if (skb_cookie == ret_skb_cookie) { __skb_unlink(skb, &data2->pending);
From: Mikulas Patocka mpatocka@redhat.com
commit d4252071b97d2027d246f6a82cbee4d52f618b47 upstream.
Let's have a look at this piece of code in __bread_slow:
get_bh(bh); bh->b_end_io = end_buffer_read_sync; submit_bh(REQ_OP_READ, 0, bh); wait_on_buffer(bh); if (buffer_uptodate(bh)) return bh;
Neither wait_on_buffer nor buffer_uptodate contain any memory barrier. Consequently, if someone calls sb_bread and then reads the buffer data, the read of buffer data may be executed before wait_on_buffer(bh) on architectures with weak memory ordering and it may return invalid data.
Fix this bug by adding a memory barrier to set_buffer_uptodate and an acquire barrier to buffer_uptodate (in a similar way as folio_test_uptodate and folio_mark_uptodate).
Signed-off-by: Mikulas Patocka mpatocka@redhat.com Reviewed-by: Matthew Wilcox (Oracle) willy@infradead.org Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/buffer_head.h | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
--- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -117,7 +117,6 @@ static __always_inline int test_clear_bu * of the form "mark_buffer_foo()". These are higher-level functions which * do something in addition to setting a b_state bit. */ -BUFFER_FNS(Uptodate, uptodate) BUFFER_FNS(Dirty, dirty) TAS_BUFFER_FNS(Dirty, dirty) BUFFER_FNS(Lock, locked) @@ -135,6 +134,30 @@ BUFFER_FNS(Meta, meta) BUFFER_FNS(Prio, prio) BUFFER_FNS(Defer_Completion, defer_completion)
+static __always_inline void set_buffer_uptodate(struct buffer_head *bh) +{ + /* + * make it consistent with folio_mark_uptodate + * pairs with smp_load_acquire in buffer_uptodate + */ + smp_mb__before_atomic(); + set_bit(BH_Uptodate, &bh->b_state); +} + +static __always_inline void clear_buffer_uptodate(struct buffer_head *bh) +{ + clear_bit(BH_Uptodate, &bh->b_state); +} + +static __always_inline int buffer_uptodate(const struct buffer_head *bh) +{ + /* + * make it consistent with folio_test_uptodate + * pairs with smp_mb__before_atomic in set_buffer_uptodate + */ + return (smp_load_acquire(&bh->b_state) & (1UL << BH_Uptodate)) != 0; +} + #define bh_offset(bh) ((unsigned long)(bh)->b_data & ~PAGE_MASK)
/* If we *know* page->private refers to buffer_heads */
From: Jeff Layton jlayton@kernel.org
commit 6930bcbfb6ceda63e298c6af6d733ecdf6bd4cde upstream.
lockd doesn't currently vet the start and length in nlm4 requests like it should, and can end up generating lock requests with arguments that overflow when passed to the filesystem.
The NLM4 protocol uses unsigned 64-bit arguments for both start and length, whereas struct file_lock tracks the start and end as loff_t values. By the time we get around to calling nlm4svc_retrieve_args, we've lost the information that would allow us to determine if there was an overflow.
Start tracking the actual start and len for NLM4 requests in the nlm_lock. In nlm4svc_retrieve_args, vet these values to ensure they won't cause an overflow, and return NLM4_FBIG if they do.
Link: https://bugzilla.linux-nfs.org/show_bug.cgi?id=392 Reported-by: Jan Kasiak j.kasiak@gmail.com Signed-off-by: Jeff Layton jlayton@kernel.org Signed-off-by: Chuck Lever chuck.lever@oracle.com Cc: stable@vger.kernel.org # 5.14+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/lockd/svc4proc.c | 8 ++++++++ fs/lockd/xdr4.c | 19 ++----------------- include/linux/lockd/xdr.h | 2 ++ 3 files changed, 12 insertions(+), 17 deletions(-)
--- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -32,6 +32,10 @@ nlm4svc_retrieve_args(struct svc_rqst *r if (!nlmsvc_ops) return nlm_lck_denied_nolocks;
+ if (lock->lock_start > OFFSET_MAX || + (lock->lock_len && ((lock->lock_len - 1) > (OFFSET_MAX - lock->lock_start)))) + return nlm4_fbig; + /* Obtain host handle */ if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len)) || (argp->monitor && nsm_monitor(host) < 0)) @@ -50,6 +54,10 @@ nlm4svc_retrieve_args(struct svc_rqst *r /* Set up the missing parts of the file_lock structure */ lock->fl.fl_file = file->f_file[mode]; lock->fl.fl_pid = current->tgid; + lock->fl.fl_start = (loff_t)lock->lock_start; + lock->fl.fl_end = lock->lock_len ? + (loff_t)(lock->lock_start + lock->lock_len - 1) : + OFFSET_MAX; lock->fl.fl_lmops = &nlmsvc_lock_operations; nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid); if (!lock->fl.fl_owner) { --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c @@ -20,13 +20,6 @@
#include "svcxdr.h"
-static inline loff_t -s64_to_loff_t(__s64 offset) -{ - return (loff_t)offset; -} - - static inline s64 loff_t_to_s64(loff_t offset) { @@ -70,8 +63,6 @@ static bool svcxdr_decode_lock(struct xdr_stream *xdr, struct nlm_lock *lock) { struct file_lock *fl = &lock->fl; - u64 len, start; - s64 end;
if (!svcxdr_decode_string(xdr, &lock->caller, &lock->len)) return false; @@ -81,20 +72,14 @@ svcxdr_decode_lock(struct xdr_stream *xd return false; if (xdr_stream_decode_u32(xdr, &lock->svid) < 0) return false; - if (xdr_stream_decode_u64(xdr, &start) < 0) + if (xdr_stream_decode_u64(xdr, &lock->lock_start) < 0) return false; - if (xdr_stream_decode_u64(xdr, &len) < 0) + if (xdr_stream_decode_u64(xdr, &lock->lock_len) < 0) return false;
locks_init_lock(fl); fl->fl_flags = FL_POSIX; fl->fl_type = F_RDLCK; - end = start + len - 1; - fl->fl_start = s64_to_loff_t(start); - if (len == 0 || end < 0) - fl->fl_end = OFFSET_MAX; - else - fl->fl_end = s64_to_loff_t(end);
return true; } --- a/include/linux/lockd/xdr.h +++ b/include/linux/lockd/xdr.h @@ -41,6 +41,8 @@ struct nlm_lock { struct nfs_fh fh; struct xdr_netobj oh; u32 svid; + u64 lock_start; + u64 lock_len; struct file_lock fl; };
From: Maximilian Luz luzmaximilian@gmail.com
commit db925d809011c37b246434fdce71209fc2e6c0c2 upstream.
Similar to the Surface Go (1), the (Elantech) touchscreen/digitizer in the Surface Go 2 mistakenly reports the battery of the stylus. Instead of over the touchscreen device, battery information is provided via bluetooth and the touchscreen device reports an empty battery.
Apply the HID_BATTERY_QUIRK_IGNORE quirk to ignore this battery and prevent the erroneous low battery warnings.
Cc: stable@vger.kernel.org Signed-off-by: Maximilian Luz luzmaximilian@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-input.c | 2 ++ 2 files changed, 3 insertions(+)
--- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -413,6 +413,7 @@ #define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544 #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A +#define I2C_DEVICE_ID_SURFACE_GO2_TOUCHSCREEN 0x2A1C
#define USB_VENDOR_ID_ELECOM 0x056e #define USB_DEVICE_ID_ELECOM_BM084 0x0061 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -381,6 +381,8 @@ static const struct hid_device_id hid_ba HID_BATTERY_QUIRK_IGNORE }, { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN), HID_BATTERY_QUIRK_IGNORE }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO2_TOUCHSCREEN), + HID_BATTERY_QUIRK_IGNORE }, {} };
From: Ping Cheng pinglinux@gmail.com
commit d6b675687a4ab4dba684716d97c8c6f81bf10905 upstream.
Touch switch state is received through WACOM_PAD_FIELD. However, it is reported by touch_input. Don't register pad_input if no other pad events require the interface.
Cc: stable@vger.kernel.org Signed-off-by: Ping Cheng ping.cheng@wacom.com Reviewed-by: Jason Gerecke jason.gerecke@wacom.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hid/wacom_sys.c | 2 +- drivers/hid/wacom_wac.c | 43 +++++++++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 19 deletions(-)
--- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2121,7 +2121,7 @@ static int wacom_register_inputs(struct
error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); if (error) { - /* no pad in use on this interface */ + /* no pad events using this interface */ input_free_device(pad_input_dev); wacom_wac->pad_input = NULL; pad_input_dev = NULL; --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2019,7 +2019,6 @@ static void wacom_wac_pad_usage_mapping( wacom_wac->has_mute_touch_switch = true; usage->type = EV_SW; usage->code = SW_MUTE_DEVICE; - features->device_type |= WACOM_DEVICETYPE_PAD; break; case WACOM_HID_WD_TOUCHSTRIP: wacom_map_usage(input, usage, field, EV_ABS, ABS_RX, 0); @@ -2099,6 +2098,30 @@ static void wacom_wac_pad_event(struct h wacom_wac->hid_data.inrange_state |= value; }
+ /* Process touch switch state first since it is reported through touch interface, + * which is indepentent of pad interface. In the case when there are no other pad + * events, the pad interface will not even be created. + */ + if ((equivalent_usage == WACOM_HID_WD_MUTE_DEVICE) || + (equivalent_usage == WACOM_HID_WD_TOUCHONOFF)) { + if (wacom_wac->shared->touch_input) { + bool *is_touch_on = &wacom_wac->shared->is_touch_on; + + if (equivalent_usage == WACOM_HID_WD_MUTE_DEVICE && value) + *is_touch_on = !(*is_touch_on); + else if (equivalent_usage == WACOM_HID_WD_TOUCHONOFF) + *is_touch_on = value; + + input_report_switch(wacom_wac->shared->touch_input, + SW_MUTE_DEVICE, !(*is_touch_on)); + input_sync(wacom_wac->shared->touch_input); + } + return; + } + + if (!input) + return; + switch (equivalent_usage) { case WACOM_HID_WD_TOUCHRING: /* @@ -2134,22 +2157,6 @@ static void wacom_wac_pad_event(struct h input_event(input, usage->type, usage->code, 0); break;
- case WACOM_HID_WD_MUTE_DEVICE: - case WACOM_HID_WD_TOUCHONOFF: - if (wacom_wac->shared->touch_input) { - bool *is_touch_on = &wacom_wac->shared->is_touch_on; - - if (equivalent_usage == WACOM_HID_WD_MUTE_DEVICE && value) - *is_touch_on = !(*is_touch_on); - else if (equivalent_usage == WACOM_HID_WD_TOUCHONOFF) - *is_touch_on = value; - - input_report_switch(wacom_wac->shared->touch_input, - SW_MUTE_DEVICE, !(*is_touch_on)); - input_sync(wacom_wac->shared->touch_input); - } - break; - case WACOM_HID_WD_MODE_CHANGE: if (wacom_wac->is_direct_mode != value) { wacom_wac->is_direct_mode = value; @@ -2835,7 +2842,7 @@ void wacom_wac_event(struct hid_device * /* usage tests must precede field tests */ if (WACOM_BATTERY_USAGE(usage)) wacom_wac_battery_event(hdev, field, usage, value); - else if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) + else if (WACOM_PAD_FIELD(field)) wacom_wac_pad_event(hdev, field, usage, value); else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) wacom_wac_pen_event(hdev, field, usage, value);
From: Sean Christopherson seanjc@google.com
commit fa578398a0ba2c079fa1170da21fa5baae0cedb2 upstream.
If a nested run isn't pending, snapshot vmcs01.GUEST_BNDCFGS irrespective of whether or not VM_ENTRY_LOAD_BNDCFGS is set in vmcs12. When restoring nested state, e.g. after migration, without a nested run pending, prepare_vmcs02() will propagate nested.vmcs01_guest_bndcfgs to vmcs02, i.e. will load garbage/zeros into vmcs02.GUEST_BNDCFGS.
If userspace restores nested state before MSRs, then loading garbage is a non-issue as loading BNDCFGS will also update vmcs02. But if usersepace restores MSRs first, then KVM is responsible for propagating L2's value, which is actually thrown into vmcs01, into vmcs02.
Restoring L2 MSRs into vmcs01, i.e. loading all MSRs before nested state is all kinds of bizarre and ideally would not be supported. Sadly, some VMMs do exactly that and rely on KVM to make things work.
Note, there's still a lurking SMM bug, as propagating vmcs01.GUEST_BNDFGS to vmcs02 across RSM may corrupt L2's BNDCFGS. But KVM's entire VMX+SMM emulation is flawed as SMI+RSM should not toouch _any_ VMCS when use the "default treatment of SMIs", i.e. when not using an SMI Transfer Monitor.
Link: https://lore.kernel.org/all/Yobt1XwOfb5M6Dfa@google.com Fixes: 62cf9bd8118c ("KVM: nVMX: Fix emulation of VM_ENTRY_LOAD_BNDCFGS") Cc: stable@vger.kernel.org Cc: Lei Wang lei4.wang@intel.com Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220614215831.3762138-2-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/vmx/nested.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -3376,7 +3376,8 @@ enum nvmx_vmentry_status nested_vmx_ente if (!(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS)) vmx->nested.vmcs01_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL); if (kvm_mpx_supported() && - !(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS)) + (!vmx->nested.nested_run_pending || + !(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS))) vmx->nested.vmcs01_guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS);
/*
From: Sean Christopherson seanjc@google.com
commit 764643a6be07445308e492a528197044c801b3ba upstream.
If a nested run isn't pending, snapshot vmcs01.GUEST_IA32_DEBUGCTL irrespective of whether or not VM_ENTRY_LOAD_DEBUG_CONTROLS is set in vmcs12. When restoring nested state, e.g. after migration, without a nested run pending, prepare_vmcs02() will propagate nested.vmcs01_debugctl to vmcs02, i.e. will load garbage/zeros into vmcs02.GUEST_IA32_DEBUGCTL.
If userspace restores nested state before MSRs, then loading garbage is a non-issue as loading DEBUGCTL will also update vmcs02. But if usersepace restores MSRs first, then KVM is responsible for propagating L2's value, which is actually thrown into vmcs01, into vmcs02.
Restoring L2 MSRs into vmcs01, i.e. loading all MSRs before nested state is all kinds of bizarre and ideally would not be supported. Sadly, some VMMs do exactly that and rely on KVM to make things work.
Note, there's still a lurking SMM bug, as propagating vmcs01's DEBUGCTL to vmcs02 across RSM may corrupt L2's DEBUGCTL. But KVM's entire VMX+SMM emulation is flawed as SMI+RSM should not toouch _any_ VMCS when use the "default treatment of SMIs", i.e. when not using an SMI Transfer Monitor.
Link: https://lore.kernel.org/all/Yobt1XwOfb5M6Dfa@google.com Fixes: 8fcc4b5923af ("kvm: nVMX: Introduce KVM_CAP_NESTED_STATE") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220614215831.3762138-3-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/vmx/nested.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -3373,7 +3373,8 @@ enum nvmx_vmentry_status nested_vmx_ente if (likely(!evaluate_pending_interrupts) && kvm_vcpu_apicv_active(vcpu)) evaluate_pending_interrupts |= vmx_has_apicv_interrupt(vcpu);
- if (!(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS)) + if (!vmx->nested.nested_run_pending || + !(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS)) vmx->nested.vmcs01_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL); if (kvm_mpx_supported() && (!vmx->nested.nested_run_pending ||
From: Maciej S. Szmigiero maciej.szmigiero@oracle.com
commit f17c31c48e5cde9895a491d91c424eeeada3e134 upstream.
Don't BUG/WARN on interrupt injection due to GIF being cleared, since it's trivial for userspace to force the situation via KVM_SET_VCPU_EVENTS (even if having at least a WARN there would be correct for KVM internally generated injections).
kernel BUG at arch/x86/kvm/svm/svm.c:3386! invalid opcode: 0000 [#1] SMP CPU: 15 PID: 926 Comm: smm_test Not tainted 5.17.0-rc3+ #264 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:svm_inject_irq+0xab/0xb0 [kvm_amd] Code: <0f> 0b 0f 1f 00 0f 1f 44 00 00 80 3d ac b3 01 00 00 55 48 89 f5 53 RSP: 0018:ffffc90000b37d88 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff88810a234ac0 RCX: 0000000000000006 RDX: 0000000000000000 RSI: ffffc90000b37df7 RDI: ffff88810a234ac0 RBP: ffffc90000b37df7 R08: ffff88810a1fa410 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: ffff888109571000 R14: ffff88810a234ac0 R15: 0000000000000000 FS: 0000000001821380(0000) GS:ffff88846fdc0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f74fc550008 CR3: 000000010a6fe000 CR4: 0000000000350ea0 Call Trace: <TASK> inject_pending_event+0x2f7/0x4c0 [kvm] kvm_arch_vcpu_ioctl_run+0x791/0x17a0 [kvm] kvm_vcpu_ioctl+0x26d/0x650 [kvm] __x64_sys_ioctl+0x82/0xb0 do_syscall_64+0x3b/0xc0 entry_SYSCALL_64_after_hwframe+0x44/0xae </TASK>
Fixes: 219b65dcf6c0 ("KVM: SVM: Improve nested interrupt injection") Cc: stable@vger.kernel.org Co-developed-by: Sean Christopherson seanjc@google.com Signed-off-by: Sean Christopherson seanjc@google.com Signed-off-by: Maciej S. Szmigiero maciej.szmigiero@oracle.com Message-Id: 35426af6e123cbe91ec7ce5132ce72521f02b1b5.1651440202.git.maciej.szmigiero@oracle.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/svm/svm.c | 2 -- 1 file changed, 2 deletions(-)
--- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3385,8 +3385,6 @@ static void svm_inject_irq(struct kvm_vc { struct vcpu_svm *svm = to_svm(vcpu);
- BUG_ON(!(gif_set(svm))); - trace_kvm_inj_virq(vcpu->arch.interrupt.nr); ++vcpu->stat.irq_injections;
From: Nico Boehr nrb@linux.ibm.com
commit c3f0e5fd2d33d80c5a5a8b5e5d2bab2841709cc8 upstream.
When the SIGP interpretation facility is present and a VCPU sends an ecall to another VCPU in enabled wait, the sending VCPU receives a 56 intercept (partial execution), so KVM can wake up the receiving CPU. Note that the SIGP interpretation facility will take care of the interrupt delivery and KVM's only job is to wake the receiving VCPU.
For PV, the sending VCPU will receive a 108 intercept (pv notify) and should continue like in the non-PV case, i.e. wake the receiving VCPU.
For PV and non-PV guests the interrupt delivery will occur through the SIGP interpretation facility on SIE entry when SIE finds the X bit in the status field set.
However, in handle_pv_notification(), there was no special handling for SIGP, which leads to interrupt injection being requested by KVM for the next SIE entry. This results in the interrupt being delivered twice: once by the SIGP interpretation facility and once by KVM through the IICTL.
Add the necessary special handling in handle_pv_notification(), similar to handle_partial_execution(), which simply wakes the receiving VCPU and leave interrupt delivery to the SIGP interpretation facility.
In contrast to external calls, emergency calls are not interpreted but also cause a 108 intercept, which is why we still need to call handle_instruction() for SIGP orders other than ecall.
Since kvm_s390_handle_sigp_pei() is now called for all SIGP orders which cause a 108 intercept - even if they are actually handled by handle_instruction() - move the tracepoint in kvm_s390_handle_sigp_pei() to avoid possibly confusing trace messages.
Signed-off-by: Nico Boehr nrb@linux.ibm.com Cc: stable@vger.kernel.org # 5.7 Fixes: da24a0cc58ed ("KVM: s390: protvirt: Instruction emulation") Reviewed-by: Claudio Imbrenda imbrenda@linux.ibm.com Reviewed-by: Janosch Frank frankja@linux.ibm.com Reviewed-by: Christian Borntraeger borntraeger@linux.ibm.com Link: https://lore.kernel.org/r/20220718130434.73302-1-nrb@linux.ibm.com Message-Id: 20220718130434.73302-1-nrb@linux.ibm.com Signed-off-by: Claudio Imbrenda imbrenda@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/kvm/intercept.c | 15 +++++++++++++++ arch/s390/kvm/sigp.c | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-)
--- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c @@ -528,12 +528,27 @@ static int handle_pv_uvc(struct kvm_vcpu
static int handle_pv_notification(struct kvm_vcpu *vcpu) { + int ret; + if (vcpu->arch.sie_block->ipa == 0xb210) return handle_pv_spx(vcpu); if (vcpu->arch.sie_block->ipa == 0xb220) return handle_pv_sclp(vcpu); if (vcpu->arch.sie_block->ipa == 0xb9a4) return handle_pv_uvc(vcpu); + if (vcpu->arch.sie_block->ipa >> 8 == 0xae) { + /* + * Besides external call, other SIGP orders also cause a + * 108 (pv notify) intercept. In contrast to external call, + * these orders need to be emulated and hence the appropriate + * place to handle them is in handle_instruction(). + * So first try kvm_s390_handle_sigp_pei() and if that isn't + * successful, go on with handle_instruction(). + */ + ret = kvm_s390_handle_sigp_pei(vcpu); + if (!ret) + return ret; + }
return handle_instruction(vcpu); } --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -480,9 +480,9 @@ int kvm_s390_handle_sigp_pei(struct kvm_ struct kvm_vcpu *dest_vcpu; u8 order_code = kvm_s390_get_base_disp_rs(vcpu, NULL);
- trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); - if (order_code == SIGP_EXTERNAL_CALL) { + trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); + dest_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr); BUG_ON(dest_vcpu == NULL);
From: Sean Christopherson seanjc@google.com
commit 345b0fd6fe5f66dfe841bad0b39dd11a5672df68 upstream.
Drop the @pga param from __release_gpc() and rename the helper to make it more obvious that the cache itself is not being released. The helper will be reused by a future commit to release a pfn+khva combination that is _never_ associated with the cache, at which point the current name would go from slightly misleading to blatantly wrong.
No functional change intended.
Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220429210025.3293691-4-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- virt/kvm/pfncache.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
--- a/virt/kvm/pfncache.c +++ b/virt/kvm/pfncache.c @@ -95,7 +95,7 @@ bool kvm_gfn_to_pfn_cache_check(struct k } EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_check);
-static void __release_gpc(struct kvm *kvm, kvm_pfn_t pfn, void *khva, gpa_t gpa) +static void gpc_release_pfn_and_khva(struct kvm *kvm, kvm_pfn_t pfn, void *khva) { /* Unmap the old page if it was mapped before, and release it */ if (!is_error_noslot_pfn(pfn)) { @@ -146,7 +146,6 @@ int kvm_gfn_to_pfn_cache_refresh(struct unsigned long page_offset = gpa & ~PAGE_MASK; kvm_pfn_t old_pfn, new_pfn; unsigned long old_uhva; - gpa_t old_gpa; void *old_khva; bool old_valid; int ret = 0; @@ -160,7 +159,6 @@ int kvm_gfn_to_pfn_cache_refresh(struct
write_lock_irq(&gpc->lock);
- old_gpa = gpc->gpa; old_pfn = gpc->pfn; old_khva = gpc->khva - offset_in_page(gpc->khva); old_uhva = gpc->uhva; @@ -244,7 +242,7 @@ int kvm_gfn_to_pfn_cache_refresh(struct out: write_unlock_irq(&gpc->lock);
- __release_gpc(kvm, old_pfn, old_khva, old_gpa); + gpc_release_pfn_and_khva(kvm, old_pfn, old_khva);
return ret; } @@ -254,14 +252,12 @@ void kvm_gfn_to_pfn_cache_unmap(struct k { void *old_khva; kvm_pfn_t old_pfn; - gpa_t old_gpa;
write_lock_irq(&gpc->lock);
gpc->valid = false;
old_khva = gpc->khva - offset_in_page(gpc->khva); - old_gpa = gpc->gpa; old_pfn = gpc->pfn;
/* @@ -273,7 +269,7 @@ void kvm_gfn_to_pfn_cache_unmap(struct k
write_unlock_irq(&gpc->lock);
- __release_gpc(kvm, old_pfn, old_khva, old_gpa); + gpc_release_pfn_and_khva(kvm, old_pfn, old_khva); } EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_unmap);
From: Sean Christopherson seanjc@google.com
commit 3dddf65b4f4c451c345d34ae85bdf1791a746e49 upstream.
Put the struct page reference to pfn acquired by hva_to_pfn() when the old and new pfns for a gfn=>pfn cache match. The cache already has a reference via the old/current pfn, and will only put one reference when the cache is done with the pfn.
Fixes: 982ed0de4753 ("KVM: Reinstate gfn_to_pfn_cache with invalidation support") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220429210025.3293691-5-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- virt/kvm/pfncache.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/virt/kvm/pfncache.c +++ b/virt/kvm/pfncache.c @@ -206,6 +206,14 @@ int kvm_gfn_to_pfn_cache_refresh(struct
if (gpc->usage & KVM_HOST_USES_PFN) { if (new_pfn == old_pfn) { + /* + * Reuse the existing pfn and khva, but put the + * reference acquired hva_to_pfn_retry(); the + * cache still holds a reference to the pfn + * from the previous refresh. + */ + gpc_release_pfn_and_khva(kvm, new_pfn, NULL); + new_khva = old_khva; old_pfn = KVM_PFN_ERR_FAULT; old_khva = NULL;
From: Sean Christopherson seanjc@google.com
commit 93984f19e7bce4c18084a6ef3dacafb155b806ed upstream.
Protect gfn=>pfn cache refresh with a mutex to fully serialize refreshes. The refresh logic doesn't protect against
- concurrent unmaps, or refreshes with different GPAs (which may or may not happen in practice, for example if a cache is only used under vcpu->mutex; but it's allowed in the code)
- a false negative on the memslot generation. If the first refresh sees a stale memslot generation, it will refresh the hva and generation before moving on to the hva=>pfn translation. If it then drops gpc->lock, a different user of the cache can come along, acquire gpc->lock, see that the memslot generation is fresh, and skip the hva=>pfn update due to the userspace address also matching (because it too was updated).
The refresh path can already sleep during hva=>pfn resolution, so wrap the refresh with a mutex to ensure that any given refresh runs to completion before other callers can start their refresh.
Cc: stable@vger.kernel.org Cc: Lai Jiangshan jiangshanlai@gmail.com Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220429210025.3293691-7-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/kvm_types.h | 2 ++ virt/kvm/pfncache.c | 12 ++++++++++++ 2 files changed, 14 insertions(+)
--- a/include/linux/kvm_types.h +++ b/include/linux/kvm_types.h @@ -19,6 +19,7 @@ struct kvm_memslots; enum kvm_mr_change;
#include <linux/bits.h> +#include <linux/mutex.h> #include <linux/types.h> #include <linux/spinlock_types.h>
@@ -69,6 +70,7 @@ struct gfn_to_pfn_cache { struct kvm_vcpu *vcpu; struct list_head list; rwlock_t lock; + struct mutex refresh_lock; void *khva; kvm_pfn_t pfn; enum pfn_cache_usage usage; --- a/virt/kvm/pfncache.c +++ b/virt/kvm/pfncache.c @@ -157,6 +157,13 @@ int kvm_gfn_to_pfn_cache_refresh(struct if (page_offset + len > PAGE_SIZE) return -EINVAL;
+ /* + * If another task is refreshing the cache, wait for it to complete. + * There is no guarantee that concurrent refreshes will see the same + * gpa, memslots generation, etc..., so they must be fully serialized. + */ + mutex_lock(&gpc->refresh_lock); + write_lock_irq(&gpc->lock);
old_pfn = gpc->pfn; @@ -250,6 +257,8 @@ int kvm_gfn_to_pfn_cache_refresh(struct out: write_unlock_irq(&gpc->lock);
+ mutex_unlock(&gpc->refresh_lock); + gpc_release_pfn_and_khva(kvm, old_pfn, old_khva);
return ret; @@ -261,6 +270,7 @@ void kvm_gfn_to_pfn_cache_unmap(struct k void *old_khva; kvm_pfn_t old_pfn;
+ mutex_lock(&gpc->refresh_lock); write_lock_irq(&gpc->lock);
gpc->valid = false; @@ -276,6 +286,7 @@ void kvm_gfn_to_pfn_cache_unmap(struct k gpc->pfn = KVM_PFN_ERR_FAULT;
write_unlock_irq(&gpc->lock); + mutex_unlock(&gpc->refresh_lock);
gpc_release_pfn_and_khva(kvm, old_pfn, old_khva); } @@ -290,6 +301,7 @@ int kvm_gfn_to_pfn_cache_init(struct kvm
if (!gpc->active) { rwlock_init(&gpc->lock); + mutex_init(&gpc->refresh_lock);
gpc->khva = NULL; gpc->pfn = KVM_PFN_ERR_FAULT;
From: Sean Christopherson seanjc@google.com
commit 58cd407ca4c6278cf9f9d09a2e663bf645b0c982 upstream.
Rework the gfn=>pfn cache (gpc) refresh logic to address multiple races between the cache itself, and between the cache and mmu_notifier events.
The existing refresh code attempts to guard against races with the mmu_notifier by speculatively marking the cache valid, and then marking it invalid if a mmu_notifier invalidation occurs. That handles the case where an invalidation occurs between dropping and re-acquiring gpc->lock, but it doesn't handle the scenario where the cache is refreshed after the cache was invalidated by the notifier, but before the notifier elevates mmu_notifier_count. The gpc refresh can't use the "retry" helper as its invalidation occurs _before_ mmu_notifier_count is elevated and before mmu_notifier_range_start is set/updated.
CPU0 CPU1 ---- ----
gfn_to_pfn_cache_invalidate_start() | -> gpc->valid = false; kvm_gfn_to_pfn_cache_refresh() | |-> gpc->valid = true;
hva_to_pfn_retry() | -> acquire kvm->mmu_lock kvm->mmu_notifier_count == 0 mmu_seq == kvm->mmu_notifier_seq drop kvm->mmu_lock return pfn 'X' acquire kvm->mmu_lock kvm_inc_notifier_count() drop kvm->mmu_lock() kernel frees pfn 'X' kvm_gfn_to_pfn_cache_check() | |-> gpc->valid == true
caller accesses freed pfn 'X'
Key off of mn_active_invalidate_count to detect that a pfncache refresh needs to wait for an in-progress mmu_notifier invalidation. While mn_active_invalidate_count is not guaranteed to be stable, it is guaranteed to be elevated prior to an invalidation acquiring gpc->lock, so either the refresh will see an active invalidation and wait, or the invalidation will run after the refresh completes.
Speculatively marking the cache valid is itself flawed, as a concurrent kvm_gfn_to_pfn_cache_check() would see a valid cache with stale pfn/khva values. The KVM Xen use case explicitly allows/wants multiple users; even though the caches are allocated per vCPU, __kvm_xen_has_interrupt() can read a different vCPU (or vCPUs). Address this race by invalidating the cache prior to dropping gpc->lock (this is made possible by fixing the above mmu_notifier race).
Complicating all of this is the fact that both the hva=>pfn resolution and mapping of the kernel address can sleep, i.e. must be done outside of gpc->lock.
Fix the above races in one fell swoop, trying to fix each individual race is largely pointless and essentially impossible to test, e.g. closing one hole just shifts the focus to the other hole.
Fixes: 982ed0de4753 ("KVM: Reinstate gfn_to_pfn_cache with invalidation support") Cc: stable@vger.kernel.org Cc: David Woodhouse dwmw@amazon.co.uk Cc: Mingwei Zhang mizhang@google.com Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220429210025.3293691-8-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- virt/kvm/kvm_main.c | 9 ++ virt/kvm/pfncache.c | 193 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 131 insertions(+), 71 deletions(-)
--- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -724,6 +724,15 @@ static int kvm_mmu_notifier_invalidate_r kvm->mn_active_invalidate_count++; spin_unlock(&kvm->mn_invalidate_lock);
+ /* + * Invalidate pfn caches _before_ invalidating the secondary MMUs, i.e. + * before acquiring mmu_lock, to avoid holding mmu_lock while acquiring + * each cache's lock. There are relatively few caches in existence at + * any given time, and the caches themselves can check for hva overlap, + * i.e. don't need to rely on memslot overlap checks for performance. + * Because this runs without holding mmu_lock, the pfn caches must use + * mn_active_invalidate_count (see above) instead of mmu_notifier_count. + */ gfn_to_pfn_cache_invalidate_start(kvm, range->start, range->end, hva_range.may_block);
--- a/virt/kvm/pfncache.c +++ b/virt/kvm/pfncache.c @@ -112,31 +112,122 @@ static void gpc_release_pfn_and_khva(str } }
-static kvm_pfn_t hva_to_pfn_retry(struct kvm *kvm, unsigned long uhva) +static inline bool mmu_notifier_retry_cache(struct kvm *kvm, unsigned long mmu_seq) { + /* + * mn_active_invalidate_count acts for all intents and purposes + * like mmu_notifier_count here; but the latter cannot be used + * here because the invalidation of caches in the mmu_notifier + * event occurs _before_ mmu_notifier_count is elevated. + * + * Note, it does not matter that mn_active_invalidate_count + * is not protected by gpc->lock. It is guaranteed to + * be elevated before the mmu_notifier acquires gpc->lock, and + * isn't dropped until after mmu_notifier_seq is updated. + */ + if (kvm->mn_active_invalidate_count) + return true; + + /* + * Ensure mn_active_invalidate_count is read before + * mmu_notifier_seq. This pairs with the smp_wmb() in + * mmu_notifier_invalidate_range_end() to guarantee either the + * old (non-zero) value of mn_active_invalidate_count or the + * new (incremented) value of mmu_notifier_seq is observed. + */ + smp_rmb(); + return kvm->mmu_notifier_seq != mmu_seq; +} + +static kvm_pfn_t hva_to_pfn_retry(struct kvm *kvm, struct gfn_to_pfn_cache *gpc) +{ + /* Note, the new page offset may be different than the old! */ + void *old_khva = gpc->khva - offset_in_page(gpc->khva); + kvm_pfn_t new_pfn = KVM_PFN_ERR_FAULT; + void *new_khva = NULL; unsigned long mmu_seq; - kvm_pfn_t new_pfn; - int retry; + + lockdep_assert_held(&gpc->refresh_lock); + + lockdep_assert_held_write(&gpc->lock); + + /* + * Invalidate the cache prior to dropping gpc->lock, the gpa=>uhva + * assets have already been updated and so a concurrent check() from a + * different task may not fail the gpa/uhva/generation checks. + */ + gpc->valid = false;
do { mmu_seq = kvm->mmu_notifier_seq; smp_rmb();
+ write_unlock_irq(&gpc->lock); + + /* + * If the previous iteration "failed" due to an mmu_notifier + * event, release the pfn and unmap the kernel virtual address + * from the previous attempt. Unmapping might sleep, so this + * needs to be done after dropping the lock. Opportunistically + * check for resched while the lock isn't held. + */ + if (new_pfn != KVM_PFN_ERR_FAULT) { + /* + * Keep the mapping if the previous iteration reused + * the existing mapping and didn't create a new one. + */ + if (new_khva == old_khva) + new_khva = NULL; + + gpc_release_pfn_and_khva(kvm, new_pfn, new_khva); + + cond_resched(); + } + /* We always request a writeable mapping */ - new_pfn = hva_to_pfn(uhva, false, NULL, true, NULL); + new_pfn = hva_to_pfn(gpc->uhva, false, NULL, true, NULL); if (is_error_noslot_pfn(new_pfn)) - break; + goto out_error; + + /* + * Obtain a new kernel mapping if KVM itself will access the + * pfn. Note, kmap() and memremap() can both sleep, so this + * too must be done outside of gpc->lock! + */ + if (gpc->usage & KVM_HOST_USES_PFN) { + if (new_pfn == gpc->pfn) { + new_khva = old_khva; + } else if (pfn_valid(new_pfn)) { + new_khva = kmap(pfn_to_page(new_pfn)); +#ifdef CONFIG_HAS_IOMEM + } else { + new_khva = memremap(pfn_to_hpa(new_pfn), PAGE_SIZE, MEMREMAP_WB); +#endif + } + if (!new_khva) { + kvm_release_pfn_clean(new_pfn); + goto out_error; + } + } + + write_lock_irq(&gpc->lock);
- KVM_MMU_READ_LOCK(kvm); - retry = mmu_notifier_retry_hva(kvm, mmu_seq, uhva); - KVM_MMU_READ_UNLOCK(kvm); - if (!retry) - break; + /* + * Other tasks must wait for _this_ refresh to complete before + * attempting to refresh. + */ + WARN_ON_ONCE(gpc->valid); + } while (mmu_notifier_retry_cache(kvm, mmu_seq)); + + gpc->valid = true; + gpc->pfn = new_pfn; + gpc->khva = new_khva + (gpc->gpa & ~PAGE_MASK); + return 0;
- cond_resched(); - } while (1); +out_error: + write_lock_irq(&gpc->lock);
- return new_pfn; + return -EFAULT; }
int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, @@ -147,7 +238,6 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm_pfn_t old_pfn, new_pfn; unsigned long old_uhva; void *old_khva; - bool old_valid; int ret = 0;
/* @@ -169,7 +259,6 @@ int kvm_gfn_to_pfn_cache_refresh(struct old_pfn = gpc->pfn; old_khva = gpc->khva - offset_in_page(gpc->khva); old_uhva = gpc->uhva; - old_valid = gpc->valid;
/* If the userspace HVA is invalid, refresh that first */ if (gpc->gpa != gpa || gpc->generation != slots->generation || @@ -182,7 +271,6 @@ int kvm_gfn_to_pfn_cache_refresh(struct gpc->uhva = gfn_to_hva_memslot(gpc->memslot, gfn);
if (kvm_is_error_hva(gpc->uhva)) { - gpc->pfn = KVM_PFN_ERR_FAULT; ret = -EFAULT; goto out; } @@ -194,60 +282,8 @@ int kvm_gfn_to_pfn_cache_refresh(struct * If the userspace HVA changed or the PFN was already invalid, * drop the lock and do the HVA to PFN lookup again. */ - if (!old_valid || old_uhva != gpc->uhva) { - unsigned long uhva = gpc->uhva; - void *new_khva = NULL; - - /* Placeholders for "hva is valid but not yet mapped" */ - gpc->pfn = KVM_PFN_ERR_FAULT; - gpc->khva = NULL; - gpc->valid = true; - - write_unlock_irq(&gpc->lock); - - new_pfn = hva_to_pfn_retry(kvm, uhva); - if (is_error_noslot_pfn(new_pfn)) { - ret = -EFAULT; - goto map_done; - } - - if (gpc->usage & KVM_HOST_USES_PFN) { - if (new_pfn == old_pfn) { - /* - * Reuse the existing pfn and khva, but put the - * reference acquired hva_to_pfn_retry(); the - * cache still holds a reference to the pfn - * from the previous refresh. - */ - gpc_release_pfn_and_khva(kvm, new_pfn, NULL); - - new_khva = old_khva; - old_pfn = KVM_PFN_ERR_FAULT; - old_khva = NULL; - } else if (pfn_valid(new_pfn)) { - new_khva = kmap(pfn_to_page(new_pfn)); -#ifdef CONFIG_HAS_IOMEM - } else { - new_khva = memremap(pfn_to_hpa(new_pfn), PAGE_SIZE, MEMREMAP_WB); -#endif - } - if (new_khva) - new_khva += page_offset; - else - ret = -EFAULT; - } - - map_done: - write_lock_irq(&gpc->lock); - if (ret) { - gpc->valid = false; - gpc->pfn = KVM_PFN_ERR_FAULT; - gpc->khva = NULL; - } else { - /* At this point, gpc->valid may already have been cleared */ - gpc->pfn = new_pfn; - gpc->khva = new_khva; - } + if (!gpc->valid || old_uhva != gpc->uhva) { + ret = hva_to_pfn_retry(kvm, gpc); } else { /* If the HVA→PFN mapping was already valid, don't unmap it. */ old_pfn = KVM_PFN_ERR_FAULT; @@ -255,11 +291,26 @@ int kvm_gfn_to_pfn_cache_refresh(struct }
out: + /* + * Invalidate the cache and purge the pfn/khva if the refresh failed. + * Some/all of the uhva, gpa, and memslot generation info may still be + * valid, leave it as is. + */ + if (ret) { + gpc->valid = false; + gpc->pfn = KVM_PFN_ERR_FAULT; + gpc->khva = NULL; + } + + /* Snapshot the new pfn before dropping the lock! */ + new_pfn = gpc->pfn; + write_unlock_irq(&gpc->lock);
mutex_unlock(&gpc->refresh_lock);
- gpc_release_pfn_and_khva(kvm, old_pfn, old_khva); + if (old_pfn != new_pfn) + gpc_release_pfn_and_khva(kvm, old_pfn, old_khva);
return ret; }
From: Sean Christopherson seanjc@google.com
commit 3ba2c95ea180740b16281fa43a3ee5f47279c0ed upstream.
Don't adjust the userspace address in the gfn=>pfn cache by the page offset from the gpa. KVM should never use the user address directly, and all KVM operations that translate a user address to something else require the user address to be page aligned. Ignoring the offset will allow the cache to reuse a gfn=>hva translation in the unlikely event that the page offset of the gpa changes, but the gfn does not. And more importantly, not having to (un)adjust the user address will simplify a future bug fix.
Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220429210025.3293691-6-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- virt/kvm/pfncache.c | 2 -- 1 file changed, 2 deletions(-)
--- a/virt/kvm/pfncache.c +++ b/virt/kvm/pfncache.c @@ -274,8 +274,6 @@ int kvm_gfn_to_pfn_cache_refresh(struct ret = -EFAULT; goto out; } - - gpc->uhva += page_offset; }
/*
From: Sean Christopherson seanjc@google.com
commit c33f6f2228fe8517e38941a508e9f905f99ecba9 upstream.
Split the common x86 parts of kvm_is_valid_cr4(), i.e. the reserved bits checks, into a separate helper, __kvm_is_valid_cr4(), and export only the inner helper to vendor code in order to prevent nested VMX from calling back into vmx_is_valid_cr4() via kvm_is_valid_cr4().
On SVM, this is a nop as SVM doesn't place any additional restrictions on CR4.
On VMX, this is also currently a nop, but only because nested VMX is missing checks on reserved CR4 bits for nested VM-Enter. That bug will be fixed in a future patch, and could simply use kvm_is_valid_cr4() as-is, but nVMX has _another_ bug where VMXON emulation doesn't enforce VMX's restrictions on CR0/CR4. The cleanest and most intuitive way to fix the VMXON bug is to use nested_host_cr{0,4}_valid(). If the CR4 variant routes through kvm_is_valid_cr4(), using nested_host_cr4_valid() won't do the right thing for the VMXON case as vmx_is_valid_cr4() enforces VMX's restrictions if and only if the vCPU is post-VMXON.
Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220607213604.3346000-2-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/svm/nested.c | 3 ++- arch/x86/kvm/vmx/vmx.c | 4 ++-- arch/x86/kvm/x86.c | 12 +++++++++--- arch/x86/kvm/x86.h | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-)
--- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -320,7 +320,8 @@ static bool __nested_vmcb_check_save(str return false; }
- if (CC(!kvm_is_valid_cr4(vcpu, save->cr4))) + /* Note, SVM doesn't have any additional restrictions on CR4. */ + if (CC(!__kvm_is_valid_cr4(vcpu, save->cr4))) return false;
if (CC(!kvm_valid_efer(vcpu, save->efer))) --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -3230,8 +3230,8 @@ static bool vmx_is_valid_cr4(struct kvm_ { /* * We operate under the default treatment of SMM, so VMX cannot be - * enabled under SMM. Note, whether or not VMXE is allowed at all is - * handled by kvm_is_valid_cr4(). + * enabled under SMM. Note, whether or not VMXE is allowed at all, + * i.e. is a reserved bit, is handled by common x86 code. */ if ((cr4 & X86_CR4_VMXE) && is_smm(vcpu)) return false; --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1094,7 +1094,7 @@ int kvm_emulate_xsetbv(struct kvm_vcpu * } EXPORT_SYMBOL_GPL(kvm_emulate_xsetbv);
-bool kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) +bool __kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { if (cr4 & cr4_reserved_bits) return false; @@ -1102,9 +1102,15 @@ bool kvm_is_valid_cr4(struct kvm_vcpu *v if (cr4 & vcpu->arch.cr4_guest_rsvd_bits) return false;
- return static_call(kvm_x86_is_valid_cr4)(vcpu, cr4); + return true; +} +EXPORT_SYMBOL_GPL(__kvm_is_valid_cr4); + +static bool kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) +{ + return __kvm_is_valid_cr4(vcpu, cr4) && + static_call(kvm_x86_is_valid_cr4)(vcpu, cr4); } -EXPORT_SYMBOL_GPL(kvm_is_valid_cr4);
void kvm_post_set_cr4(struct kvm_vcpu *vcpu, unsigned long old_cr4, unsigned long cr4) { --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -407,7 +407,7 @@ static inline void kvm_machine_check(voi void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu); void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu); int kvm_spec_ctrl_test_value(u64 value); -bool kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); +bool __kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); int kvm_handle_memory_failure(struct kvm_vcpu *vcpu, int r, struct x86_exception *e); int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsigned long type, gva_t gva);
From: Sean Christopherson seanjc@google.com
commit f8ae08f9789ad59d318ea75b570caa454aceda81 upstream.
Restrict the nVMX MSRs based on KVM's config, not based on the guest's current config. Using the guest's config to audit the new config prevents userspace from restoring the original config (KVM's config) if at any point in the past the guest's config was restricted in any way.
Fixes: 62cc6b9dc61e ("KVM: nVMX: support restore of VMX capability MSRs") Cc: stable@vger.kernel.org Cc: David Matlack dmatlack@google.com Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220607213604.3346000-6-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/vmx/nested.c | 70 ++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 33 deletions(-)
--- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -1223,7 +1223,7 @@ static int vmx_restore_vmx_basic(struct BIT_ULL(49) | BIT_ULL(54) | BIT_ULL(55) | /* reserved */ BIT_ULL(31) | GENMASK_ULL(47, 45) | GENMASK_ULL(63, 56); - u64 vmx_basic = vmx->nested.msrs.basic; + u64 vmx_basic = vmcs_config.nested.basic;
if (!is_bitwise_subset(vmx_basic, data, feature_and_reserved)) return -EINVAL; @@ -1246,36 +1246,42 @@ static int vmx_restore_vmx_basic(struct return 0; }
-static int -vmx_restore_control_msr(struct vcpu_vmx *vmx, u32 msr_index, u64 data) +static void vmx_get_control_msr(struct nested_vmx_msrs *msrs, u32 msr_index, + u32 **low, u32 **high) { - u64 supported; - u32 *lowp, *highp; - switch (msr_index) { case MSR_IA32_VMX_TRUE_PINBASED_CTLS: - lowp = &vmx->nested.msrs.pinbased_ctls_low; - highp = &vmx->nested.msrs.pinbased_ctls_high; + *low = &msrs->pinbased_ctls_low; + *high = &msrs->pinbased_ctls_high; break; case MSR_IA32_VMX_TRUE_PROCBASED_CTLS: - lowp = &vmx->nested.msrs.procbased_ctls_low; - highp = &vmx->nested.msrs.procbased_ctls_high; + *low = &msrs->procbased_ctls_low; + *high = &msrs->procbased_ctls_high; break; case MSR_IA32_VMX_TRUE_EXIT_CTLS: - lowp = &vmx->nested.msrs.exit_ctls_low; - highp = &vmx->nested.msrs.exit_ctls_high; + *low = &msrs->exit_ctls_low; + *high = &msrs->exit_ctls_high; break; case MSR_IA32_VMX_TRUE_ENTRY_CTLS: - lowp = &vmx->nested.msrs.entry_ctls_low; - highp = &vmx->nested.msrs.entry_ctls_high; + *low = &msrs->entry_ctls_low; + *high = &msrs->entry_ctls_high; break; case MSR_IA32_VMX_PROCBASED_CTLS2: - lowp = &vmx->nested.msrs.secondary_ctls_low; - highp = &vmx->nested.msrs.secondary_ctls_high; + *low = &msrs->secondary_ctls_low; + *high = &msrs->secondary_ctls_high; break; default: BUG(); } +} + +static int +vmx_restore_control_msr(struct vcpu_vmx *vmx, u32 msr_index, u64 data) +{ + u32 *lowp, *highp; + u64 supported; + + vmx_get_control_msr(&vmcs_config.nested, msr_index, &lowp, &highp);
supported = vmx_control_msr(*lowp, *highp);
@@ -1287,6 +1293,7 @@ vmx_restore_control_msr(struct vcpu_vmx if (!is_bitwise_subset(supported, data, GENMASK_ULL(63, 32))) return -EINVAL;
+ vmx_get_control_msr(&vmx->nested.msrs, msr_index, &lowp, &highp); *lowp = data; *highp = data >> 32; return 0; @@ -1300,10 +1307,8 @@ static int vmx_restore_vmx_misc(struct v BIT_ULL(28) | BIT_ULL(29) | BIT_ULL(30) | /* reserved */ GENMASK_ULL(13, 9) | BIT_ULL(31); - u64 vmx_misc; - - vmx_misc = vmx_control_msr(vmx->nested.msrs.misc_low, - vmx->nested.msrs.misc_high); + u64 vmx_misc = vmx_control_msr(vmcs_config.nested.misc_low, + vmcs_config.nested.misc_high);
if (!is_bitwise_subset(vmx_misc, data, feature_and_reserved_bits)) return -EINVAL; @@ -1331,10 +1336,8 @@ static int vmx_restore_vmx_misc(struct v
static int vmx_restore_vmx_ept_vpid_cap(struct vcpu_vmx *vmx, u64 data) { - u64 vmx_ept_vpid_cap; - - vmx_ept_vpid_cap = vmx_control_msr(vmx->nested.msrs.ept_caps, - vmx->nested.msrs.vpid_caps); + u64 vmx_ept_vpid_cap = vmx_control_msr(vmcs_config.nested.ept_caps, + vmcs_config.nested.vpid_caps);
/* Every bit is either reserved or a feature bit. */ if (!is_bitwise_subset(vmx_ept_vpid_cap, data, -1ULL)) @@ -1345,20 +1348,21 @@ static int vmx_restore_vmx_ept_vpid_cap( return 0; }
-static int vmx_restore_fixed0_msr(struct vcpu_vmx *vmx, u32 msr_index, u64 data) +static u64 *vmx_get_fixed0_msr(struct nested_vmx_msrs *msrs, u32 msr_index) { - u64 *msr; - switch (msr_index) { case MSR_IA32_VMX_CR0_FIXED0: - msr = &vmx->nested.msrs.cr0_fixed0; - break; + return &msrs->cr0_fixed0; case MSR_IA32_VMX_CR4_FIXED0: - msr = &vmx->nested.msrs.cr4_fixed0; - break; + return &msrs->cr4_fixed0; default: BUG(); } +} + +static int vmx_restore_fixed0_msr(struct vcpu_vmx *vmx, u32 msr_index, u64 data) +{ + const u64 *msr = vmx_get_fixed0_msr(&vmcs_config.nested, msr_index);
/* * 1 bits (which indicates bits which "must-be-1" during VMX operation) @@ -1367,7 +1371,7 @@ static int vmx_restore_fixed0_msr(struct if (!is_bitwise_subset(data, *msr, -1ULL)) return -EINVAL;
- *msr = data; + *vmx_get_fixed0_msr(&vmx->nested.msrs, msr_index) = data; return 0; }
@@ -1428,7 +1432,7 @@ int vmx_set_vmx_msr(struct kvm_vcpu *vcp vmx->nested.msrs.vmcs_enum = data; return 0; case MSR_IA32_VMX_VMFUNC: - if (data & ~vmx->nested.msrs.vmfunc_controls) + if (data & ~vmcs_config.nested.vmfunc_controls) return -EINVAL; vmx->nested.msrs.vmfunc_controls = data; return 0;
From: Sean Christopherson seanjc@google.com
commit ca58f3aa53d165afe4ab74c755bc2f6d168617ac upstream.
Check that the guest (L2) and host (L1) CR4 values that would be loaded by nested VM-Enter and VM-Exit respectively are valid with respect to KVM's (L0 host) allowed CR4 bits. Failure to check KVM reserved bits would allow L1 to load an illegal CR4 (or trigger hardware VM-Fail or failed VM-Entry) by massaging guest CPUID to allow features that are not supported by KVM. Amusingly, KVM itself is an accomplice in its doom, as KVM adjusts L1's MSR_IA32_VMX_CR4_FIXED1 to allow L1 to enable bits for L2 based on L1's CPUID model.
Note, although nested_{guest,host}_cr4_valid() are _currently_ used if and only if the vCPU is post-VMXON (nested.vmxon == true), that may not be true in the future, e.g. emulating VMXON has a bug where it doesn't check the allowed/required CR0/CR4 bits.
Cc: stable@vger.kernel.org Fixes: 3899152ccbf4 ("KVM: nVMX: fix checks on CR{0,4} during virtual VMX operation") Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220607213604.3346000-3-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/vmx/nested.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/x86/kvm/vmx/nested.h +++ b/arch/x86/kvm/vmx/nested.h @@ -281,7 +281,8 @@ static inline bool nested_cr4_valid(stru u64 fixed0 = to_vmx(vcpu)->nested.msrs.cr4_fixed0; u64 fixed1 = to_vmx(vcpu)->nested.msrs.cr4_fixed1;
- return fixed_bits_valid(val, fixed0, fixed1); + return fixed_bits_valid(val, fixed0, fixed1) && + __kvm_is_valid_cr4(vcpu, val); }
/* No difference in the restrictions on guest and host CR4 in VMX operation. */
From: Sean Christopherson seanjc@google.com
commit c7d855c2aff2d511fd60ee2e356134c4fb394799 upstream.
Inject a #UD if L1 attempts VMXON with a CR0 or CR4 that is disallowed per the associated nested VMX MSRs' fixed0/1 settings. KVM cannot rely on hardware to perform the checks, even for the few checks that have higher priority than VM-Exit, as (a) KVM may have forced CR0/CR4 bits in hardware while running the guest, (b) there may incompatible CR0/CR4 bits that have lower priority than VM-Exit, e.g. CR0.NE, and (c) userspace may have further restricted the allowed CR0/CR4 values by manipulating the guest's nested VMX MSRs.
Note, despite a very strong desire to throw shade at Jim, commit 70f3aac964ae ("kvm: nVMX: Remove superfluous VMX instruction fault checks") is not to blame for the buggy behavior (though the comment...). That commit only removed the CR0.PE, EFLAGS.VM, and COMPATIBILITY mode checks (though it did erroneously drop the CPL check, but that has already been remedied). KVM may force CR0.PE=1, but will do so only when also forcing EFLAGS.VM=1 to emulate Real Mode, i.e. hardware will still #UD.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216033 Fixes: ec378aeef9df ("KVM: nVMX: Implement VMXON and VMXOFF") Reported-by: Eric Li ercli@ucdavis.edu Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220607213604.3346000-4-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/vmx/nested.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
--- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -4968,20 +4968,25 @@ static int handle_vmon(struct kvm_vcpu * | FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
/* - * The Intel VMX Instruction Reference lists a bunch of bits that are - * prerequisite to running VMXON, most notably cr4.VMXE must be set to - * 1 (see vmx_is_valid_cr4() for when we allow the guest to set this). - * Otherwise, we should fail with #UD. But most faulting conditions - * have already been checked by hardware, prior to the VM-exit for - * VMXON. We do test guest cr4.VMXE because processor CR4 always has - * that bit set to 1 in non-root mode. + * Note, KVM cannot rely on hardware to perform the CR0/CR4 #UD checks + * that have higher priority than VM-Exit (see Intel SDM's pseudocode + * for VMXON), as KVM must load valid CR0/CR4 values into hardware while + * running the guest, i.e. KVM needs to check the _guest_ values. + * + * Rely on hardware for the other two pre-VM-Exit checks, !VM86 and + * !COMPATIBILITY modes. KVM may run the guest in VM86 to emulate Real + * Mode, but KVM will never take the guest out of those modes. */ - if (!kvm_read_cr4_bits(vcpu, X86_CR4_VMXE)) { + if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) || + !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) { kvm_queue_exception(vcpu, UD_VECTOR); return 1; }
- /* CPL=0 must be checked manually. */ + /* + * CPL=0 and all other checks that are lower priority than VM-Exit must + * be checked manually. + */ if (vmx_get_cpl(vcpu)) { kvm_inject_gp(vcpu, 0); return 1;
From: Sean Christopherson seanjc@google.com
commit ec6e4d863258d4bfb36d48d5e3ef68140234d688 upstream.
Wait to mark the TSS as busy during LTR emulation until after all fault checks for the LTR have passed. Specifically, don't mark the TSS busy if the new TSS base is non-canonical.
Opportunistically drop the one-off !seg_desc.PRESENT check for TR as the only reason for the early check was to avoid marking a !PRESENT TSS as busy, i.e. the common !PRESENT is now done before setting the busy bit.
Fixes: e37a75a13cda ("KVM: x86: Emulator ignores LDTR/TR extended base on LLDT/LTR") Reported-by: syzbot+760a73552f47a8cd0fd9@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Cc: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp Cc: Hou Wenlong houwenlong.hwl@antgroup.com Signed-off-by: Sean Christopherson seanjc@google.com Reviewed-by: Maxim Levitsky mlevitsk@redhat.com Link: https://lore.kernel.org/r/20220711232750.1092012-2-seanjc@google.com Signed-off-by: Sean Christopherson seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/emulate.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
--- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1687,16 +1687,6 @@ static int __load_segment_descriptor(str case VCPU_SREG_TR: if (seg_desc.s || (seg_desc.type != 1 && seg_desc.type != 9)) goto exception; - if (!seg_desc.p) { - err_vec = NP_VECTOR; - goto exception; - } - old_desc = seg_desc; - seg_desc.type |= 2; /* busy */ - ret = ctxt->ops->cmpxchg_emulated(ctxt, desc_addr, &old_desc, &seg_desc, - sizeof(seg_desc), &ctxt->exception); - if (ret != X86EMUL_CONTINUE) - return ret; break; case VCPU_SREG_LDTR: if (seg_desc.s || seg_desc.type != 2) @@ -1737,6 +1727,15 @@ static int __load_segment_descriptor(str ((u64)base3 << 32), ctxt)) return emulate_gp(ctxt, 0); } + + if (seg == VCPU_SREG_TR) { + old_desc = seg_desc; + seg_desc.type |= 2; /* busy */ + ret = ctxt->ops->cmpxchg_emulated(ctxt, desc_addr, &old_desc, &seg_desc, + sizeof(seg_desc), &ctxt->exception); + if (ret != X86EMUL_CONTINUE) + return ret; + } load: ctxt->ops->set_segment(ctxt, selector, &seg_desc, base3, seg); if (desc)
From: Sean Christopherson seanjc@google.com
commit 2626206963ace9e8bf92b6eea5ff78dd674c555c upstream.
When injecting a #GP on LLDT/LTR due to a non-canonical LDT/TSS base, set the error code to the selector. Intel SDM's says nothing about the #GP, but AMD's APM explicitly states that both LLDT and LTR set the error code to the selector, not zero.
Note, a non-canonical memory operand on LLDT/LTR does generate a #GP(0), but the KVM code in question is specific to the base from the descriptor.
Fixes: e37a75a13cda ("KVM: x86: Emulator ignores LDTR/TR extended base on LLDT/LTR") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Reviewed-by: Maxim Levitsky mlevitsk@redhat.com Link: https://lore.kernel.org/r/20220711232750.1092012-3-seanjc@google.com Signed-off-by: Sean Christopherson seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/emulate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1724,8 +1724,8 @@ static int __load_segment_descriptor(str if (ret != X86EMUL_CONTINUE) return ret; if (emul_is_noncanonical_address(get_desc_base(&seg_desc) | - ((u64)base3 << 32), ctxt)) - return emulate_gp(ctxt, 0); + ((u64)base3 << 32), ctxt)) + return emulate_gp(ctxt, err_code); }
if (seg == VCPU_SREG_TR) {
From: Sean Christopherson seanjc@google.com
commit 6c6ab524cfae0799e55c82b2c1d61f1af0156f8d upstream.
Treat the NX bit as valid when using NPT, as KVM will set the NX bit when the NX huge page mitigation is enabled (mindblowing) and trigger the WARN that fires on reserved SPTE bits being set.
KVM has required NX support for SVM since commit b26a71a1a5b9 ("KVM: SVM: Refuse to load kvm_amd if NX support is not available") for exactly this reason, but apparently it never occurred to anyone to actually test NPT with the mitigation enabled.
------------[ cut here ]------------ spte = 0x800000018a600ee7, level = 2, rsvd bits = 0x800f0000001fe000 WARNING: CPU: 152 PID: 15966 at arch/x86/kvm/mmu/spte.c:215 make_spte+0x327/0x340 [kvm] Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 10.48.0 01/27/2022 RIP: 0010:make_spte+0x327/0x340 [kvm] Call Trace: <TASK> tdp_mmu_map_handle_target_level+0xc3/0x230 [kvm] kvm_tdp_mmu_map+0x343/0x3b0 [kvm] direct_page_fault+0x1ae/0x2a0 [kvm] kvm_tdp_page_fault+0x7d/0x90 [kvm] kvm_mmu_page_fault+0xfb/0x2e0 [kvm] npf_interception+0x55/0x90 [kvm_amd] svm_invoke_exit_handler+0x31/0xf0 [kvm_amd] svm_handle_exit+0xf6/0x1d0 [kvm_amd] vcpu_enter_guest+0xb6d/0xee0 [kvm] ? kvm_pmu_trigger_event+0x6d/0x230 [kvm] vcpu_run+0x65/0x2c0 [kvm] kvm_arch_vcpu_ioctl_run+0x355/0x610 [kvm] kvm_vcpu_ioctl+0x551/0x610 [kvm] __se_sys_ioctl+0x77/0xc0 __x64_sys_ioctl+0x1d/0x20 do_syscall_64+0x44/0xa0 entry_SYSCALL_64_after_hwframe+0x46/0xb0 </TASK> ---[ end trace 0000000000000000 ]---
Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220723013029.1753623-1-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/mmu/mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -4567,7 +4567,7 @@ reset_tdp_shadow_zero_bits_mask(struct k
if (boot_cpu_is_amd()) __reset_rsvds_bits_mask(shadow_zero_check, reserved_hpa_bits(), - context->root_role.level, false, + context->root_role.level, true, boot_cpu_has(X86_FEATURE_GBPAGES), false, true); else
From: Sean Christopherson seanjc@google.com
commit 0c29397ac1fdd64ae59941a477511a05e61a4754 upstream.
Disable SEV-ES if MMIO caching is disabled as SEV-ES relies on MMIO SPTEs generating #NPF(RSVD), which are reflected by the CPU into the guest as a #VC. With SEV-ES, the untrusted host, a.k.a. KVM, doesn't have access to the guest instruction stream or register state and so can't directly emulate in response to a #NPF on an emulated MMIO GPA. Disabling MMIO caching means guest accesses to emulated MMIO ranges cause #NPF(!PRESENT), and those flavors of #NPF cause automatic VM-Exits, not #VC.
Adjust KVM's MMIO masks to account for the C-bit location prior to doing SEV(-ES) setup, and document that dependency between adjusting the MMIO SPTE mask and SEV(-ES) setup.
Fixes: b09763da4dd8 ("KVM: x86/mmu: Add module param to disable MMIO caching (for testing)") Reported-by: Michael Roth michael.roth@amd.com Tested-by: Michael Roth michael.roth@amd.com Cc: Tom Lendacky thomas.lendacky@amd.com Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220803224957.1285926-4-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/mmu.h | 2 ++ arch/x86/kvm/mmu/spte.c | 1 + arch/x86/kvm/mmu/spte.h | 2 -- arch/x86/kvm/svm/sev.c | 10 ++++++++++ arch/x86/kvm/svm/svm.c | 9 ++++++--- 5 files changed, 19 insertions(+), 5 deletions(-)
--- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -11,6 +11,8 @@ #define PT32_PT_BITS 10 #define PT32_ENT_PER_PAGE (1 << PT32_PT_BITS)
+extern bool __read_mostly enable_mmio_caching; + #define PT_WRITABLE_SHIFT 1 #define PT_USER_SHIFT 2
--- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -21,6 +21,7 @@
bool __read_mostly enable_mmio_caching = true; module_param_named(mmio_caching, enable_mmio_caching, bool, 0444); +EXPORT_SYMBOL_GPL(enable_mmio_caching);
u64 __read_mostly shadow_host_writable_mask; u64 __read_mostly shadow_mmu_writable_mask; --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -5,8 +5,6 @@
#include "mmu_internal.h"
-extern bool __read_mostly enable_mmio_caching; - /* * A MMU present SPTE is backed by actual memory and may or may not be present * in hardware. E.g. MMIO SPTEs are not considered present. Use bit 11, as it --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -22,6 +22,7 @@ #include <asm/trapnr.h> #include <asm/fpu/xcr.h>
+#include "mmu.h" #include "x86.h" #include "svm.h" #include "svm_ops.h" @@ -2221,6 +2222,15 @@ void __init sev_hardware_setup(void) if (!sev_es_enabled) goto out;
+ /* + * SEV-ES requires MMIO caching as KVM doesn't have access to the guest + * instruction stream, i.e. can't emulate in response to a #NPF and + * instead relies on #NPF(RSVD) being reflected into the guest as #VC + * (the guest can then do a #VMGEXIT to request MMIO emulation). + */ + if (!enable_mmio_caching) + goto out; + /* Does the CPU support SEV-ES? */ if (!boot_cpu_has(X86_FEATURE_SEV_ES)) goto out; --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4897,13 +4897,16 @@ static __init int svm_hardware_setup(voi /* Setup shadow_me_value and shadow_me_mask */ kvm_mmu_set_me_spte_mask(sme_me_mask, sme_me_mask);
- /* Note, SEV setup consumes npt_enabled. */ + svm_adjust_mmio_mask(); + + /* + * Note, SEV setup consumes npt_enabled and enable_mmio_caching (which + * may be modified by svm_adjust_mmio_mask()). + */ sev_hardware_setup();
svm_hv_hardware_setup();
- svm_adjust_mmio_mask(); - for_each_possible_cpu(cpu) { r = svm_cpu_init(cpu); if (r)
From: Sean Christopherson seanjc@google.com
commit 982bae43f11c37b51d2f1961bb25ef7cac3746fa upstream.
Mark kvm_mmu_x86_module_init() with __init, the entire reason it exists is to initialize variables when kvm.ko is loaded, i.e. it must never be called after module initialization.
Fixes: 1d0e84806047 ("KVM: x86/mmu: Resolve nx_huge_pages when kvm.ko is loaded") Cc: stable@vger.kernel.org Reviewed-by: Kai Huang kai.huang@intel.com Tested-by: Michael Roth michael.roth@amd.com Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220803224957.1285926-2-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/mmu/mmu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
--- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1654,7 +1654,7 @@ static inline int kvm_arch_flush_remote_ #define kvm_arch_pmi_in_guest(vcpu) \ ((vcpu) && (vcpu)->arch.handling_intr_from_guest)
-void kvm_mmu_x86_module_init(void); +void __init kvm_mmu_x86_module_init(void); int kvm_mmu_vendor_module_init(void); void kvm_mmu_vendor_module_exit(void);
--- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -6275,7 +6275,7 @@ static int set_nx_huge_pages(const char * nx_huge_pages needs to be resolved to true/false when kvm.ko is loaded, as * its default value of -1 is technically undefined behavior for a boolean. */ -void kvm_mmu_x86_module_init(void) +void __init kvm_mmu_x86_module_init(void) { if (nx_huge_pages == -1) __set_nx_huge_pages(get_nx_auto_mode());
From: Sean Christopherson seanjc@google.com
commit c3e0c8c2e8b17bae30d5978bc2decdd4098f0f99 upstream.
Fully re-evaluate whether or not MMIO caching can be enabled when SPTE masks change; simply clearing enable_mmio_caching when a configuration isn't compatible with caching fails to handle the scenario where the masks are updated, e.g. by VMX for EPT or by SVM to account for the C-bit location, and toggle compatibility from false=>true.
Snapshot the original module param so that re-evaluating MMIO caching preserves userspace's desire to allow caching. Use a snapshot approach so that enable_mmio_caching still reflects KVM's actual behavior.
Fixes: 8b9e74bfbf8c ("KVM: x86/mmu: Use enable_mmio_caching to track if MMIO caching is enabled") Reported-by: Michael Roth michael.roth@amd.com Cc: Tom Lendacky thomas.lendacky@amd.com Cc: stable@vger.kernel.org Tested-by: Michael Roth michael.roth@amd.com Signed-off-by: Sean Christopherson seanjc@google.com Reviewed-by: Kai Huang kai.huang@intel.com Message-Id: 20220803224957.1285926-3-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/mmu/mmu.c | 4 ++++ arch/x86/kvm/mmu/spte.c | 19 +++++++++++++++++++ arch/x86/kvm/mmu/spte.h | 1 + 3 files changed, 24 insertions(+)
--- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -6274,11 +6274,15 @@ static int set_nx_huge_pages(const char /* * nx_huge_pages needs to be resolved to true/false when kvm.ko is loaded, as * its default value of -1 is technically undefined behavior for a boolean. + * Forward the module init call to SPTE code so that it too can handle module + * params that need to be resolved/snapshot. */ void __init kvm_mmu_x86_module_init(void) { if (nx_huge_pages == -1) __set_nx_huge_pages(get_nx_auto_mode()); + + kvm_mmu_spte_module_init(); }
/* --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -20,6 +20,7 @@ #include <asm/vmx.h>
bool __read_mostly enable_mmio_caching = true; +static bool __ro_after_init allow_mmio_caching; module_param_named(mmio_caching, enable_mmio_caching, bool, 0444); EXPORT_SYMBOL_GPL(enable_mmio_caching);
@@ -43,6 +44,18 @@ u64 __read_mostly shadow_nonpresent_or_r
u8 __read_mostly shadow_phys_bits;
+void __init kvm_mmu_spte_module_init(void) +{ + /* + * Snapshot userspace's desire to allow MMIO caching. Whether or not + * KVM can actually enable MMIO caching depends on vendor-specific + * hardware capabilities and other module params that can't be resolved + * until the vendor module is loaded, i.e. enable_mmio_caching can and + * will change when the vendor module is (re)loaded. + */ + allow_mmio_caching = enable_mmio_caching; +} + static u64 generation_mmio_spte_mask(u64 gen) { u64 mask; @@ -338,6 +351,12 @@ void kvm_mmu_set_mmio_spte_mask(u64 mmio BUG_ON((u64)(unsigned)access_mask != access_mask); WARN_ON(mmio_value & shadow_nonpresent_or_rsvd_lower_gfn_mask);
+ /* + * Reset to the original module param value to honor userspace's desire + * to (dis)allow MMIO caching. Update the param itself so that + * userspace can see whether or not KVM is actually using MMIO caching. + */ + enable_mmio_caching = allow_mmio_caching; if (!enable_mmio_caching) mmio_value = 0;
--- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -444,6 +444,7 @@ static inline u64 restore_acc_track_spte
u64 kvm_mmu_changed_pte_notifier_make_spte(u64 old_spte, kvm_pfn_t new_pfn);
+void __init kvm_mmu_spte_module_init(void); void kvm_mmu_reset_all_pte_masks(void);
#endif
From: Paolo Bonzini pbonzini@redhat.com
commit c3c28d24d910a746b02f496d190e0e8c6560224b upstream.
Commit 7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status", 2021-11-11) open coded the previous call to kvm_map_gfn, but in doing so it dropped the comparison between the cached guest physical address and the one in the MSR. This cause an incorrect cache hit if the guest modifies the steal time address while the memslots remain the same. This can happen with kexec, in which case the preempted bit is written at the address used by the old kernel instead of the old one.
Cc: David Woodhouse dwmw@amazon.co.uk Cc: stable@vger.kernel.org Fixes: 7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status") Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4635,6 +4635,7 @@ static void kvm_steal_time_set_preempted struct kvm_steal_time __user *st; struct kvm_memslots *slots; static const u8 preempted = KVM_VCPU_PREEMPTED; + gpa_t gpa = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS;
/* * The vCPU can be marked preempted if and only if the VM-Exit was on @@ -4662,6 +4663,7 @@ static void kvm_steal_time_set_preempted slots = kvm_memslots(vcpu->kvm);
if (unlikely(slots->generation != ghc->generation || + gpa != ghc->gpa || kvm_is_error_hva(ghc->hva) || !ghc->memslot)) return;
From: Paolo Bonzini pbonzini@redhat.com
commit 901d3765fa804ce42812f1d5b1f3de2dfbb26723 upstream.
Commit 7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status", 2021-11-11) open coded the previous call to kvm_map_gfn, but in doing so it dropped the comparison between the cached guest physical address and the one in the MSR. This cause an incorrect cache hit if the guest modifies the steal time address while the memslots remain the same. This can happen with kexec, in which case the steal time data is written at the address used by the old kernel instead of the old one.
While at it, rename the variable from gfn to gpa since it is a plain physical address and not a right-shifted one.
Reported-by: Dave Young ruyang@redhat.com Reported-by: Xiaoying Yan yiyan@redhat.com Analyzed-by: Dr. David Alan Gilbert dgilbert@redhat.com Cc: David Woodhouse dwmw@amazon.co.uk Cc: stable@vger.kernel.org Fixes: 7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status") Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3386,6 +3386,7 @@ static void record_steal_time(struct kvm struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache; struct kvm_steal_time __user *st; struct kvm_memslots *slots; + gpa_t gpa = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS; u64 steal; u32 version;
@@ -3403,13 +3404,12 @@ static void record_steal_time(struct kvm slots = kvm_memslots(vcpu->kvm);
if (unlikely(slots->generation != ghc->generation || + gpa != ghc->gpa || kvm_is_error_hva(ghc->hva) || !ghc->memslot)) { - gfn_t gfn = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS; - /* We rely on the fact that it fits in a single page. */ BUILD_BUG_ON((sizeof(*st) - 1) & KVM_STEAL_VALID_BITS);
- if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gfn, sizeof(*st)) || + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gpa, sizeof(*st)) || kvm_is_error_hva(ghc->hva) || !ghc->memslot) return; }
From: Coleman Dietsch dietschc@csp.edu
commit af735db31285fa699384c649be72a9f32ecbb665 upstream.
Add a check for existing xen timers before initializing a new one.
Currently kvm_xen_init_timer() is called on every KVM_XEN_VCPU_ATTR_TYPE_TIMER, which is causing the following ODEBUG crash when vcpu->arch.xen.timer is already set.
ODEBUG: init active (active state 0) object type: hrtimer hint: xen_timer_callbac0 RIP: 0010:debug_print_object+0x16e/0x250 lib/debugobjects.c:502 Call Trace: __debug_object_init debug_hrtimer_init debug_init hrtimer_init kvm_xen_init_timer kvm_xen_vcpu_set_attr kvm_arch_vcpu_ioctl kvm_vcpu_ioctl vfs_ioctl
Fixes: 536395260582 ("KVM: x86/xen: handle PV timers oneshot mode") Cc: stable@vger.kernel.org Link: https://syzkaller.appspot.com/bug?id=8234a9dfd3aafbf092cc5a7cd9842e3ebc45fc4... Reported-by: syzbot+e54f930ed78eb0f85281@syzkaller.appspotmail.com Signed-off-by: Coleman Dietsch dietschc@csp.edu Reviewed-by: Sean Christopherson seanjc@google.com Message-Id: 20220808190607.323899-2-dietschc@csp.edu Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/xen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -713,7 +713,9 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcp break; } vcpu->arch.xen.timer_virq = data->u.timer.port; - kvm_xen_init_timer(vcpu); + + if (!vcpu->arch.xen.timer.function) + kvm_xen_init_timer(vcpu);
/* Restart the timer if it's set */ if (data->u.timer.expires_ns)
From: Coleman Dietsch dietschc@csp.edu
commit c036899136355758dcd88878145036ab4d9c1f26 upstream.
Stop Xen timer (if it's running) prior to changing the IRQ vector and potentially (re)starting the timer. Changing the IRQ vector while the timer is still running can result in KVM injecting a garbage event, e.g. vm_xen_inject_timer_irqs() could see a non-zero xen.timer_pending from a previous timer but inject the new xen.timer_virq.
Fixes: 536395260582 ("KVM: x86/xen: handle PV timers oneshot mode") Cc: stable@vger.kernel.org Link: https://syzkaller.appspot.com/bug?id=8234a9dfd3aafbf092cc5a7cd9842e3ebc45fc4... Reported-by: syzbot+e54f930ed78eb0f85281@syzkaller.appspotmail.com Signed-off-by: Coleman Dietsch dietschc@csp.edu Reviewed-by: Sean Christopherson seanjc@google.com Acked-by: David Woodhouse dwmw@amazon.co.uk Message-Id: 20220808190607.323899-3-dietschc@csp.edu Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/xen.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-)
--- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -707,25 +707,24 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcp break;
case KVM_XEN_VCPU_ATTR_TYPE_TIMER: - if (data->u.timer.port) { - if (data->u.timer.priority != KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL) { - r = -EINVAL; - break; - } - vcpu->arch.xen.timer_virq = data->u.timer.port; + if (data->u.timer.port && + data->u.timer.priority != KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL) { + r = -EINVAL; + break; + }
- if (!vcpu->arch.xen.timer.function) - kvm_xen_init_timer(vcpu); + if (!vcpu->arch.xen.timer.function) + kvm_xen_init_timer(vcpu);
- /* Restart the timer if it's set */ - if (data->u.timer.expires_ns) - kvm_xen_start_timer(vcpu, data->u.timer.expires_ns, - data->u.timer.expires_ns - - get_kvmclock_ns(vcpu->kvm)); - } else if (kvm_xen_timer_enabled(vcpu)) { - kvm_xen_stop_timer(vcpu); - vcpu->arch.xen.timer_virq = 0; - } + /* Stop the timer (if it's running) before changing the vector */ + kvm_xen_stop_timer(vcpu); + vcpu->arch.xen.timer_virq = data->u.timer.port; + + /* Start the timer if the new value has a valid vector+expiry. */ + if (data->u.timer.port && data->u.timer.expires_ns) + kvm_xen_start_timer(vcpu, data->u.timer.expires_ns, + data->u.timer.expires_ns - + get_kvmclock_ns(vcpu->kvm));
r = 0; break;
From: Meng Tang tangmeng@uniontech.com
commit f83bb2592482fe94c6eea07a8121763c80f36ce5 upstream.
There is another LENOVO 20149 (Type1Sku0) Notebook model with CX20590, the device PCI SSID is 17aa:3977, which headphones are not responding, that requires the quirk CXT_PINCFG_LENOVO_NOTEBOOK. Add the corresponding entry to the quirk table.
Signed-off-by: Meng Tang tangmeng@uniontech.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220808073406.19460-1-tangmeng@uniontech.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_conexant.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
--- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -222,6 +222,7 @@ enum { CXT_PINCFG_LEMOTE_A1205, CXT_PINCFG_COMPAQ_CQ60, CXT_FIXUP_STEREO_DMIC, + CXT_PINCFG_LENOVO_NOTEBOOK, CXT_FIXUP_INC_MIC_BOOST, CXT_FIXUP_HEADPHONE_MIC_PIN, CXT_FIXUP_HEADPHONE_MIC, @@ -772,6 +773,14 @@ static const struct hda_fixup cxt_fixups .type = HDA_FIXUP_FUNC, .v.func = cxt_fixup_stereo_dmic, }, + [CXT_PINCFG_LENOVO_NOTEBOOK] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x1a, 0x05d71030 }, + { } + }, + .chain_id = CXT_FIXUP_STEREO_DMIC, + }, [CXT_FIXUP_INC_MIC_BOOST] = { .type = HDA_FIXUP_FUNC, .v.func = cxt5066_increase_mic_boost, @@ -971,7 +980,7 @@ static const struct snd_pci_quirk cxt506 SND_PCI_QUIRK(0x17aa, 0x3905, "Lenovo G50-30", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_PINCFG_LENOVO_NOTEBOOK), SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo G50-70", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI),
From: Allen Ballway ballway@chromium.org
commit 74bba640d69914cf832b87f6bbb700e5ba430672 upstream.
The 12,1 model requires the same configuration as the 12,2 model to enable headphones but has a different codec SSID. Adds 12,1 SSID for matching quirk.
[ re-sorted in SSID order by tiwai ]
Signed-off-by: Allen Ballway ballway@chromium.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220810152701.1.I902c2e591bbf8de9acb649d1322fa1f2... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_cirrus.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -395,6 +395,7 @@ static const struct snd_pci_quirk cs420x
/* codec SSID */ SND_PCI_QUIRK(0x106b, 0x0600, "iMac 14,1", CS420X_IMAC27_122), + SND_PCI_QUIRK(0x106b, 0x0900, "iMac 12,1", CS420X_IMAC27_122), SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101),
From: Meng Tang tangmeng@uniontech.com
commit f882c4bef9cb914d9f7be171afb10ed26536bfa7 upstream.
There is another Asus K42JZ model with the PCI SSID 1043:1313 that requires the quirk ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE. Add the corresponding entry to the quirk table.
Signed-off-by: Meng Tang tangmeng@uniontech.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220805074534.20003-1-tangmeng@uniontech.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6879,6 +6879,7 @@ enum { ALC269_FIXUP_LIMIT_INT_MIC_BOOST, ALC269VB_FIXUP_ASUS_ZENBOOK, ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, + ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE, ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, ALC269VB_FIXUP_ORDISSIMO_EVE2, ALC283_FIXUP_CHROME_BOOK, @@ -7466,6 +7467,15 @@ static const struct hda_fixup alc269_fix .chained = true, .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK, }, + [ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x18, 0x01a110f0 }, /* use as headset mic */ + { } + }, + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MIC + }, [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_limit_int_mic_boost, @@ -9237,6 +9247,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
From: Bedant Patnaik bedant.patnaik@gmail.com
commit 30267718fe2d4dbea49015b022f6f1fe16ca31ab upstream.
Board ID 8786 seems to be another variant of the Omen 15 that needs ALC285_FIXUP_HP_MUTE_LED for working mute LED.
Signed-off-by: Bedant Patnaik bedant.patnaik@gmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220809142455.6473-1-bedant.patnaik@gmail.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 @@ -9178,6 +9178,7 @@ static const struct snd_pci_quirk alc269 ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8783, "HP ZBook Fury 15 G7 Mobile Workstation", ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x8786, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8787, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8788, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED),
From: Huacai Chen chenhuacai@loongson.cn
commit 28e112afa44ad0814120d41c68fa72372a2cd2c2 upstream.
When CONFIG_CPUMASK_OFFSTACK and CONFIG_DEBUG_PER_CPU_MAPS is selected, cpu_max_bits_warn() generates a runtime warning similar as below while we show /proc/cpuinfo. Fix this by using nr_cpu_ids (the runtime limit) instead of NR_CPUS to iterate CPUs.
[ 3.052463] ------------[ cut here ]------------ [ 3.059679] WARNING: CPU: 3 PID: 1 at include/linux/cpumask.h:108 show_cpuinfo+0x5e8/0x5f0 [ 3.070072] Modules linked in: efivarfs autofs4 [ 3.076257] CPU: 0 PID: 1 Comm: systemd Not tainted 5.19-rc5+ #1052 [ 3.084034] Hardware name: Loongson Loongson-3A5000-7A1000-1w-V0.1-CRB/Loongson-LS3A5000-7A1000-1w-EVB-V1.21, BIOS Loongson-UDK2018-V2.0.04082-beta7 04/27 [ 3.099465] Stack : 9000000100157b08 9000000000f18530 9000000000cf846c 9000000100154000 [ 3.109127] 9000000100157a50 0000000000000000 9000000100157a58 9000000000ef7430 [ 3.118774] 90000001001578e8 0000000000000040 0000000000000020 ffffffffffffffff [ 3.128412] 0000000000aaaaaa 1ab25f00eec96a37 900000010021de80 900000000101c890 [ 3.138056] 0000000000000000 0000000000000000 0000000000000000 0000000000aaaaaa [ 3.147711] ffff8000339dc220 0000000000000001 0000000006ab4000 0000000000000000 [ 3.157364] 900000000101c998 0000000000000004 9000000000ef7430 0000000000000000 [ 3.167012] 0000000000000009 000000000000006c 0000000000000000 0000000000000000 [ 3.176641] 9000000000d3de08 9000000001639390 90000000002086d8 00007ffff0080286 [ 3.186260] 00000000000000b0 0000000000000004 0000000000000000 0000000000071c1c [ 3.195868] ... [ 3.199917] Call Trace: [ 3.203941] [<90000000002086d8>] show_stack+0x38/0x14c [ 3.210666] [<9000000000cf846c>] dump_stack_lvl+0x60/0x88 [ 3.217625] [<900000000023d268>] __warn+0xd0/0x100 [ 3.223958] [<9000000000cf3c90>] warn_slowpath_fmt+0x7c/0xcc [ 3.231150] [<9000000000210220>] show_cpuinfo+0x5e8/0x5f0 [ 3.238080] [<90000000004f578c>] seq_read_iter+0x354/0x4b4 [ 3.245098] [<90000000004c2e90>] new_sync_read+0x17c/0x1c4 [ 3.252114] [<90000000004c5174>] vfs_read+0x138/0x1d0 [ 3.258694] [<90000000004c55f8>] ksys_read+0x70/0x100 [ 3.265265] [<9000000000cfde9c>] do_syscall+0x7c/0x94 [ 3.271820] [<9000000000202fe4>] handle_syscall+0xc4/0x160 [ 3.281824] ---[ end trace 8b484262b4b8c24c ]---
Cc: stable@vger.kernel.org Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/loongarch/kernel/proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/loongarch/kernel/proc.c +++ b/arch/loongarch/kernel/proc.c @@ -106,7 +106,7 @@ static void *c_start(struct seq_file *m, { unsigned long i = *pos;
- return i < NR_CPUS ? (void *)(i + 1) : NULL; + return i < nr_cpu_ids ? (void *)(i + 1) : NULL; }
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
From: Cameron Williams cang1@live.co.uk
commit ef5a03a26c87a760bc3d86b5af7b773e82f8b1b7 upstream.
Add support for some of the Brainboxes PCIe (PX) range of serial cards, including the PX-101, PX-235/PX-246, PX-203/PX-257, PX-260/PX-701, PX-310, PX-313, PX-320/PX-324/PX-376/PX-387, PX-335/PX-346, PX-368, PX-420, PX-803 and PX-846.
Signed-off-by: Cameron Williams cang1@live.co.uk Cc: stable stable@kernel.org Link: https://lore.kernel.org/r/AM5PR0202MB2564669252BDC59BF55A6E87C4879@AM5PR0202... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/8250/8250_pci.c | 109 +++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+)
--- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -5077,6 +5077,115 @@ static const struct pci_device_id serial 0, 0, pbn_b2_4_115200 }, /* + * Brainboxes PX-101 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4005, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b0_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4019, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_2_15625000 }, + /* + * Brainboxes PX-235/246 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4004, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b0_1_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4016, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_1_15625000 }, + /* + * Brainboxes PX-203/PX-257 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4006, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b0_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4015, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_4_15625000 }, + /* + * Brainboxes PX-260/PX-701 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x400A, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_4_15625000 }, + /* + * Brainboxes PX-310 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x400E, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_2_15625000 }, + /* + * Brainboxes PX-313 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x400C, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_2_15625000 }, + /* + * Brainboxes PX-320/324/PX-376/PX-387 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x400B, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_1_15625000 }, + /* + * Brainboxes PX-335/346 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x400F, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_4_15625000 }, + /* + * Brainboxes PX-368 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4010, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_4_15625000 }, + /* + * Brainboxes PX-420 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4000, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b0_4_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4011, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_4_15625000 }, + /* + * Brainboxes PX-803 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4009, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b0_1_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x401E, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_1_15625000 }, + /* + * Brainboxes PX-846 + */ + { PCI_VENDOR_ID_INTASHIELD, 0x4008, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b0_1_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4017, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_oxsemi_1_15625000 }, + + /* * Perle PCI-RAS cards */ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
commit af77c56aa35325daa2bc2bed5c2ebf169be61b86 upstream.
syzbot reports kernel infoleak at vcs_read() [1], for buffer can be read immediately after resize operation. Initialize buffer using kzalloc().
---------- #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/fb.h>
int main(int argc, char *argv[]) { struct fb_var_screeninfo var = { }; const int fb_fd = open("/dev/fb0", 3); ioctl(fb_fd, FBIOGET_VSCREENINFO, &var); var.yres = 0x21; ioctl(fb_fd, FBIOPUT_VSCREENINFO, &var); return read(open("/dev/vcsu", O_RDONLY), &var, sizeof(var)) == -1; } ----------
Link: https://syzkaller.appspot.com/bug?extid=31a641689d43387f05d3 [1] Cc: stable stable@vger.kernel.org Reported-by: syzbot syzbot+31a641689d43387f05d3@syzkaller.appspotmail.com Reviewed-by: Jiri Slaby jirislaby@kernel.org Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Link: https://lore.kernel.org/r/4ef053cf-e796-fb5e-58b7-3ae58242a4ad@I-love.SAKURA... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/vt/vt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -344,7 +344,7 @@ static struct uni_screen *vc_uniscr_allo /* allocate everything in one go */ memsize = cols * rows * sizeof(char32_t); memsize += rows * sizeof(char32_t *); - p = vmalloc(memsize); + p = vzalloc(memsize); if (!p) return NULL;
From: David Howells dhowells@redhat.com
commit e2ebff9c57fe4eb104ce4768f6ebcccf76bef849 upstream.
If something manages to set the maximum file size to MAX_OFFSET+1, this can cause the xfs and ext4 filesystems at least to become corrupt.
Ordinarily, the kernel protects against userspace trying this by checking the value early in the truncate() and ftruncate() system calls calls - but there are at least two places that this check is bypassed:
(1) Cachefiles will round up the EOF of the backing file to DIO block size so as to allow DIO on the final block - but this might push the offset negative. It then calls notify_change(), but this inadvertently bypasses the checking. This can be triggered if someone puts an 8EiB-1 file on a server for someone else to try and access by, say, nfs.
(2) ksmbd doesn't check the value it is given in set_end_of_file_info() and then calls vfs_truncate() directly - which also bypasses the check.
In both cases, it is potentially possible for a network filesystem to cause a disk filesystem to be corrupted: cachefiles in the client's cache filesystem; ksmbd in the server's filesystem.
nfsd is okay as it checks the value, but we can then remove this check too.
Fix this by adding a check to inode_newsize_ok(), as called from setattr_prepare(), thereby catching the issue as filesystems set up to perform the truncate with minimal opportunity for bypassing the new check.
Fixes: 1f08c925e7a3 ("cachefiles: Implement backing file wrangling") Fixes: f44158485826 ("cifsd: add file operations") Signed-off-by: David Howells dhowells@redhat.com Reported-by: Jeff Layton jlayton@kernel.org Tested-by: Jeff Layton jlayton@kernel.org Reviewed-by: Namjae Jeon linkinjeon@kernel.org Cc: stable@kernel.org Acked-by: Alexander Viro viro@zeniv.linux.org.uk cc: Steve French sfrench@samba.org cc: Hyunchul Lee hyc.lee@gmail.com cc: Chuck Lever chuck.lever@oracle.com cc: Dave Wysochanski dwysocha@redhat.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/attr.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/fs/attr.c +++ b/fs/attr.c @@ -184,6 +184,8 @@ EXPORT_SYMBOL(setattr_prepare); */ int inode_newsize_ok(const struct inode *inode, loff_t offset) { + if (offset < 0) + return -EINVAL; if (inode->i_size < offset) { unsigned long limit;
From: Yang Xu xuyang2018.jy@fujitsu.com
commit ac6800e279a22b28f4fc21439843025a0d5bf03e upstream.
All creation paths except for O_TMPFILE handle umask in the vfs directly if the filesystem doesn't support or enable POSIX ACLs. If the filesystem does then umask handling is deferred until posix_acl_create(). Because, O_TMPFILE misses umask handling in the vfs it will not honor umask settings. Fix this by adding the missing umask handling.
Link: https://lore.kernel.org/r/1657779088-2242-2-git-send-email-xuyang2018.jy@fuj... Fixes: 60545d0d4610 ("[O_TMPFILE] it's still short a few helpers, but infrastructure should be OK now...") Cc: stable@vger.kernel.org # 4.19+ Reported-by: Christian Brauner (Microsoft) brauner@kernel.org Reviewed-by: Darrick J. Wong djwong@kernel.org Reviewed-and-Tested-by: Jeff Layton jlayton@kernel.org Acked-by: Christian Brauner (Microsoft) brauner@kernel.org Signed-off-by: Yang Xu xuyang2018.jy@fujitsu.com Signed-off-by: Christian Brauner (Microsoft) brauner@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/namei.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/fs/namei.c +++ b/fs/namei.c @@ -3565,6 +3565,8 @@ struct dentry *vfs_tmpfile(struct user_n child = d_alloc(dentry, &slash_name); if (unlikely(!child)) goto out_err; + if (!IS_POSIXACL(dir)) + mode &= ~current_umask(); error = dir->i_op->tmpfile(mnt_userns, dir, child, mode); if (error) goto out_err;
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
commit d5a8aa5d7d80d21ab6b266f1bed4194b61746199 upstream.
If cooling_device_stats_setup() fails to create the stats object, it must clear the last slot in cooling_device_attr_groups that was initially empty (so as to make it possible to add stats attributes to the cooling device attribute groups).
Failing to do so may cause the stats attributes to be created by mistake for a device that doesn't have a stats object, because the slot in question might be populated previously during the registration of another cooling device.
Fixes: 8ea229511e06 ("thermal: Add cooling device's statistics in sysfs") Reported-by: Di Shen di.shen@unisoc.com Tested-by: Di Shen di.shen@unisoc.com Cc: 4.17+ stable@vger.kernel.org # 4.17+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/thermal/thermal_sysfs.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
--- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -813,12 +813,13 @@ static const struct attribute_group cool
static void cooling_device_stats_setup(struct thermal_cooling_device *cdev) { + const struct attribute_group *stats_attr_group = NULL; struct cooling_dev_stats *stats; unsigned long states; int var;
if (cdev->ops->get_max_state(cdev, &states)) - return; + goto out;
states++; /* Total number of states is highest state + 1 */
@@ -828,7 +829,7 @@ static void cooling_device_stats_setup(s
stats = kzalloc(var, GFP_KERNEL); if (!stats) - return; + goto out;
stats->time_in_state = (ktime_t *)(stats + 1); stats->trans_table = (unsigned int *)(stats->time_in_state + states); @@ -838,9 +839,12 @@ static void cooling_device_stats_setup(s
spin_lock_init(&stats->lock);
+ stats_attr_group = &cooling_device_stats_attr_group; + +out: /* Fill the empty slot left in cooling_device_attr_groups */ var = ARRAY_SIZE(cooling_device_attr_groups) - 2; - cooling_device_attr_groups[var] = &cooling_device_stats_attr_group; + cooling_device_attr_groups[var] = stats_attr_group; }
static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev)
From: Helge Deller deller@gmx.de
commit cad564ca557f8d3bb3b1fa965d9a2b3f6490ec69 upstream.
The user may use the fbcon=vc:<n1>-<n2> option to tell fbcon to take over the given range (n1...n2) of consoles. The value for n1 and n2 needs to be a positive number and up to (MAX_NR_CONSOLES - 1). The given values were not fully checked against those boundaries yet.
To fix the issue, convert first_fb_vc and last_fb_vc to unsigned integers and check them against the upper boundary, and make sure that first_fb_vc is smaller than last_fb_vc.
Cc: stable@vger.kernel.org # v4.19+ Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Signed-off-by: Helge Deller deller@gmx.de Link: https://patchwork.freedesktop.org/patch/msgid/YpkYRMojilrtZIgM@p100 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/video/fbdev/core/fbcon.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -125,8 +125,8 @@ static int logo_lines; enums. */ static int logo_shown = FBCON_LOGO_CANSHOW; /* console mappings */ -static int first_fb_vc; -static int last_fb_vc = MAX_NR_CONSOLES - 1; +static unsigned int first_fb_vc; +static unsigned int last_fb_vc = MAX_NR_CONSOLES - 1; static int fbcon_is_default = 1; static int primary_device = -1; static int fbcon_has_console_bind; @@ -440,10 +440,12 @@ static int __init fb_console_setup(char options += 3; if (*options) first_fb_vc = simple_strtoul(options, &options, 10) - 1; - if (first_fb_vc < 0) + if (first_fb_vc >= MAX_NR_CONSOLES) first_fb_vc = 0; if (*options++ == '-') last_fb_vc = simple_strtoul(options, &options, 10) - 1; + if (last_fb_vc < first_fb_vc || last_fb_vc >= MAX_NR_CONSOLES) + last_fb_vc = MAX_NR_CONSOLES - 1; fbcon_is_default = 0; continue; }
From: Helge Deller deller@gmx.de
commit 3866cba87dcd0162fb41e9b3b653d0af68fad5ec upstream.
There is no need to directly skip over to the SCROLL_REDRAW case while the logo is still shown.
When using DRM, this change has no effect because the code will reach the SCROLL_REDRAW case immediately anyway.
But if you run an accelerated fbdev driver and have FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION enabled, console scrolling is slowed down by factors so that it feels as if you use a 9600 baud terminal.
So, drop those unnecessary checks and speed up fbdev console acceleration during bootup.
Cc: stable@vger.kernel.org # v5.10+ Acked-by: Daniel Vetter daniel.vetter@ffwll.ch Signed-off-by: Helge Deller deller@gmx.de Link: https://patchwork.freedesktop.org/patch/msgid/YpkYxk7wsBPx3po+@p100 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/video/fbdev/core/fbcon.c | 4 ---- 1 file changed, 4 deletions(-)
--- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -1760,8 +1760,6 @@ static bool fbcon_scroll(struct vc_data case SM_UP: if (count > vc->vc_rows) /* Maximum realistic size */ count = vc->vc_rows; - if (logo_shown >= 0) - goto redraw_up; switch (fb_scrollmode(p)) { case SCROLL_MOVE: fbcon_redraw_blit(vc, info, p, t, b - t - count, @@ -1850,8 +1848,6 @@ static bool fbcon_scroll(struct vc_data case SM_DOWN: if (count > vc->vc_rows) /* Maximum realistic size */ count = vc->vc_rows; - if (logo_shown >= 0) - goto redraw_down; switch (fb_scrollmode(p)) { case SCROLL_MOVE: fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
From: Lukas Wunner lukas@wunner.de
commit a69e617e533edddf3fa3123149900f36e0a6dc74 upstream.
usbnet uses the work usbnet_deferred_kevent() to perform tasks which may sleep. On disconnect, completion of the work was originally awaited in ->ndo_stop(). But in 2003, that was moved to ->disconnect() by historic commit "[PATCH] USB: usbnet, prevent exotic rtnl deadlock":
https://git.kernel.org/tglx/history/c/0f138bbfd83c
The change was made because back then, the kernel's workqueue implementation did not allow waiting for a single work. One had to wait for completion of *all* work by calling flush_scheduled_work(), and that could deadlock when waiting for usbnet_deferred_kevent() with rtnl_mutex held in ->ndo_stop().
The commit solved one problem but created another: It causes a use-after-free in USB Ethernet drivers aqc111.c, asix_devices.c, ax88179_178a.c, ch9200.c and smsc75xx.c:
* If the drivers receive a link change interrupt immediately before disconnect, they raise EVENT_LINK_RESET in their (non-sleepable) ->status() callback and schedule usbnet_deferred_kevent(). * usbnet_deferred_kevent() invokes the driver's ->link_reset() callback, which calls netif_carrier_{on,off}(). * That in turn schedules the work linkwatch_event().
Because usbnet_deferred_kevent() is awaited after unregister_netdev(), netif_carrier_{on,off}() may operate on an unregistered netdev and linkwatch_event() may run after free_netdev(), causing a use-after-free.
In 2010, usbnet was changed to only wait for a single instance of usbnet_deferred_kevent() instead of *all* work by commit 23f333a2bfaf ("drivers/net: don't use flush_scheduled_work()").
Unfortunately the commit neglected to move the wait back to ->ndo_stop(). Rectify that omission at long last.
Reported-by: Jann Horn jannh@google.com Link: https://lore.kernel.org/netdev/CAG48ez0MHBbENX5gCdHAUXZ7h7s20LnepBF-pa5M=7Bi... Reported-by: Oleksij Rempel o.rempel@pengutronix.de Link: https://lore.kernel.org/netdev/20220315113841.GA22337@pengutronix.de/ Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org Acked-by: Oliver Neukum oneukum@suse.com Link: https://lore.kernel.org/r/d1c87ebe9fc502bffcd1576e238d685ad08321e4.165598788... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/usb/usbnet.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
--- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -849,13 +849,11 @@ int usbnet_stop (struct net_device *net)
mpn = !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags);
- /* deferred work (task, timer, softirq) must also stop. - * can't flush_scheduled_work() until we drop rtnl (later), - * else workers could deadlock; so make workers a NOP. - */ + /* deferred work (timer, softirq, task) must also stop */ dev->flags = 0; del_timer_sync (&dev->delay); tasklet_kill (&dev->bh); + cancel_work_sync(&dev->kevent); if (!pm) usb_autopm_put_interface(dev->intf);
@@ -1619,8 +1617,6 @@ void usbnet_disconnect (struct usb_inter net = dev->net; unregister_netdev (net);
- cancel_work_sync(&dev->kevent); - usb_scuttle_anchored_urbs(&dev->deferred);
if (dev->driver_info->unbind)
From: Lukas Wunner lukas@wunner.de
commit 7b960c967f2aa01ab8f45c5a0bd78e754cffdeee upstream.
Commit 05b35e7eb9a1 ("smsc95xx: add phylib support") amended smsc95xx_resume() to call phy_init_hw(). That function waits for the device to runtime resume even though it is placed in the runtime resume path, causing a deadlock.
The problem is that phy_init_hw() calls down to smsc95xx_mdiobus_read(), which never uses the _nopm variant of usbnet_read_cmd().
Commit b4df480f68ae ("usbnet: smsc95xx: add reset_resume function with reset operation") causes a similar deadlock on resume if the device was already runtime suspended when entering system sleep:
That's because the commit introduced smsc95xx_reset_resume(), which calls down to smsc95xx_reset(), which neglects to use _nopm accessors.
Fix by auto-detecting whether a device access is performed by the suspend/resume task_struct and use the _nopm variant if so. This works because the PM core guarantees that suspend/resume callbacks are run in task context.
Stacktrace for posterity:
INFO: task kworker/2:1:49 blocked for more than 122 seconds. Workqueue: usb_hub_wq hub_event schedule rpm_resume __pm_runtime_resume usb_autopm_get_interface usbnet_read_cmd __smsc95xx_read_reg __smsc95xx_phy_wait_not_busy __smsc95xx_mdio_read smsc95xx_mdiobus_read __mdiobus_read mdiobus_read smsc_phy_reset phy_init_hw smsc95xx_resume usb_resume_interface usb_resume_both usb_runtime_resume __rpm_callback rpm_callback rpm_resume __pm_runtime_resume usb_autoresume_device hub_event process_one_work
Fixes: b4df480f68ae ("usbnet: smsc95xx: add reset_resume function with reset operation") Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v3.16+ Cc: Andre Edich andre.edich@microchip.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/usb/smsc95xx.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
--- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -71,6 +71,7 @@ struct smsc95xx_priv { struct fwnode_handle *irqfwnode; struct mii_bus *mdiobus; struct phy_device *phydev; + struct task_struct *pm_task; };
static bool turbo_mode = true; @@ -80,13 +81,14 @@ MODULE_PARM_DESC(turbo_mode, "Enable mul static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data, int in_pm) { + struct smsc95xx_priv *pdata = dev->driver_priv; u32 buf; int ret; int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
BUG_ON(!dev);
- if (!in_pm) + if (current != pdata->pm_task) fn = usbnet_read_cmd; else fn = usbnet_read_cmd_nopm; @@ -110,13 +112,14 @@ static int __must_check __smsc95xx_read_ static int __must_check __smsc95xx_write_reg(struct usbnet *dev, u32 index, u32 data, int in_pm) { + struct smsc95xx_priv *pdata = dev->driver_priv; u32 buf; int ret; int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
BUG_ON(!dev);
- if (!in_pm) + if (current != pdata->pm_task) fn = usbnet_write_cmd; else fn = usbnet_write_cmd_nopm; @@ -1490,9 +1493,12 @@ static int smsc95xx_suspend(struct usb_i u32 val, link_up; int ret;
+ pdata->pm_task = current; + ret = usbnet_suspend(intf, message); if (ret < 0) { netdev_warn(dev->net, "usbnet_suspend error\n"); + pdata->pm_task = NULL; return ret; }
@@ -1732,6 +1738,7 @@ done: if (ret && PMSG_IS_AUTO(message)) usbnet_resume(intf);
+ pdata->pm_task = NULL; return ret; }
@@ -1752,29 +1759,31 @@ static int smsc95xx_resume(struct usb_in /* do this first to ensure it's cleared even in error case */ pdata->suspend_flags = 0;
+ pdata->pm_task = current; + if (suspend_flags & SUSPEND_ALLMODES) { /* clear wake-up sources */ ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); if (ret < 0) - return ret; + goto done;
val &= ~(WUCSR_WAKE_EN_ | WUCSR_MPEN_);
ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); if (ret < 0) - return ret; + goto done;
/* clear wake-up status */ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); if (ret < 0) - return ret; + goto done;
val &= ~PM_CTL_WOL_EN_; val |= PM_CTL_WUPS_;
ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); if (ret < 0) - return ret; + goto done; }
phy_init_hw(pdata->phydev); @@ -1783,15 +1792,20 @@ static int smsc95xx_resume(struct usb_in if (ret < 0) netdev_warn(dev->net, "usbnet_resume error\n");
+done: + pdata->pm_task = NULL; return ret; }
static int smsc95xx_reset_resume(struct usb_interface *intf) { struct usbnet *dev = usb_get_intfdata(intf); + struct smsc95xx_priv *pdata = dev->driver_priv; int ret;
+ pdata->pm_task = current; ret = smsc95xx_reset(dev); + pdata->pm_task = NULL; if (ret < 0) return ret;
From: Al Viro viro@zeniv.linux.org.uk
commit c3497fd009ef2c59eea60d21c3ac22de3585ed7d upstream.
Unlike other copying operations on ITER_PIPE, copy_mc_to_iter() can result in a short copy. In that case we need to trim the unused buffers, as well as the length of partially filled one - it's not enough to set ->head, ->iov_offset and ->count to reflect how much had we copied. Not hard to fix, fortunately...
I'd put a helper (pipe_discard_from(pipe, head)) into pipe_fs_i.h, rather than iov_iter.c - it has nothing to do with iov_iter and having it will allow us to avoid an ugly kludge in fs/splice.c. We could put it into lib/iov_iter.c for now and move it later, but I don't see the point going that way...
Cc: stable@kernel.org # 4.19+ Fixes: ca146f6f091e "lib/iov_iter: Fix pipe handling in _copy_to_iter_mcsafe()" Reviewed-by: Jeff Layton jlayton@kernel.org Reviewed-by: Christian Brauner (Microsoft) brauner@kernel.org Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/pipe_fs_i.h | 9 +++++++++ lib/iov_iter.c | 15 +++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-)
--- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -229,6 +229,15 @@ static inline bool pipe_buf_try_steal(st return buf->ops->try_steal(pipe, buf); }
+static inline void pipe_discard_from(struct pipe_inode_info *pipe, + unsigned int old_head) +{ + unsigned int mask = pipe->ring_size - 1; + + while (pipe->head > old_head) + pipe_buf_release(pipe, &pipe->bufs[--pipe->head & mask]); +} + /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual memory allocation, whereas PIPE_BUF makes atomicity guarantees. */ #define PIPE_SIZE PAGE_SIZE --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -689,6 +689,7 @@ static size_t copy_mc_pipe_to_iter(const struct pipe_inode_info *pipe = i->pipe; unsigned int p_mask = pipe->ring_size - 1; unsigned int i_head; + unsigned int valid = pipe->head; size_t n, off, xfer = 0;
if (!sanity(i)) @@ -702,11 +703,17 @@ static size_t copy_mc_pipe_to_iter(const rem = copy_mc_to_kernel(p + off, addr + xfer, chunk); chunk -= rem; kunmap_local(p); - i->head = i_head; - i->iov_offset = off + chunk; - xfer += chunk; - if (rem) + if (chunk) { + i->head = i_head; + i->iov_offset = off + chunk; + xfer += chunk; + valid = i_head + 1; + } + if (rem) { + pipe->bufs[i_head & p_mask].len -= rem; + pipe_discard_from(pipe, valid); break; + } n -= chunk; off = 0; i_head++;
From: John Allen john.allen@amd.com
commit 13dc15a3f5fd7f884e4bfa8c011a0ae868df12ae upstream.
For some sev ioctl interfaces, input may be passed that is less than or equal to SEV_FW_BLOB_MAX_SIZE, but larger than the data that PSP firmware returns. In this case, kmalloc will allocate memory that is the size of the input rather than the size of the data. Since PSP firmware doesn't fully overwrite the buffer, the sev ioctl interfaces with the issue may return uninitialized slab memory.
Currently, all of the ioctl interfaces in the ccp driver are safe, but to prevent future problems, change all ioctl interfaces that allocate memory with kmalloc to use kzalloc and memset the data buffer to zero in sev_ioctl_do_platform_status.
Fixes: 38103671aad3 ("crypto: ccp: Use the stack and common buffer for status commands") Fixes: e799035609e15 ("crypto: ccp: Implement SEV_PEK_CSR ioctl command") Fixes: 76a2b524a4b1d ("crypto: ccp: Implement SEV_PDH_CERT_EXPORT ioctl command") Fixes: d6112ea0cb344 ("crypto: ccp - introduce SEV_GET_ID2 command") Cc: stable@vger.kernel.org Reported-by: Andy Nguyen theflow@google.com Suggested-by: David Rientjes rientjes@google.com Suggested-by: Peter Gonda pgonda@google.com Signed-off-by: John Allen john.allen@amd.com Reviewed-by: Peter Gonda pgonda@google.com Acked-by: David Rientjes rientjes@google.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/crypto/ccp/sev-dev.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -577,6 +577,8 @@ static int sev_ioctl_do_platform_status( struct sev_user_data_status data; int ret;
+ memset(&data, 0, sizeof(data)); + ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, &argp->error); if (ret) return ret; @@ -630,7 +632,7 @@ static int sev_ioctl_do_pek_csr(struct s if (input.length > SEV_FW_BLOB_MAX_SIZE) return -EFAULT;
- blob = kmalloc(input.length, GFP_KERNEL); + blob = kzalloc(input.length, GFP_KERNEL); if (!blob) return -ENOMEM;
@@ -854,7 +856,7 @@ static int sev_ioctl_do_get_id2(struct s input_address = (void __user *)input.address;
if (input.address && input.length) { - id_blob = kmalloc(input.length, GFP_KERNEL); + id_blob = kzalloc(input.length, GFP_KERNEL); if (!id_blob) return -ENOMEM;
@@ -973,14 +975,14 @@ static int sev_ioctl_do_pdh_export(struc if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE) return -EFAULT;
- pdh_blob = kmalloc(input.pdh_cert_len, GFP_KERNEL); + pdh_blob = kzalloc(input.pdh_cert_len, GFP_KERNEL); if (!pdh_blob) return -ENOMEM;
data.pdh_cert_address = __psp_pa(pdh_blob); data.pdh_cert_len = input.pdh_cert_len;
- cert_blob = kmalloc(input.cert_chain_len, GFP_KERNEL); + cert_blob = kzalloc(input.cert_chain_len, GFP_KERNEL); if (!cert_blob) { ret = -ENOMEM; goto e_free_pdh;
From: Jiachen Zhang zhangjiachen.jaycee@bytedance.com
commit dd524b7f317de8d31d638cbfdc7be4cf9b770e42 upstream.
Some code paths cannot guarantee the inode have any dentry alias. So WARN_ON() all !dentry may flood the kernel logs.
For example, when an overlayfs inode is watched by inotifywait (1), and someone is trying to read the /proc/$(pidof inotifywait)/fdinfo/INOTIFY_FD, at that time if the dentry has been reclaimed by kernel (such as echo 2 > /proc/sys/vm/drop_caches), there will be a WARN_ON(). The printed call stack would be like:
? show_mark_fhandle+0xf0/0xf0 show_mark_fhandle+0x4a/0xf0 ? show_mark_fhandle+0xf0/0xf0 ? seq_vprintf+0x30/0x50 ? seq_printf+0x53/0x70 ? show_mark_fhandle+0xf0/0xf0 inotify_fdinfo+0x70/0x90 show_fdinfo.isra.4+0x53/0x70 seq_show+0x130/0x170 seq_read+0x153/0x440 vfs_read+0x94/0x150 ksys_read+0x5f/0xe0 do_syscall_64+0x59/0x1e0 entry_SYSCALL_64_after_hwframe+0x44/0xa9
So let's drop WARN_ON() to avoid kernel log flooding.
Reported-by: Hongbo Yin yinhongbo@bytedance.com Signed-off-by: Jiachen Zhang zhangjiachen.jaycee@bytedance.com Signed-off-by: Tianci Zhang zhangtianci.1997@bytedance.com Fixes: 8ed5eec9d6c4 ("ovl: encode pure upper file handles") Cc: stable@vger.kernel.org # v4.16 Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/overlayfs/export.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/overlayfs/export.c +++ b/fs/overlayfs/export.c @@ -259,7 +259,7 @@ static int ovl_encode_fh(struct inode *i return FILEID_INVALID;
dentry = d_find_any_alias(inode); - if (WARN_ON(!dentry)) + if (!dentry) return FILEID_INVALID;
bytes = ovl_dentry_to_fid(ofs, dentry, fid, buflen);
From: Helge Deller deller@gmx.de
commit cab56b51ec0e69128909cef4650e1907248d821b upstream.
Fix the output of /proc/iomem to show the real hardware device name including the pa_pathname, e.g. "Merlin 160 Core Centronics [8:16:0]". Up to now only the pa_pathname ("[8:16.0]") was shown.
Signed-off-by: Helge Deller deller@gmx.de Cc: stable@vger.kernel.org # v4.9+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/kernel/drivers.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
--- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -520,7 +520,6 @@ alloc_pa_dev(unsigned long hpa, struct h dev->id.hversion_rev = iodc_data[1] & 0x0f; dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) | (iodc_data[5] << 8) | iodc_data[6]; - dev->hpa.name = parisc_pathname(dev); dev->hpa.start = hpa; /* This is awkward. The STI spec says that gfx devices may occupy * 32MB or 64MB. Unfortunately, we don't know how to tell whether @@ -534,10 +533,10 @@ alloc_pa_dev(unsigned long hpa, struct h dev->hpa.end = hpa + 0xfff; } dev->hpa.flags = IORESOURCE_MEM; - name = parisc_hardware_description(&dev->id); - if (name) { - strlcpy(dev->name, name, sizeof(dev->name)); - } + dev->hpa.name = dev->name; + name = parisc_hardware_description(&dev->id) ? : "unknown"; + snprintf(dev->name, sizeof(dev->name), "%s [%s]", + name, parisc_pathname(dev));
/* Silently fail things like mouse ports which are subsumed within * the keyboard controller
From: Helge Deller deller@gmx.de
commit 3fbc9a7de0564c55d8a9584c9cd2c9dfe6bd6d43 upstream.
This spinlock was dropped with commit b7795074a046 ("parisc: Optimize per-pagetable spinlocks") in kernel v5.12.
Remove it to silence a sparse warning.
Signed-off-by: Helge Deller deller@gmx.de Reported-by: kernel test robot lkp@intel.com Cc: stable@vger.kernel.org # v5.12+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/kernel/cache.c | 3 --- 1 file changed, 3 deletions(-)
--- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -50,9 +50,6 @@ void flush_instruction_cache_local(void) */ DEFINE_SPINLOCK(pa_tlb_flush_lock);
-/* Swapper page setup lock. */ -DEFINE_SPINLOCK(pa_swapper_pg_lock); - #if defined(CONFIG_64BIT) && defined(CONFIG_SMP) int pa_serialize_tlb_flushes __ro_after_init; #endif
From: William Dean williamsukatube@gmail.com
commit cf59f34d7f978d14d6520fd80a78a5ad5cb8abf8 upstream.
The function ioremap() in lba_driver_probe() can fail, so its return value should be checked.
Fixes: 4bdc0d676a643 ("remove ioremap_nocache and devm_ioremap_nocache") Reported-by: Hacash Robot hacashRobot@santino.com Signed-off-by: William Dean williamsukatube@gmail.com Signed-off-by: Helge Deller deller@gmx.de Cc: stable@vger.kernel.org # v5.6+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/parisc/lba_pci.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -1476,9 +1476,13 @@ lba_driver_probe(struct parisc_device *d u32 func_class; void *tmp_obj; char *version; - void __iomem *addr = ioremap(dev->hpa.start, 4096); + void __iomem *addr; int max;
+ addr = ioremap(dev->hpa.start, 4096); + if (addr == NULL) + return -ENOMEM; + /* Read HW Rev First */ func_class = READ_REG32(addr + LBA_FCLASS);
From: Helge Deller deller@gmx.de
commit 6431e92fc827bdd2d28f79150d90415ba9ce0d21 upstream.
For all syscalls in 32-bit compat mode on 64-bit kernels the upper 32-bits of the 64-bit registers are zeroed out, so a negative 32-bit signed value will show up as positive 64-bit signed value.
This behaviour breaks the io_pgetevents_time64() syscall which expects signed 64-bit values for the "min_nr" and "nr" parameters. Fix this by switching to the compat_sys_io_pgetevents_time64() syscall, which uses "compat_long_t" types for those parameters.
Cc: stable@vger.kernel.org # v5.1+ Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/kernel/syscalls/syscall.tbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl @@ -413,7 +413,7 @@ 412 32 utimensat_time64 sys_utimensat sys_utimensat 413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 -416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents +416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend 419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive
From: Yipeng Zou zouyipeng@huawei.com
commit 3dbe5829408bc1586f75b4667ef60e5aab0209c7 upstream.
In riscv the process of uprobe going to clear spie before exec the origin insn,and set spie after that.But When access the page which origin insn has been placed a page fault may happen and irq was disabled in arch_uprobe_pre_xol function,It cause a WARN as follows. There is no need to clear/set spie in arch_uprobe_pre/post/abort_xol. We can just remove it.
[ 31.684157] BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:1488 [ 31.684677] in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 76, name: work [ 31.684929] preempt_count: 0, expected: 0 [ 31.685969] CPU: 2 PID: 76 Comm: work Tainted: G [ 31.686542] Hardware name: riscv-virtio,qemu (DT) [ 31.686797] Call Trace: [ 31.687053] [<ffffffff80006442>] dump_backtrace+0x30/0x38 [ 31.687699] [<ffffffff80812118>] show_stack+0x40/0x4c [ 31.688141] [<ffffffff8081817a>] dump_stack_lvl+0x44/0x5c [ 31.688396] [<ffffffff808181aa>] dump_stack+0x18/0x20 [ 31.688653] [<ffffffff8003e454>] __might_resched+0x114/0x122 [ 31.688948] [<ffffffff8003e4b2>] __might_sleep+0x50/0x7a [ 31.689435] [<ffffffff80822676>] down_read+0x30/0x130 [ 31.689728] [<ffffffff8000b650>] do_page_fault+0x166/x446 [ 31.689997] [<ffffffff80003c0c>] ret_from_exception+0x0/0xc
Fixes: 74784081aac8 ("riscv: Add uprobes supported") Signed-off-by: Yipeng Zou zouyipeng@huawei.com Reviewed-by: Guo Ren guoren@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220721065820.245755-1-zouyipeng@huawei.com Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/kernel/probes/uprobes.c | 6 ------ 1 file changed, 6 deletions(-)
--- a/arch/riscv/kernel/probes/uprobes.c +++ b/arch/riscv/kernel/probes/uprobes.c @@ -59,8 +59,6 @@ int arch_uprobe_pre_xol(struct arch_upro
instruction_pointer_set(regs, utask->xol_vaddr);
- regs->status &= ~SR_SPIE; - return 0; }
@@ -72,8 +70,6 @@ int arch_uprobe_post_xol(struct arch_upr
instruction_pointer_set(regs, utask->vaddr + auprobe->insn_size);
- regs->status |= SR_SPIE; - return 0; }
@@ -111,8 +107,6 @@ void arch_uprobe_abort_xol(struct arch_u * address. */ instruction_pointer_set(regs, utask->vaddr); - - regs->status &= ~SR_SPIE; }
bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
From: Chen Lifu chenlifu@huawei.com
commit c08b4848f596fd95543197463b5162bd7bab2442 upstream.
Since commit 5d8544e2d007 ("RISC-V: Generic library routines and assembly") and commit ebcbd75e3962 ("riscv: Fix the bug in memory access fixup code"), if __clear_user and __copy_user return from an fixup branch, CSR_STATUS SR_SUM bit will be set, it is a vulnerability, so that S-mode memory accesses to pages that are accessible by U-mode will success. Disable S-mode access to U-mode memory should clear SR_SUM bit.
Fixes: 5d8544e2d007 ("RISC-V: Generic library routines and assembly") Fixes: ebcbd75e3962 ("riscv: Fix the bug in memory access fixup code") Signed-off-by: Chen Lifu chenlifu@huawei.com Reviewed-by: Ben Dooks ben.dooks@codethink.co.uk Link: https://lore.kernel.org/r/20220615014714.1650349-1-chenlifu@huawei.com Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/lib/uaccess.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/riscv/lib/uaccess.S +++ b/arch/riscv/lib/uaccess.S @@ -175,7 +175,7 @@ ENTRY(__asm_copy_from_user) /* Exception fixup code */ 10: /* Disable access to user memory */ - csrs CSR_STATUS, t6 + csrc CSR_STATUS, t6 mv a0, t5 ret ENDPROC(__asm_copy_to_user) @@ -227,7 +227,7 @@ ENTRY(__clear_user) /* Exception fixup code */ 11: /* Disable access to user memory */ - csrs CSR_STATUS, t6 + csrc CSR_STATUS, t6 mv a0, a1 ret ENDPROC(__clear_user)
From: Conor Dooley conor.dooley@microchip.com
commit b60cf8e59e61133b6c9514ff8d8c8d7049d040ef upstream.
Fix device tree schema validation error messages for the SiFive Unmatched: ' cache-sets:0:0: 1024 was expected'.
The existing bindings allow for just 1024 cache-sets but the fu740 on Unmatched the has 2048 cache-sets. The ISA itself permits any arbitrary power of two, however this is not supported by dt-schema. The RTL for the IP, to which the number of cache-sets is a tunable parameter, has been released publicly so speculatively adding a small number of "reasonable" values seems unwise also.
Instead, as the binding only supports two distinct controllers: add 2048 and explicitly lock it to the fu740's l2 cache while limiting 1024 to the l2 cache on the fu540.
Fixes: af951c3a113b ("dt-bindings: riscv: Update l2 cache DT documentation to add support for SiFive FU740") Reported-by: Atul Khare atulkhare@rivosinc.com Signed-off-by: Conor Dooley conor.dooley@microchip.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220803185359.942928-1-mail@conchuod.ie Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml +++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml @@ -46,7 +46,7 @@ properties: const: 2
cache-sets: - const: 1024 + enum: [1024, 2048]
cache-size: const: 2097152 @@ -84,6 +84,8 @@ then: description: | Must contain entries for DirError, DataError and DataFail signals. maxItems: 3 + cache-sets: + const: 1024
else: properties: @@ -91,6 +93,8 @@ else: description: | Must contain entries for DirError, DataError, DataFail, DirFail signals. minItems: 4 + cache-sets: + const: 2048
additionalProperties: false
From: Mark Kettenis kettenis@openbsd.org
commit a208acf0eac857dc8cdaddd63a4e18ed03f91786 upstream.
The PLIC integrated on the Vic_U7_Core integrated on the StarFive JH7100 SoC actually supports 133 external interrupts. 127 of these are exposed to the outside world; the remainder are used by other devices that are part of the core-complex such as the L2 cache controller. But all 133 interrupts are external interrupts as far as the PLIC is concerned. Fix the property so that the driver can manage these additional interrupts, which is important since the interrupts for the L2 cache controller are enabled by default.
Fixes: ec85362fb121 ("RISC-V: Add initial StarFive JH7100 device tree") Signed-off-by: Mark Kettenis kettenis@openbsd.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220707185529.19509-1-kettenis@openbsd.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/boot/dts/starfive/jh7100.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi @@ -118,7 +118,7 @@ interrupt-controller; #address-cells = <0>; #interrupt-cells = <1>; - riscv,ndev = <127>; + riscv,ndev = <133>; };
clkgen: clock-controller@11800000 {
From: Ben Dooks ben.dooks@sifive.com
commit e4aa991c05aedc3ead92d1352af86db74090dc3c upstream.
Running sparse shows cpu_ops_spinwait.c is missing two definitions found in head.h, so include it to stop the following warnings:
arch/riscv/kernel/cpu_ops_spinwait.c:15:6: warning: symbol '__cpu_spinwait_stack_pointer' was not declared. Should it be static? arch/riscv/kernel/cpu_ops_spinwait.c:16:6: warning: symbol '__cpu_spinwait_task_pointer' was not declared. Should it be static?
Signed-off-by: Ben Dooks ben.dooks@sifive.com Link: https://lore.kernel.org/r/20220713215306.94675-1-ben.dooks@sifive.com Fixes: c78f94f35cf6 ("RISC-V: Use __cpu_up_stack/task_pointer only for spinwait method") Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/kernel/cpu_ops_spinwait.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/riscv/kernel/cpu_ops_spinwait.c +++ b/arch/riscv/kernel/cpu_ops_spinwait.c @@ -11,6 +11,8 @@ #include <asm/sbi.h> #include <asm/smp.h>
+#include "head.h" + const struct cpu_operations cpu_ops_spinwait; void *__cpu_spinwait_stack_pointer[NR_CPUS] __section(".data"); void *__cpu_spinwait_task_pointer[NR_CPUS] __section(".data");
From: Ben Dooks ben.dooks@sifive.com
commit da6d2128e56a50a0d497c8e41ca1d33d88bcc0aa upstream.
The cpu_ops_spinwait is used in a couple of places in arch/riscv and is causing a sparse warning due to no declaration. Add this to <asm/cpu_ops.h> with the others to fix the following:
arch/riscv/kernel/cpu_ops_spinwait.c:16:29: warning: symbol 'cpu_ops_spinwait' was not declared. Should it be static?
Signed-off-by: Ben Dooks ben.dooks@sifive.com Link: https://lore.kernel.org/r/20220714071811.187491-1-ben.dooks@sifive.com [Palmer: Drop the extern from cpu_ops.c] Fixes: 2ffc48fc7071 ("RISC-V: Move spinwait booting method to its own config") Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/include/asm/cpu_ops.h | 1 + arch/riscv/kernel/cpu_ops.c | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-)
--- a/arch/riscv/include/asm/cpu_ops.h +++ b/arch/riscv/include/asm/cpu_ops.h @@ -38,6 +38,7 @@ struct cpu_operations { #endif };
+extern const struct cpu_operations cpu_ops_spinwait; extern const struct cpu_operations *cpu_ops[NR_CPUS]; void __init cpu_set_ops(int cpu);
--- a/arch/riscv/kernel/cpu_ops.c +++ b/arch/riscv/kernel/cpu_ops.c @@ -15,9 +15,7 @@ const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init;
extern const struct cpu_operations cpu_ops_sbi; -#ifdef CONFIG_RISCV_BOOT_SPINWAIT -extern const struct cpu_operations cpu_ops_spinwait; -#else +#ifndef CONFIG_RISCV_BOOT_SPINWAIT const struct cpu_operations cpu_ops_spinwait = { .name = "", .cpu_prepare = NULL,
From: Xianting Tian xianting.tian@linux.alibaba.com
commit 357628e68f5c08ad578a718dc62a0031e06dbe91 upstream.
Use __smp_processor_id() to avoid check the preemption context when CONFIG_DEBUG_PREEMPT enabled, as we will enter crash kernel and no return.
Without the patch, [ 103.781044] sysrq: Trigger a crash [ 103.784625] Kernel panic - not syncing: sysrq triggered crash [ 103.837634] CPU1: off [ 103.889668] CPU2: off [ 103.933479] CPU3: off [ 103.939424] Starting crashdump kernel... [ 103.943442] BUG: using smp_processor_id() in preemptible [00000000] code: sh/346 [ 103.950884] caller is debug_smp_processor_id+0x1c/0x26 [ 103.956051] CPU: 0 PID: 346 Comm: sh Kdump: loaded Not tainted 5.10.113-00002-gce03f03bf4ec-dirty #149 [ 103.965355] Call Trace: [ 103.967805] [<ffffffe00020372a>] walk_stackframe+0x0/0xa2 [ 103.973206] [<ffffffe000bcf1f4>] show_stack+0x32/0x3e [ 103.978258] [<ffffffe000bd382a>] dump_stack_lvl+0x72/0x8e [ 103.983655] [<ffffffe000bd385a>] dump_stack+0x14/0x1c [ 103.988705] [<ffffffe000bdc8fe>] check_preemption_disabled+0x9e/0xaa [ 103.995057] [<ffffffe000bdc926>] debug_smp_processor_id+0x1c/0x26 [ 104.001150] [<ffffffe000206c64>] machine_kexec+0x22/0xd0 [ 104.006463] [<ffffffe000291a7e>] __crash_kexec+0x6a/0xa4 [ 104.011774] [<ffffffe000bcf3fa>] panic+0xfc/0x2b0 [ 104.016480] [<ffffffe000656ca4>] sysrq_reset_seq_param_set+0x0/0x70 [ 104.022745] [<ffffffe000657310>] __handle_sysrq+0x8c/0x154 [ 104.028229] [<ffffffe0006577e8>] write_sysrq_trigger+0x5a/0x6a [ 104.034061] [<ffffffe0003d90e0>] proc_reg_write+0x58/0xd4 [ 104.039459] [<ffffffe00036cff4>] vfs_write+0x7e/0x254 [ 104.044509] [<ffffffe00036d2f6>] ksys_write+0x58/0xbe [ 104.049558] [<ffffffe00036d36a>] sys_write+0xe/0x16 [ 104.054434] [<ffffffe000201b9a>] ret_from_syscall+0x0/0x2 [ 104.067863] Will call new kernel at ecc00000 from hart id 0 [ 104.074939] FDT image at fc5ee000 [ 104.079523] Bye...
With the patch we can got clear output, [ 67.740553] sysrq: Trigger a crash [ 67.744166] Kernel panic - not syncing: sysrq triggered crash [ 67.809123] CPU1: off [ 67.865210] CPU2: off [ 67.909075] CPU3: off [ 67.919123] Starting crashdump kernel... [ 67.924900] Will call new kernel at ecc00000 from hart id 0 [ 67.932045] FDT image at fc5ee000 [ 67.935560] Bye...
Fixes: 0e105f1d0037 ("riscv: use hart id instead of cpu id on machine_kexec") Reviewed-by: Guo Ren guoren@kernel.org Reviewed-by: Heiko Stuebner heiko@sntech.de Reviewed-by: Atish Patra atishp@rivosinc.com Signed-off-by: Xianting Tian xianting.tian@linux.alibaba.com Link: https://lore.kernel.org/r/20220811074150.3020189-2-xianting.tian@linux.aliba... Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/kernel/machine_kexec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/riscv/kernel/machine_kexec.c +++ b/arch/riscv/kernel/machine_kexec.c @@ -171,7 +171,7 @@ machine_kexec(struct kimage *image) struct kimage_arch *internal = &image->arch; unsigned long jump_addr = (unsigned long) image->start; unsigned long first_ind_entry = (unsigned long) &image->head; - unsigned long this_cpu_id = smp_processor_id(); + unsigned long this_cpu_id = __smp_processor_id(); unsigned long this_hart_id = cpuid_to_hartid_map(this_cpu_id); unsigned long fdt_addr = internal->fdt_addr; void *control_code_buffer = page_address(image->control_code_page);
From: Xianting Tian xianting.tian@linux.alibaba.com
commit 59c026c359c30f116fef6ee958e24d04983efbb0 upstream.
When use 'echo c > /proc/sysrq-trigger' to trigger kdump, riscv_crash_save_regs() will be called to save regs for vmcore, we found "epc" value 00ffffffa5537400 is not a valid kernel virtual address, but is a user virtual address. Other regs(eg, ra, sp, gp...) are correct kernel virtual address. Actually 0x00ffffffb0dd9400 is the user mode PC of 'PID: 113 Comm: sh', which is saved in the task's stack.
[ 21.201701] CPU: 0 PID: 113 Comm: sh Kdump: loaded Not tainted 5.18.9 #45 [ 21.201979] Hardware name: riscv-virtio,qemu (DT) [ 21.202160] epc : 00ffffffa5537400 ra : ffffffff80088640 sp : ff20000010333b90 [ 21.202435] gp : ffffffff810dde38 tp : ff6000000226c200 t0 : ffffffff8032be7c [ 21.202707] t1 : 0720072007200720 t2 : 30203a7375746174 s0 : ff20000010333cf0 [ 21.202973] s1 : 0000000000000000 a0 : ff20000010333b98 a1 : 0000000000000001 [ 21.203243] a2 : 0000000000000010 a3 : 0000000000000000 a4 : 28c8f0aeffea4e00 [ 21.203519] a5 : 28c8f0aeffea4e00 a6 : 0000000000000009 a7 : ffffffff8035c9b8 [ 21.203794] s2 : ffffffff810df0a8 s3 : ffffffff810df718 s4 : ff20000010333b98 [ 21.204062] s5 : 0000000000000000 s6 : 0000000000000007 s7 : ffffffff80c4a468 [ 21.204331] s8 : 00ffffffef451410 s9 : 0000000000000007 s10: 00aaaaaac0510700 [ 21.204606] s11: 0000000000000001 t3 : ff60000001218f00 t4 : ff60000001218f00 [ 21.204876] t5 : ff60000001218000 t6 : ff200000103338b8 [ 21.205079] status: 0000000200000020 badaddr: 0000000000000000 cause: 0000000000000008
With the incorrect PC, the backtrace showed by crash tool as below, the first stack frame is abnormal,
crash> bt PID: 113 TASK: ff60000002269600 CPU: 0 COMMAND: "sh" #0 [ff2000001039bb90] __efistub_.Ldebug_info0 at 00ffffffa5537400 <-- Abnormal #1 [ff2000001039bcf0] panic at ffffffff806578ba #2 [ff2000001039bd50] sysrq_reset_seq_param_set at ffffffff8038c030 #3 [ff2000001039bda0] __handle_sysrq at ffffffff8038c5f8 #4 [ff2000001039be00] write_sysrq_trigger at ffffffff8038cad8 #5 [ff2000001039be20] proc_reg_write at ffffffff801b7edc #6 [ff2000001039be40] vfs_write at ffffffff80152ba6 #7 [ff2000001039be80] ksys_write at ffffffff80152ece #8 [ff2000001039bed0] sys_write at ffffffff80152f46
With the patch, we can get current kernel mode PC, the output as below,
[ 17.607658] CPU: 0 PID: 113 Comm: sh Kdump: loaded Not tainted 5.18.9 #42 [ 17.607937] Hardware name: riscv-virtio,qemu (DT) [ 17.608150] epc : ffffffff800078f8 ra : ffffffff8008862c sp : ff20000010333b90 [ 17.608441] gp : ffffffff810dde38 tp : ff6000000226c200 t0 : ffffffff8032be68 [ 17.608741] t1 : 0720072007200720 t2 : 666666666666663c s0 : ff20000010333cf0 [ 17.609025] s1 : 0000000000000000 a0 : ff20000010333b98 a1 : 0000000000000001 [ 17.609320] a2 : 0000000000000010 a3 : 0000000000000000 a4 : 0000000000000000 [ 17.609601] a5 : ff60000001c78000 a6 : 000000000000003c a7 : ffffffff8035c9a4 [ 17.609894] s2 : ffffffff810df0a8 s3 : ffffffff810df718 s4 : ff20000010333b98 [ 17.610186] s5 : 0000000000000000 s6 : 0000000000000007 s7 : ffffffff80c4a468 [ 17.610469] s8 : 00ffffffca281410 s9 : 0000000000000007 s10: 00aaaaaab5bb6700 [ 17.610755] s11: 0000000000000001 t3 : ff60000001218f00 t4 : ff60000001218f00 [ 17.611041] t5 : ff60000001218000 t6 : ff20000010333988 [ 17.611255] status: 0000000200000020 badaddr: 0000000000000000 cause: 0000000000000008
With the correct PC, the backtrace showed by crash tool as below,
crash> bt PID: 113 TASK: ff6000000226c200 CPU: 0 COMMAND: "sh" #0 [ff20000010333b90] riscv_crash_save_regs at ffffffff800078f8 <--- Normal #1 [ff20000010333cf0] panic at ffffffff806578c6 #2 [ff20000010333d50] sysrq_reset_seq_param_set at ffffffff8038c03c #3 [ff20000010333da0] __handle_sysrq at ffffffff8038c604 #4 [ff20000010333e00] write_sysrq_trigger at ffffffff8038cae4 #5 [ff20000010333e20] proc_reg_write at ffffffff801b7ee8 #6 [ff20000010333e40] vfs_write at ffffffff80152bb2 #7 [ff20000010333e80] ksys_write at ffffffff80152eda #8 [ff20000010333ed0] sys_write at ffffffff80152f52
Fixes: e53d28180d4d ("RISC-V: Add kdump support") Co-developed-by: Guo Ren guoren@kernel.org Signed-off-by: Xianting Tian xianting.tian@linux.alibaba.com Link: https://lore.kernel.org/r/20220811074150.3020189-3-xianting.tian@linux.aliba... Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/kernel/crash_save_regs.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/riscv/kernel/crash_save_regs.S +++ b/arch/riscv/kernel/crash_save_regs.S @@ -44,7 +44,7 @@ SYM_CODE_START(riscv_crash_save_regs) REG_S t6, PT_T6(a0) /* x31 */
csrr t1, CSR_STATUS - csrr t2, CSR_EPC + auipc t2, 0x0 csrr t3, CSR_TVAL csrr t4, CSR_CAUSE
From: Xianting Tian xianting.tian@linux.alibaba.com
commit ad943893d5f1d0aeea892bf7b781cf8062b36d58 upstream.
Current task of executing crash kexec will be schedule out when panic is triggered by RCU Stall, as it needs to wait rcu completion. It lead to inability to enter the crash system.
The implementation of machine_crash_shutdown() is non-standard for RISC-V according to other Arch's implementation(eg, x86, arm64), we need to send IPI to stop secondary harts.
[224521.877268] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks: [224521.883471] rcu: 0-...0: (3 GPs behind) idle=cfa/0/0x1 softirq=3968793/3968793 fqs=2495 [224521.891742] (detected by 2, t=5255 jiffies, g=60855593, q=328) [224521.897754] Task dump for CPU 0: [224521.901074] task:swapper/0 state:R running task stack: 0 pid: 0 ppid: 0 flags:0x00000008 [224521.911090] Call Trace: [224521.913638] [<ffffffe000c432de>] __schedule+0x208/0x5ea [224521.918957] Kernel panic - not syncing: RCU Stall [224521.923773] bad: scheduling from the idle thread! [224521.928571] CPU: 2 PID: 0 Comm: swapper/2 Kdump: loaded Tainted: G O 5.10.113-yocto-standard #1 [224521.938658] Call Trace: [224521.941200] [<ffffffe00020395c>] walk_stackframe+0x0/0xaa [224521.946689] [<ffffffe000c34f8e>] show_stack+0x32/0x3e [224521.951830] [<ffffffe000c39020>] dump_stack_lvl+0x7e/0xa2 [224521.957317] [<ffffffe000c39058>] dump_stack+0x14/0x1c [224521.962459] [<ffffffe000243884>] dequeue_task_idle+0x2c/0x40 [224521.968207] [<ffffffe000c434f4>] __schedule+0x41e/0x5ea [224521.973520] [<ffffffe000c43826>] schedule+0x34/0xe4 [224521.978487] [<ffffffe000c46cae>] schedule_timeout+0xc6/0x170 [224521.984234] [<ffffffe000c4491e>] wait_for_completion+0x98/0xf2 [224521.990157] [<ffffffe00026d9e2>] __wait_rcu_gp+0x148/0x14a [224521.995733] [<ffffffe0002761c4>] synchronize_rcu+0x5c/0x66 [224522.001307] [<ffffffe00026f1a6>] rcu_sync_enter+0x54/0xe6 [224522.006795] [<ffffffe00025a436>] percpu_down_write+0x32/0x11c [224522.012629] [<ffffffe000c4266a>] _cpu_down+0x92/0x21a [224522.017771] [<ffffffe000219a0a>] smp_shutdown_nonboot_cpus+0x90/0x118 [224522.024299] [<ffffffe00020701e>] machine_crash_shutdown+0x30/0x4a [224522.030483] [<ffffffe00029a3f8>] __crash_kexec+0x62/0xa6 [224522.035884] [<ffffffe000c3515e>] panic+0xfa/0x2b6 [224522.040678] [<ffffffe0002772be>] rcu_sched_clock_irq+0xc26/0xcb8 [224522.046774] [<ffffffe00027fc7a>] update_process_times+0x62/0x8a [224522.052785] [<ffffffe00028d522>] tick_sched_timer+0x9e/0x102 [224522.058533] [<ffffffe000280c3a>] __hrtimer_run_queues+0x16a/0x318 [224522.064716] [<ffffffe0002812ec>] hrtimer_interrupt+0xd4/0x228 [224522.070551] [<ffffffe0009a69b6>] riscv_timer_interrupt+0x3c/0x48 [224522.076646] [<ffffffe000268f8c>] handle_percpu_devid_irq+0xb0/0x24c [224522.083004] [<ffffffe00026428e>] __handle_domain_irq+0xa8/0x122 [224522.089014] [<ffffffe00062f954>] riscv_intc_irq+0x38/0x60 [224522.094501] [<ffffffe000201bd4>] ret_from_exception+0x0/0xc [224522.100161] [<ffffffe000c42146>] rcu_eqs_enter.constprop.0+0x8c/0xb8
With the patch, it can enter crash system when RCU Stall occur.
Fixes: e53d28180d4d ("RISC-V: Add kdump support") Signed-off-by: Xianting Tian xianting.tian@linux.alibaba.com Link: https://lore.kernel.org/r/20220811074150.3020189-4-xianting.tian@linux.aliba... Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/kernel/machine_kexec.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-)
--- a/arch/riscv/kernel/machine_kexec.c +++ b/arch/riscv/kernel/machine_kexec.c @@ -138,19 +138,37 @@ void machine_shutdown(void) #endif }
+/* Override the weak function in kernel/panic.c */ +void crash_smp_send_stop(void) +{ + static int cpus_stopped; + + /* + * This function can be called twice in panic path, but obviously + * we execute this only once. + */ + if (cpus_stopped) + return; + + smp_send_stop(); + cpus_stopped = 1; +} + /* * machine_crash_shutdown - Prepare to kexec after a kernel crash * * This function is called by crash_kexec just before machine_kexec - * below and its goal is similar to machine_shutdown, but in case of - * a kernel crash. Since we don't handle such cases yet, this function - * is empty. + * and its goal is to shutdown non-crashing cpus and save registers. */ void machine_crash_shutdown(struct pt_regs *regs) { + local_irq_disable(); + + /* shutdown non-crashing cpus */ + crash_smp_send_stop(); + crash_save_cpu(regs, smp_processor_id()); - machine_shutdown(); pr_info("Starting crashdump kernel...\n"); }
From: Xianting Tian xianting.tian@linux.alibaba.com
commit f9293ad46d8ba9909187a37b7215324420ad4596 upstream.
Modules always live before the kernel, MODULES_END is fixed but MODULES_VADDR isn't fixed, it depends on the kernel size. Let's add it to virtual kernel memory layout dump.
As MODULES is only defined for CONFIG_64BIT, so we dump it when CONFIG_64BIT=y.
eg, MODULES_VADDR - MODULES_END 0xffffffff01133000 - 0xffffffff80000000
Reviewed-by: Guo Ren guoren@kernel.org Reviewed-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Xianting Tian xianting.tian@linux.alibaba.com Link: https://lore.kernel.org/r/20220811074150.3020189-5-xianting.tian@linux.aliba... Cc: stable@vger.kernel.org Fixes: 2bfc6cd81bd1 ("riscv: Move kernel mapping outside of linear mapping") Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/mm/init.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -135,6 +135,10 @@ static void __init print_vm_layout(void) (unsigned long)VMEMMAP_END); print_ml("vmalloc", (unsigned long)VMALLOC_START, (unsigned long)VMALLOC_END); +#ifdef CONFIG_64BIT + print_ml("modules", (unsigned long)MODULES_VADDR, + (unsigned long)MODULES_END); +#endif print_ml("lowmem", (unsigned long)PAGE_OFFSET, (unsigned long)high_memory); if (IS_ENABLED(CONFIG_64BIT)) {
From: Atish Patra atishp@rivosinc.com
commit acc1b919f47926b089be21b8aaa29ec91fef0aa2 upstream.
Pass the upper half of the initial value of the counter correctly for RV32.
Fixes: 4905ec2fb7e6 ("RISC-V: Add sscofpmf extension support") Signed-off-by: Atish Patra atishp@rivosinc.com Reviewed-by: Guo Ren guoren@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220711174632.4186047-2-atishp@rivosinc.com Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/perf/riscv_pmu_sbi.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -525,8 +525,13 @@ static inline void pmu_sbi_start_overflo hwc = &event->hw; max_period = riscv_pmu_ctr_get_width_mask(event); init_val = local64_read(&hwc->prev_count) & max_period; +#if defined(CONFIG_32BIT) + sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, idx, 1, + flag, init_val, init_val >> 32, 0); +#else sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, idx, 1, flag, init_val, 0, 0); +#endif } ctr_ovf_mask = ctr_ovf_mask >> 1; idx++;
From: Atish Patra atishp@rivosinc.com
commit 0209b5830bea42dd3ce33ab0397231e67ec3b751 upstream.
Some of the SBI PMU calls does not pass 64bit arguments correctly and not under RV32 compile time flags. Currently, this doesn't create any incorrect results as RV64 ignores any value in the additional register and qemu doesn't support raw events.
Fix those SBI calls in order to set correct values for RV32.
Fixes: e9991434596f ("RISC-V: Add perf platform driver based on SBI PMU extension") Signed-off-by: Atish Patra atishp@rivosinc.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220711174632.4186047-4-atishp@rivosinc.com Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/perf/riscv_pmu_sbi.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
--- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -274,8 +274,13 @@ static int pmu_sbi_ctr_get_idx(struct pe cflags |= SBI_PMU_CFG_FLAG_SET_UINH;
/* retrieve the available counter index */ +#if defined(CONFIG_32BIT) + ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, cmask, + cflags, hwc->event_base, hwc->config, hwc->config >> 32); +#else ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, cmask, cflags, hwc->event_base, hwc->config, 0); +#endif if (ret.error) { pr_debug("Not able to find a counter for event %lx config %llx\n", hwc->event_base, hwc->config); @@ -417,8 +422,13 @@ static void pmu_sbi_ctr_start(struct per struct hw_perf_event *hwc = &event->hw; unsigned long flag = SBI_PMU_START_FLAG_SET_INIT_VALUE;
+#if defined(CONFIG_32BIT) ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, hwc->idx, 1, flag, ival, ival >> 32, 0); +#else + ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, hwc->idx, + 1, flag, ival, 0, 0); +#endif if (ret.error && (ret.error != SBI_ERR_ALREADY_STARTED)) pr_err("Starting counter idx %d failed with error %d\n", hwc->idx, sbi_err_map_linux_errno(ret.error));
From: Atish Patra atishp@rivosinc.com
commit 133a6d1fe7d7ad8393af025c4dde379c0616661f upstream.
Currently, riscv_pmu_event_set_period updates the userpage mapping. However, the caller of riscv_pmu_event_set_period should update the userpage mapping because the counter can not be updated/started from set_period function in counter overflow path.
Invoke the perf_event_update_userpage at the caller so that it doesn't get invoked twice during counter start path.
Fixes: f5bfa23f576f ("RISC-V: Add a perf core library for pmu drivers") Reviewed-by: Anup Patel anup@brainfault.org Signed-off-by: Atish Patra atishp@rivosinc.com Reviewed-by: Guo Ren guoren@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220711174632.4186047-3-atishp@rivosinc.com Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/perf/riscv_pmu.c | 1 - drivers/perf/riscv_pmu_sbi.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/perf/riscv_pmu.c +++ b/drivers/perf/riscv_pmu.c @@ -170,7 +170,6 @@ int riscv_pmu_event_set_period(struct pe left = (max_period >> 1);
local64_set(&hwc->prev_count, (u64)-left); - perf_event_update_userpage(event);
return overflow; } --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -542,6 +542,7 @@ static inline void pmu_sbi_start_overflo sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, idx, 1, flag, init_val, 0, 0); #endif + perf_event_update_userpage(event); } ctr_ovf_mask = ctr_ovf_mask >> 1; idx++;
From: Jason A. Donenfeld Jason@zx2c4.com
commit 9019b4f6d9bd88524ecd95420cf9cd4aaed7a125 upstream.
When the CONFIG_PORTABLE/CONFIG_NONPORTABLE switches were added, various configs were updated, but the wireguard config was forgotten about. This leads to unbootable test kernels, causing CI fails. Add CONFIG_NONPORTABLE=y to the wireguard test suite configuration for riscv32.
Fixes: 44c1e84a38a0 ("RISC-V: Add CONFIG_{NON,}PORTABLE") Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220809145757.83673-1-Jason@zx2c4.com Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/wireguard/qemu/arch/riscv32.config | 1 + 1 file changed, 1 insertion(+)
--- a/tools/testing/selftests/wireguard/qemu/arch/riscv32.config +++ b/tools/testing/selftests/wireguard/qemu/arch/riscv32.config @@ -1,3 +1,4 @@ +CONFIG_NONPORTABLE=y CONFIG_ARCH_RV32I=y CONFIG_MMU=y CONFIG_FPU=y
From: Mathew McBride matt@traverse.com.au
commit 71af91565052214ad86f288e0d8ffb165f790995 upstream.
The 12/24hr flag in the RX-8035 can be found in the hour register, instead of the CTRL1 on the RX-8025. This was overlooked when support for the RX-8035 was added, and was causing read errors when the hour register 'overflowed'.
To deal with the relevant register not always being visible in the relevant functions, determine the 12/24 mode at startup and store it in the driver state.
Signed-off-by: Mathew McBride matt@traverse.com.au Fixes: f120e2e33ac8 ("rtc: rx8025: implement RX-8035 support") Cc: stable@vger.kernel.org Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Link: https://lore.kernel.org/r/20220706074236.24011-1-matt@traverse.com.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/rtc/rtc-rx8025.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
--- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -55,6 +55,8 @@ #define RX8025_BIT_CTRL2_XST BIT(5) #define RX8025_BIT_CTRL2_VDET BIT(6)
+#define RX8035_BIT_HOUR_1224 BIT(7) + /* Clock precision adjustment */ #define RX8025_ADJ_RESOLUTION 3050 /* in ppb */ #define RX8025_ADJ_DATA_MAX 62 @@ -78,6 +80,7 @@ struct rx8025_data { struct rtc_device *rtc; enum rx_model model; u8 ctrl1; + int is_24; };
static s32 rx8025_read_reg(const struct i2c_client *client, u8 number) @@ -226,7 +229,7 @@ static int rx8025_get_time(struct device
dt->tm_sec = bcd2bin(date[RX8025_REG_SEC] & 0x7f); dt->tm_min = bcd2bin(date[RX8025_REG_MIN] & 0x7f); - if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) + if (rx8025->is_24) dt->tm_hour = bcd2bin(date[RX8025_REG_HOUR] & 0x3f); else dt->tm_hour = bcd2bin(date[RX8025_REG_HOUR] & 0x1f) % 12 @@ -254,7 +257,7 @@ static int rx8025_set_time(struct device */ date[RX8025_REG_SEC] = bin2bcd(dt->tm_sec); date[RX8025_REG_MIN] = bin2bcd(dt->tm_min); - if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) + if (rx8025->is_24) date[RX8025_REG_HOUR] = bin2bcd(dt->tm_hour); else date[RX8025_REG_HOUR] = (dt->tm_hour >= 12 ? 0x20 : 0) @@ -279,6 +282,7 @@ static int rx8025_init_client(struct i2c struct rx8025_data *rx8025 = i2c_get_clientdata(client); u8 ctrl[2], ctrl2; int need_clear = 0; + int hour_reg; int err;
err = rx8025_read_regs(client, RX8025_REG_CTRL1, 2, ctrl); @@ -303,6 +307,16 @@ static int rx8025_init_client(struct i2c
err = rx8025_write_reg(client, RX8025_REG_CTRL2, ctrl2); } + + if (rx8025->model == model_rx_8035) { + /* In RX-8035, 12/24 flag is in the hour register */ + hour_reg = rx8025_read_reg(client, RX8025_REG_HOUR); + if (hour_reg < 0) + return hour_reg; + rx8025->is_24 = (hour_reg & RX8035_BIT_HOUR_1224); + } else { + rx8025->is_24 = (ctrl[1] & RX8025_BIT_CTRL1_1224); + } out: return err; } @@ -329,7 +343,7 @@ static int rx8025_read_alarm(struct devi /* Hardware alarms precision is 1 minute! */ t->time.tm_sec = 0; t->time.tm_min = bcd2bin(ald[0] & 0x7f); - if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) + if (rx8025->is_24) t->time.tm_hour = bcd2bin(ald[1] & 0x3f); else t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12 @@ -350,7 +364,7 @@ static int rx8025_set_alarm(struct devic int err;
ald[0] = bin2bcd(t->time.tm_min); - if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) + if (rx8025->is_24) ald[1] = bin2bcd(t->time.tm_hour); else ald[1] = (t->time.tm_hour >= 12 ? 0x20 : 0)
From: Dmitry Osipenko dmitry.osipenko@collabora.com
commit 2939deac1fa220bc82b89235f146df1d9b52e876 upstream.
Use ww_acquire_fini() in the error code paths. Otherwise lockdep thinks that lock is held when lock's memory is freed after the drm_gem_lock_reservations() error. The ww_acquire_context needs to be annotated as "released", which fixes the noisy "WARNING: held lock freed!" splat of VirtIO-GPU driver with CONFIG_DEBUG_MUTEXES=y and enabled lockdep.
Cc: stable@vger.kernel.org Fixes: 7edc3e3b975b5 ("drm: Add helpers for locking an array of BO reservations.") Reviewed-by: Thomas Hellström thomas.hellstrom@linux.intel.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Dmitry Osipenko dmitry.osipenko@collabora.com Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20220630200405.1883897-2-dmitr... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -1226,7 +1226,7 @@ retry: ret = dma_resv_lock_slow_interruptible(obj->resv, acquire_ctx); if (ret) { - ww_acquire_done(acquire_ctx); + ww_acquire_fini(acquire_ctx); return ret; } } @@ -1251,7 +1251,7 @@ retry: goto retry; }
- ww_acquire_done(acquire_ctx); + ww_acquire_fini(acquire_ctx); return ret; } }
From: Dmitry Osipenko dmitry.osipenko@collabora.com
commit df4aaf015775221dde8a51ee09edb919981f091e upstream.
The vmapping of dma-buf may succeed, but DRM SHMEM rejects the IOMEM mapping, and thus, drm_gem_shmem_vmap_locked() should unvmap the IOMEM before erroring out.
Cc: stable@vger.kernel.org Fixes: 49a3f51dfeee ("drm/gem: Use struct dma_buf_map in GEM vmap ops and convert GEM backends") Signed-off-by: Dmitry Osipenko dmitry.osipenko@collabora.com Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20220630200058.1883506-2-dmitr... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_gem_shmem_helper.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -302,6 +302,7 @@ static int drm_gem_shmem_vmap_locked(str ret = dma_buf_vmap(obj->import_attach->dmabuf, map); if (!ret) { if (WARN_ON(map->is_iomem)) { + dma_buf_vunmap(obj->import_attach->dmabuf, map); ret = -EIO; goto err_put_pages; }
From: Phil Elwell phil@raspberrypi.org
commit db2b927f8668adf3ac765e0921cd2720f5c04172 upstream.
The dmas property is used to hold the dmaengine channel used for audio output.
Older device trees were missing that property, so if it's not there we disable the audio output entirely.
However, some overlays have set an empty value to that property, mostly to workaround the fact that overlays cannot remove a property. Let's add a test for that case and if it's empty, let's disable it as well.
Cc: stable@vger.kernel.org Signed-off-by: Phil Elwell phil@raspberrypi.org Link: https://lore.kernel.org/r/20220613144800.326124-18-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -2035,12 +2035,12 @@ static int vc4_hdmi_audio_init(struct vc struct device *dev = &vc4_hdmi->pdev->dev; struct platform_device *codec_pdev; const __be32 *addr; - int index; + int index, len; int ret;
- if (!of_find_property(dev->of_node, "dmas", NULL)) { + if (!of_find_property(dev->of_node, "dmas", &len) || !len) { dev_warn(dev, - "'dmas' DT property is missing, no HDMI audio\n"); + "'dmas' DT property is missing or empty, no HDMI audio\n"); return 0; }
From: Paul Cercueil paul@crapouillou.net
commit f0dce5c4fdaf9e98dd2755ffb1363822854b6287 upstream.
Until now, when running at the maximum resolution of 1280x720 at 32bpp on the JZ4770 SoC the output was garbled, the X/Y position of the top-left corner of the framebuffer warping to a random position with the whole image being offset accordingly, every time a new frame was being submitted.
This problem can be eliminated by using a bigger burst size for the DMA.
Set in each soc_info structure the maximum burst size supported by the corresponding SoC, and use it in the driver.
Set the new value using regmap_update_bits() instead of regmap_set_bits(), since we do want to override the old value of the burst size. (Note that regmap_set_bits() wasn't really valid before for the same reason, but it never seemed to be a problem).
Cc: stable@vger.kernel.org Fixes: 90b86fcc47b4 ("DRM: Add KMS driver for the Ingenic JZ47xx SoCs") Signed-off-by: Paul Cercueil paul@crapouillou.net Link: https://patchwork.freedesktop.org/patch/msgid/20220702230727.66704-1-paul@cr... Acked-by: Sam Ravnborg sam@ravnborg.org Tested-by: Christophe Branchereau cbranchereau@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 10 ++++++++-- drivers/gpu/drm/ingenic/ingenic-drm.h | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -69,6 +69,7 @@ struct jz_soc_info { bool map_noncoherent; bool use_extended_hwdesc; bool plane_f0_not_working; + u32 max_burst; unsigned int max_width, max_height; const u32 *formats_f0, *formats_f1; unsigned int num_formats_f0, num_formats_f1; @@ -318,8 +319,9 @@ static void ingenic_drm_crtc_update_timi regmap_write(priv->map, JZ_REG_LCD_REV, mode->htotal << 16); }
- regmap_set_bits(priv->map, JZ_REG_LCD_CTRL, - JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16); + regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, + JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_MASK, + JZ_LCD_CTRL_OFUP | priv->soc_info->max_burst);
/* * IPU restart - specify how much time the LCDC will wait before @@ -1518,6 +1520,7 @@ static const struct jz_soc_info jz4740_s .map_noncoherent = false, .max_width = 800, .max_height = 600, + .max_burst = JZ_LCD_CTRL_BURST_16, .formats_f1 = jz4740_formats, .num_formats_f1 = ARRAY_SIZE(jz4740_formats), /* JZ4740 has only one plane */ @@ -1529,6 +1532,7 @@ static const struct jz_soc_info jz4725b_ .map_noncoherent = false, .max_width = 800, .max_height = 600, + .max_burst = JZ_LCD_CTRL_BURST_16, .formats_f1 = jz4725b_formats_f1, .num_formats_f1 = ARRAY_SIZE(jz4725b_formats_f1), .formats_f0 = jz4725b_formats_f0, @@ -1541,6 +1545,7 @@ static const struct jz_soc_info jz4770_s .map_noncoherent = true, .max_width = 1280, .max_height = 720, + .max_burst = JZ_LCD_CTRL_BURST_64, .formats_f1 = jz4770_formats_f1, .num_formats_f1 = ARRAY_SIZE(jz4770_formats_f1), .formats_f0 = jz4770_formats_f0, @@ -1555,6 +1560,7 @@ static const struct jz_soc_info jz4780_s .plane_f0_not_working = true, /* REVISIT */ .max_width = 4096, .max_height = 2048, + .max_burst = JZ_LCD_CTRL_BURST_64, .formats_f1 = jz4770_formats_f1, .num_formats_f1 = ARRAY_SIZE(jz4770_formats_f1), .formats_f0 = jz4770_formats_f0, --- a/drivers/gpu/drm/ingenic/ingenic-drm.h +++ b/drivers/gpu/drm/ingenic/ingenic-drm.h @@ -106,6 +106,9 @@ #define JZ_LCD_CTRL_BURST_4 (0x0 << 28) #define JZ_LCD_CTRL_BURST_8 (0x1 << 28) #define JZ_LCD_CTRL_BURST_16 (0x2 << 28) +#define JZ_LCD_CTRL_BURST_32 (0x3 << 28) +#define JZ_LCD_CTRL_BURST_64 (0x4 << 28) +#define JZ_LCD_CTRL_BURST_MASK (0x7 << 28) #define JZ_LCD_CTRL_RGB555 BIT(27) #define JZ_LCD_CTRL_OFUP BIT(26) #define JZ_LCD_CTRL_FRC_GRAYSCALE_16 (0x0 << 24)
From: Thomas Zimmermann tzimmermann@suse.de
commit ae25885bdf59fde40726863c57fd20e4a0642183 upstream.
Clip memory range to screen-buffer size to avoid out-of-bounds access in fbdev deferred I/O's damage handling.
Fbdev's deferred I/O can only track pages. From the range of pages, the damage handler computes the clipping rectangle for the display update. If the fbdev screen buffer ends near the beginning of a page, that page could contain more scanlines. The damage handler would then track these non-existing scanlines as dirty and provoke an out-of-bounds access during the screen update. Hence, clip the maximum memory range to the size of the screen buffer.
While at it, rename the variables min/max to min_off/max_off in drm_fb_helper_deferred_io(). This avoids confusion with the macros of the same name.
Reported-by: Nuno Gonçalves nunojpg@gmail.com Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Reviewed-by: Javier Martinez Canillas javierm@redhat.com Tested-by: Nuno Gonçalves nunojpg@gmail.com Fixes: 67b723f5b742 ("drm/fb-helper: Calculate damaged area in separate helper") Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Javier Martinez Canillas javierm@redhat.com Cc: Maarten Lankhorst maarten.lankhorst@linux.intel.com Cc: Maxime Ripard mripard@kernel.org Cc: stable@vger.kernel.org # v5.18+ Link: https://patchwork.freedesktop.org/patch/msgid/20220621104617.8817-1-tzimmerm... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_fb_helper.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-)
--- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -680,7 +680,11 @@ static void drm_fb_helper_damage(struct schedule_work(&helper->damage_work); }
-/* Convert memory region into area of scanlines and pixels per scanline */ +/* + * Convert memory region into area of scanlines and pixels per + * scanline. The parameters off and len must not reach beyond + * the end of the framebuffer. + */ static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off, size_t len, struct drm_rect *clip) { @@ -715,22 +719,29 @@ static void drm_fb_helper_memory_range_t */ void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist) { - unsigned long start, end, min, max; + unsigned long start, end, min_off, max_off; struct fb_deferred_io_pageref *pageref; struct drm_rect damage_area;
- min = ULONG_MAX; - max = 0; + min_off = ULONG_MAX; + max_off = 0; list_for_each_entry(pageref, pagereflist, list) { start = pageref->offset; end = start + PAGE_SIZE; - min = min(min, start); - max = max(max, end); + min_off = min(min_off, start); + max_off = max(max_off, end); } - if (min >= max) + if (min_off >= max_off) return;
- drm_fb_helper_memory_range_to_clip(info, min, max - min, &damage_area); + /* + * As we can only track pages, we might reach beyond the end + * of the screen and account for non-existing scanlines. Hence, + * keep the covered memory area within the screen buffer. + */ + max_off = min(max_off, info->screen_size); + + drm_fb_helper_memory_range_to_clip(info, min_off, max_off - min_off, &damage_area); drm_fb_helper_damage(info, damage_area.x1, damage_area.y1, drm_rect_width(&damage_area), drm_rect_height(&damage_area));
From: Thomas Zimmermann tzimmermann@suse.de
commit 009a3a52791f31c57d755a73f6bc66fbdd8bd76c upstream.
Fix a number of compile errors by including the correct header files. Examples are shown below.
../drivers/gpu/drm/hyperv/hyperv_drm_modeset.c: In function 'hyperv_blit_to_vram_rect': ../drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:25:48: error: invalid use of undefined type 'struct drm_framebuffer' 25 | struct hyperv_drm_device *hv = to_hv(fb->dev); | ^~
../drivers/gpu/drm/hyperv/hyperv_drm_modeset.c: In function 'hyperv_connector_get_modes': ../drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:59:17: error: implicit declaration of function 'drm_add_modes_noedid' [-Werror=implicit-function-declaration] 59 | count = drm_add_modes_noedid(connector, | ^~~~~~~~~~~~~~~~~~~~
../drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:62:9: error: implicit declaration of function 'drm_set_preferred_mode'; did you mean 'drm_mm_reserve_node'? [-Werror=implicit-function-declaration] 62 | drm_set_preferred_mode(connector, hv->preferred_width, | ^~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Fixes: 76c56a5affeb ("drm/hyperv: Add DRM driver for hyperv synthetic video device") Fixes: 720cf96d8fec ("drm: Drop drm_framebuffer.h from drm_crtc.h") Fixes: 255490f9150d ("drm: Drop drm_edid.h from drm_crtc.h") Cc: Deepak Rawat drawat.floss@gmail.com Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Maarten Lankhorst maarten.lankhorst@linux.intel.com Cc: Maxime Ripard mripard@kernel.org Cc: linux-hyperv@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: stable@vger.kernel.org # v5.14+ Acked-by: Maxime Ripard maxime@cerno.tech Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20220622083413.12573-1-tzimmer... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c @@ -7,9 +7,11 @@
#include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_edid.h> #include <drm/drm_fb_helper.h> #include <drm/drm_format_helper.h> #include <drm/drm_fourcc.h> +#include <drm/drm_framebuffer.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_shmem_helper.h>
From: Imre Deak imre.deak@intel.com
commit 7a710a8bc909313951eb9252d8419924c771d7c2 upstream.
The WD22TB4 Thunderbolt dock at least will revert its DP_MAX_LINK_RATE from HBR3 to HBR2 after system suspend/resume if the DP_DP13_DPCD_REV registers are not read subsequently also as required.
Fix this by reading DP_DP13_DPCD_REV registers as well, matching what is done during connector detection. While at it also fix up the same call in drm_dp_mst_dump_topology().
Cc: Lyude Paul lyude@redhat.com Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5292 Signed-off-by: Imre Deak imre.deak@intel.com Reviewed-by: Jani Nikula jani.nikula@intel.com Cc: stable@vger.kernel.org # v5.14+ Reviewed-by: Lyude Paul lyude@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20220614094537.885472-1-imre.d... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -3860,9 +3860,7 @@ int drm_dp_mst_topology_mgr_resume(struc if (!mgr->mst_primary) goto out_fail;
- ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, - DP_RECEIVER_CAP_SIZE); - if (ret != DP_RECEIVER_CAP_SIZE) { + if (drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd) < 0) { drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n"); goto out_fail; } @@ -4911,8 +4909,7 @@ void drm_dp_mst_dump_topology(struct seq u8 buf[DP_PAYLOAD_TABLE_SIZE]; int ret;
- ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, buf, DP_RECEIVER_CAP_SIZE); - if (ret) { + if (drm_dp_read_dpcd_caps(mgr->aux, buf) < 0) { seq_printf(m, "dpcd read failed\n"); goto out; }
From: Timur Tabi ttabi@nvidia.com
commit c441d28945fb113220d48d6c86ebc0b090a2b677 upstream.
This check determines whether a given address is part of image 0 or image 1. Image 1 starts at offset image0_size, so that address should be included.
Fixes: 4d4e9907ff572 ("drm/nouveau/bios: guard against out-of-bounds accesses to image") Cc: stable@vger.kernel.org # v4.8+ Signed-off-by: Timur Tabi ttabi@nvidia.com Reviewed-by: Karol Herbst kherbst@redhat.com Signed-off-by: Lyude Paul lyude@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20220511163716.3520591-1-ttabi... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c @@ -33,7 +33,7 @@ nvbios_addr(struct nvkm_bios *bios, u32 { u32 p = *addr;
- if (*addr > bios->image0_size && bios->imaged_addr) { + if (*addr >= bios->image0_size && bios->imaged_addr) { *addr -= bios->image0_size; *addr += bios->imaged_addr; }
From: Lyude Paul lyude@redhat.com
commit c96cfaf8fc02d4bb70727dfa7ce7841a3cff9be2 upstream.
While trying to fix another issue, it occurred to me that I don't actually think there is any situation where we want pm_runtime_put() in nouveau to be synchronous. In fact, this kind of just seems like it would cause issues where we may unexpectedly block a thread we don't expect to be blocked.
So, let's only use pm_runtime_put_autosuspend().
Changes since v1: * Use pm_runtime_put_autosuspend(), not pm_runtime_put()
Signed-off-by: Lyude Paul lyude@redhat.com Reviewed-by: David Airlie airlied@linux.ie Fixes: 3a6536c51d5d ("drm/nouveau: Intercept ACPI_VIDEO_NOTIFY_PROBE") Cc: Hans de Goede hdegoede@redhat.com Cc: stable@vger.kernel.org # v4.10+ Link: https://patchwork.freedesktop.org/patch/msgid/20220714174234.949259-3-lyude@... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/nouveau/nouveau_display.c | 2 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -515,7 +515,7 @@ nouveau_display_hpd_work(struct work_str
pm_runtime_mark_last_busy(drm->dev->dev); noop: - pm_runtime_put_sync(drm->dev->dev); + pm_runtime_put_autosuspend(dev->dev); }
#ifdef CONFIG_ACPI --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -466,7 +466,7 @@ nouveau_fbcon_set_suspend_work(struct wo if (state == FBINFO_STATE_RUNNING) { nouveau_fbcon_hotplug_resume(drm->fbcon); pm_runtime_mark_last_busy(drm->dev->dev); - pm_runtime_put_sync(drm->dev->dev); + pm_runtime_put_autosuspend(drm->dev->dev); } }
From: Lyude Paul lyude@redhat.com
commit 53c26181950ddc3c8ace3c0939c89e9c4d8deeb9 upstream.
Since this isn't actually a failure.
Signed-off-by: Lyude Paul lyude@redhat.com Reviewed-by: David Airlie airlied@linux.ie Fixes: 79e765ad665d ("drm/nouveau/drm/nouveau: Prevent handling ACPI HPD events too early") Cc: stable@vger.kernel.org # v4.19+ Link: https://patchwork.freedesktop.org/patch/msgid/20220714174234.949259-2-lyude@... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/nouveau/nouveau_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -537,7 +537,7 @@ nouveau_display_acpi_ntfy(struct notifie * it's own hotplug events. */ pm_runtime_put_autosuspend(drm->dev->dev); - } else if (ret == 0) { + } else if (ret == 0 || ret == -EINPROGRESS) { /* We've started resuming the GPU already, so * it will handle scheduling a full reprobe * itself
From: Lyude Paul lyude@redhat.com
commit ca0367ca5d9216644b41f86348d6661f8d9e32d8 upstream.
It looks like that when we moved nouveau over to using drm_dp_aux_init() and registering it's aux bus during late connector registration, we totally forgot to fix the failure codepath in nouveau_connector_create() - as it still seems to assume that drm_dp_aux_init() can fail (it can't).
So, let's fix that and also add a missing check to ensure that we've properly allocated nv_connector->aux.name while we're at it.
Signed-off-by: Lyude Paul lyude@redhat.com Reviewed-by: David Airlie airlied@linux.ie Fixes: fd43ad9d47e7 ("drm/nouveau/kms/nv50-: Move AUX adapter reg to connector late register/early unregister") Cc: stable@vger.kernel.org # v5.14+ Link: https://patchwork.freedesktop.org/patch/msgid/20220526204313.656473-1-lyude@... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/nouveau/nouveau_connector.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -1361,13 +1361,11 @@ nouveau_connector_create(struct drm_devi snprintf(aux_name, sizeof(aux_name), "sor-%04x-%04x", dcbe->hasht, dcbe->hashm); nv_connector->aux.name = kstrdup(aux_name, GFP_KERNEL); - drm_dp_aux_init(&nv_connector->aux); - if (ret) { - NV_ERROR(drm, "Failed to init AUX adapter for sor-%04x-%04x: %d\n", - dcbe->hasht, dcbe->hashm, ret); + if (!nv_connector->aux.name) { kfree(nv_connector); - return ERR_PTR(ret); + return ERR_PTR(-ENOMEM); } + drm_dp_aux_init(&nv_connector->aux); fallthrough; default: funcs = &nouveau_connector_funcs;
From: Dmitry Osipenko dmitry.osipenko@collabora.com
commit c7860cbee9989882d2908682526a5ef617523cfe upstream.
The code assumes that Tegra GEM is permanently vmapped, which is not true for the scattered buffers. After converting Tegra video decoder driver to V4L API, we're now getting a BUG_ON from dma-buf core on playing video using libvdpau-tegra on T30+ because tegra_gem_prime_vmap() sets vaddr to NULL. Older pre-V4L video decoder driver wasn't vmapping dma-bufs. Fix it by actually vmapping the exported GEMs.
Cc: stable@vger.kernel.org Signed-off-by: Dmitry Osipenko dmitry.osipenko@collabora.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/tegra/gem.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -704,14 +704,23 @@ static int tegra_gem_prime_vmap(struct d { struct drm_gem_object *gem = buf->priv; struct tegra_bo *bo = to_tegra_bo(gem); + void *vaddr;
- iosys_map_set_vaddr(map, bo->vaddr); + vaddr = tegra_bo_mmap(&bo->base); + if (IS_ERR(vaddr)) + return PTR_ERR(vaddr); + + iosys_map_set_vaddr(map, vaddr);
return 0; }
static void tegra_gem_prime_vunmap(struct dma_buf *buf, struct iosys_map *map) { + struct drm_gem_object *gem = buf->priv; + struct tegra_bo *bo = to_tegra_bo(gem); + + tegra_bo_munmap(&bo->base, map->vaddr); }
static const struct dma_buf_ops tegra_gem_prime_dmabuf_ops = {
From: Leo Li sunpeng.li@amd.com
commit f5ba14043621f4afdf3ad5f92ee2d8dbebbe4340 upstream.
When pinning a buffer, we should check to see if there are any additional restrictions imposed by bo->preferred_domains. This will prevent the BO from being moved to an invalid domain when pinning.
For example, this can happen if the user requests to create a BO in GTT domain for display scanout. amdgpu_dm will allow pinning to either VRAM or GTT domains, since DCN can scanout from either or. However, in amdgpu_bo_pin_restricted(), pinning to VRAM is preferred if there is adequate carveout. This can lead to pinning to VRAM despite the user requesting GTT placement for the BO.
v2: Allow the kernel to override the domain, which can happen when exporting a BO to a V4L camera (for example).
Signed-off-by: Leo Li sunpeng.li@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Reviewed-by: Christian König christian.koenig@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_object.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -882,6 +882,10 @@ int amdgpu_bo_pin_restricted(struct amdg if (WARN_ON_ONCE(min_offset > max_offset)) return -EINVAL;
+ /* Check domain to be pinned to against preferred domains */ + if (bo->preferred_domains & domain) + domain = bo->preferred_domains & domain; + /* A shared bo cannot be migrated to VRAM */ if (bo->tbo.base.import_attach) { if (domain & AMDGPU_GEM_DOMAIN_GTT)
From: Tadeusz Struk tadeusz.struk@linaro.org
commit 4c46091ee985ae84c60c5e95055d779fcd291d87 upstream.
Syzbot found a Use After Free bug in compute_effective_progs(). The reproducer creates a number of BPF links, and causes a fault injected alloc to fail, while calling bpf_link_detach on them. Link detach triggers the link to be freed by bpf_link_free(), which calls __cgroup_bpf_detach() and update_effective_progs(). If the memory allocation in this function fails, the function restores the pointer to the bpf_cgroup_link on the cgroup list, but the memory gets freed just after it returns. After this, every subsequent call to update_effective_progs() causes this already deallocated pointer to be dereferenced in prog_list_length(), and triggers KASAN UAF error.
To fix this issue don't preserve the pointer to the prog or link in the list, but remove it and replace it with a dummy prog without shrinking the table. The subsequent call to __cgroup_bpf_detach() or __cgroup_bpf_detach() will correct it.
Fixes: af6eea57437a ("bpf: Implement bpf_link-based cgroup BPF program attachment") Reported-by: syzbot+f264bffdfbd5614f3bb2@syzkaller.appspotmail.com Signed-off-by: Tadeusz Struk tadeusz.struk@linaro.org Signed-off-by: Andrii Nakryiko andrii@kernel.org Cc: stable@vger.kernel.org Link: https://syzkaller.appspot.com/bug?id=8ebf179a95c2a2670f7cf1ba62429ec044369db... Link: https://lore.kernel.org/bpf/20220517180420.87954-1-tadeusz.struk@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/bpf/cgroup.c | 70 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 10 deletions(-)
--- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -721,6 +721,60 @@ static struct bpf_prog_list *find_detach }
/** + * purge_effective_progs() - After compute_effective_progs fails to alloc new + * cgrp->bpf.inactive table we can recover by + * recomputing the array in place. + * + * @cgrp: The cgroup which descendants to travers + * @prog: A program to detach or NULL + * @link: A link to detach or NULL + * @atype: Type of detach operation + */ +static void purge_effective_progs(struct cgroup *cgrp, struct bpf_prog *prog, + struct bpf_cgroup_link *link, + enum cgroup_bpf_attach_type atype) +{ + struct cgroup_subsys_state *css; + struct bpf_prog_array *progs; + struct bpf_prog_list *pl; + struct list_head *head; + struct cgroup *cg; + int pos; + + /* recompute effective prog array in place */ + css_for_each_descendant_pre(css, &cgrp->self) { + struct cgroup *desc = container_of(css, struct cgroup, self); + + if (percpu_ref_is_zero(&desc->bpf.refcnt)) + continue; + + /* find position of link or prog in effective progs array */ + for (pos = 0, cg = desc; cg; cg = cgroup_parent(cg)) { + if (pos && !(cg->bpf.flags[atype] & BPF_F_ALLOW_MULTI)) + continue; + + head = &cg->bpf.progs[atype]; + list_for_each_entry(pl, head, node) { + if (!prog_list_prog(pl)) + continue; + if (pl->prog == prog && pl->link == link) + goto found; + pos++; + } + } +found: + BUG_ON(!cg); + progs = rcu_dereference_protected( + desc->bpf.effective[atype], + lockdep_is_held(&cgroup_mutex)); + + /* Remove the program from the array */ + WARN_ONCE(bpf_prog_array_delete_safe_at(progs, pos), + "Failed to purge a prog from array at index %d", pos); + } +} + +/** * __cgroup_bpf_detach() - Detach the program or link from a cgroup, and * propagate the change to descendants * @cgrp: The cgroup which descendants to traverse @@ -739,7 +793,6 @@ static int __cgroup_bpf_detach(struct cg struct bpf_prog_list *pl; struct list_head *progs; u32 flags; - int err;
atype = to_cgroup_bpf_attach_type(type); if (atype < 0) @@ -761,9 +814,12 @@ static int __cgroup_bpf_detach(struct cg pl->prog = NULL; pl->link = NULL;
- err = update_effective_progs(cgrp, atype); - if (err) - goto cleanup; + if (update_effective_progs(cgrp, atype)) { + /* if update effective array failed replace the prog with a dummy prog*/ + pl->prog = old_prog; + pl->link = link; + purge_effective_progs(cgrp, old_prog, link, atype); + }
/* now can actually delete it from this cgroup list */ list_del(&pl->node); @@ -775,12 +831,6 @@ static int __cgroup_bpf_detach(struct cg bpf_prog_put(old_prog); static_branch_dec(&cgroup_bpf_enabled_key[atype]); return 0; - -cleanup: - /* restore back prog or link */ - pl->prog = old_prog; - pl->link = link; - return err; }
static int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
From: Qu Wenruo wqu@suse.com
commit dc4d31684974d140250f3ee612c3f0cab13b3146 upstream.
[BUG] If we have a btrfs image with dirty log, along with an unsupported RO compatible flag:
log_root 30474240 ... compat_flags 0x0 compat_ro_flags 0x40000003 ( FREE_SPACE_TREE | FREE_SPACE_TREE_VALID | unknown flag: 0x40000000 )
Then even if we can only mount it RO, we will still cause metadata update for log replay:
BTRFS info (device dm-1): flagging fs with big metadata feature BTRFS info (device dm-1): using free space tree BTRFS info (device dm-1): has skinny extents BTRFS info (device dm-1): start tree-log replay
This is definitely against RO compact flag requirement.
[CAUSE] RO compact flag only forces us to do RO mount, but we will still do log replay for plain RO mount.
Thus this will result us to do log replay and update metadata.
This can be very problematic for new RO compat flag, for example older kernel can not understand v2 cache, and if we allow metadata update on RO mount and invalidate/corrupt v2 cache.
[FIX] Just reject the mount unless rescue=nologreplay is provided:
BTRFS error (device dm-1): cannot replay dirty log with unsupport optional features (0x40000000), try rescue=nologreplay instead
We don't want to set rescue=nologreply directly, as this would make the end user to read the old data, and cause confusion.
Since the such case is really rare, we're mostly fine to just reject the mount with an error message, which also includes the proper workaround.
CC: stable@vger.kernel.org #4.9+ Signed-off-by: Qu Wenruo wqu@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/disk-io.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
--- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -3670,6 +3670,20 @@ int __cold open_ctree(struct super_block err = -EINVAL; goto fail_alloc; } + /* + * We have unsupported RO compat features, although RO mounted, we + * should not cause any metadata write, including log replay. + * Or we could screw up whatever the new feature requires. + */ + if (unlikely(features && btrfs_super_log_root(disk_super) && + !btrfs_test_opt(fs_info, NOLOGREPLAY))) { + btrfs_err(fs_info, +"cannot replay dirty log with unsupported compat_ro features (0x%llx), try rescue=nologreplay", + features); + err = -EINVAL; + goto fail_alloc; + } +
if (sectorsize < PAGE_SIZE) { struct btrfs_subpage_info *subpage_info;
From: Olga Kitaina okitain@gmail.com
commit e16eceea863b417fd328588b1be1a79de0bc937f upstream.
According to the Arasan NAND controller spec, the flash clock rate for SDR must be <= 100 MHz, while for NV-DDR it must be the same as the rate of the CLK line for the mode. The driver previously always set 100 MHz for NV-DDR, which would result in incorrect behavior for NV-DDR modes 0-4.
The appropriate clock rate can be calculated from the NV-DDR timing parameters as 1/tCK, or for rates measured in picoseconds, 10^12 / nand_nvddr_timings->tCK_min.
Fixes: 197b88fecc50 ("mtd: rawnand: arasan: Add new Arasan NAND controller") CC: stable@vger.kernel.org # 5.8+ Signed-off-by: Olga Kitaina okitain@gmail.com Signed-off-by: Amit Kumar Mahapatra amit.kumar-mahapatra@xilinx.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220628154824.12222-3-amit.kumar-mahapatr... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/arasan-nand-controller.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/mtd/nand/raw/arasan-nand-controller.c +++ b/drivers/mtd/nand/raw/arasan-nand-controller.c @@ -1043,7 +1043,13 @@ static int anfc_setup_interface(struct n DQS_BUFF_SEL_OUT(dqs_mode); }
- anand->clk = ANFC_XLNX_SDR_DFLT_CORE_CLK; + if (nand_interface_is_sdr(conf)) { + anand->clk = ANFC_XLNX_SDR_DFLT_CORE_CLK; + } else { + /* ONFI timings are defined in picoseconds */ + anand->clk = div_u64((u64)NSEC_PER_SEC * 1000, + conf->timings.nvddr.tCK_min); + }
/* * Due to a hardware bug in the ZynqMP SoC, SDR timing modes 0-1 work
From: Amit Kumar Mahapatra amit.kumar-mahapatra@xilinx.com
commit 7499bfeedb47efc1ee4dc793b92c610d46e6d6a6 upstream.
In current implementation the Arasan NAND driver is updating the system clock(i.e., anand->clk) in accordance to the timing modes (i.e., SDR or NVDDR). But as per the Arasan NAND controller spec the flash clock or the NAND bus clock(i.e., nfc->bus_clk), need to be updated instead. This patch keeps the system clock unchanged and updates the NAND bus clock as per the timing modes.
Fixes: 197b88fecc50 ("mtd: rawnand: arasan: Add new Arasan NAND controller") CC: stable@vger.kernel.org # 5.8+ Signed-off-by: Amit Kumar Mahapatra amit.kumar-mahapatra@xilinx.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220628154824.12222-2-amit.kumar-mahapatr... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/arasan-nand-controller.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/mtd/nand/raw/arasan-nand-controller.c +++ b/drivers/mtd/nand/raw/arasan-nand-controller.c @@ -347,17 +347,17 @@ static int anfc_select_target(struct nan
/* Update clock frequency */ if (nfc->cur_clk != anand->clk) { - clk_disable_unprepare(nfc->controller_clk); - ret = clk_set_rate(nfc->controller_clk, anand->clk); + clk_disable_unprepare(nfc->bus_clk); + ret = clk_set_rate(nfc->bus_clk, anand->clk); if (ret) { dev_err(nfc->dev, "Failed to change clock rate\n"); return ret; }
- ret = clk_prepare_enable(nfc->controller_clk); + ret = clk_prepare_enable(nfc->bus_clk); if (ret) { dev_err(nfc->dev, - "Failed to re-enable the controller clock\n"); + "Failed to re-enable the bus clock\n"); return ret; }
From: Benjamin Beichler benjamin.beichler@uni-rostock.de
commit c6496e0a4a90d8149203c16323cff3fa46e422e7 upstream.
Commit e3a33af812c6 ("um: fix and optimize xor select template for CONFIG64 and timetravel mode") caused a build regression when CONFIG_XOR_BLOCKS and CONFIG_UML_TIME_TRAVEL_SUPPORT are selected. Fix it by removing the straying parenthesis.
Cc: stable@vger.kernel.org Fixes: e3a33af812c6 ("um: fix and optimize xor select template for CONFIG64 and timetravel mode") Signed-off-by: Benjamin Beichler benjamin.beichler@uni-rostock.de [rw: Added commit message] Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/um/include/asm/xor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/um/include/asm/xor.h +++ b/arch/um/include/asm/xor.h @@ -18,7 +18,7 @@ #undef XOR_SELECT_TEMPLATE /* pick an arbitrary one - measuring isn't possible with inf-cpu */ #define XOR_SELECT_TEMPLATE(x) \ - (time_travel_mode == TT_MODE_INFCPU ? TT_CPU_INF_XOR_DEFAULT : x)) + (time_travel_mode == TT_MODE_INFCPU ? TT_CPU_INF_XOR_DEFAULT : x) #endif
#endif
From: Jason A. Donenfeld Jason@zx2c4.com
commit 0b9ba6135d7f18b82f3d8bebb55ded725ba88e0e upstream.
UML generally does not provide access to special CPU instructions like RDRAND, and execution tends to be rather deterministic, with no real hardware interrupts, making good randomness really very hard, if not all together impossible. Not only is this a security eyebrow raiser, but it's also quite annoying when trying to do various pieces of UML-based automation that takes a long time to boot, if ever.
Fix this by trivially calling getrandom() in the host and using that seed as "bootloader randomness", which initializes the rng immediately at UML boot.
The old behavior can be restored the same way as on any other arch, by way of CONFIG_TRUST_BOOTLOADER_RANDOMNESS=n or random.trust_bootloader=0. So seen from that perspective, this just makes UML act like other archs, which is positive in its own right.
Additionally, wire up arch_get_random_{int,long}() in the same way, so that reseeds can also make use of the host RNG, controllable by CONFIG_TRUST_CPU_RANDOMNESS and random.trust_cpu, per usual.
Cc: stable@vger.kernel.org Acked-by: Johannes Berg johannes@sipsolutions.net Acked-By: Anton Ivanov anton.ivanov@cambridgegreys.com Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/um/include/asm/archrandom.h | 30 ++++++++++++++++++++++++++++++ arch/um/include/shared/os.h | 7 +++++++ arch/um/kernel/um_arch.c | 8 ++++++++ arch/um/os-Linux/util.c | 6 ++++++ 4 files changed, 51 insertions(+) create mode 100644 arch/um/include/asm/archrandom.h
--- /dev/null +++ b/arch/um/include/asm/archrandom.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_UM_ARCHRANDOM_H__ +#define __ASM_UM_ARCHRANDOM_H__ + +#include <linux/types.h> + +/* This is from <os.h>, but better not to #include that in a global header here. */ +ssize_t os_getrandom(void *buf, size_t len, unsigned int flags); + +static inline bool __must_check arch_get_random_long(unsigned long *v) +{ + return os_getrandom(v, sizeof(*v), 0) == sizeof(*v); +} + +static inline bool __must_check arch_get_random_int(unsigned int *v) +{ + return os_getrandom(v, sizeof(*v), 0) == sizeof(*v); +} + +static inline bool __must_check arch_get_random_seed_long(unsigned long *v) +{ + return false; +} + +static inline bool __must_check arch_get_random_seed_int(unsigned int *v) +{ + return false; +} + +#endif --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -11,6 +11,12 @@ #include <irq_user.h> #include <longjmp.h> #include <mm_id.h> +/* This is to get size_t */ +#ifndef __UM_HOST__ +#include <linux/types.h> +#else +#include <sys/types.h> +#endif
#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
@@ -243,6 +249,7 @@ extern void stack_protections(unsigned l extern int raw(int fd); extern void setup_machinename(char *machine_out); extern void setup_hostinfo(char *buf, int len); +extern ssize_t os_getrandom(void *buf, size_t len, unsigned int flags); extern void os_dump_core(void) __attribute__ ((noreturn)); extern void um_early_printk(const char *s, unsigned int n); extern void os_fix_helper_signals(void); --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -16,6 +16,7 @@ #include <linux/sched/task.h> #include <linux/kmsg_dump.h> #include <linux/suspend.h> +#include <linux/random.h>
#include <asm/processor.h> #include <asm/cpufeature.h> @@ -406,6 +407,8 @@ int __init __weak read_initrd(void)
void __init setup_arch(char **cmdline_p) { + u8 rng_seed[32]; + stack_protections((unsigned long) &init_thread_info); setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); mem_total_pages(physmem_size, iomem_size, highmem); @@ -416,6 +419,11 @@ void __init setup_arch(char **cmdline_p) strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; setup_hostinfo(host_info, sizeof host_info); + + if (os_getrandom(rng_seed, sizeof(rng_seed), 0) == sizeof(rng_seed)) { + add_bootloader_randomness(rng_seed, sizeof(rng_seed)); + memzero_explicit(rng_seed, sizeof(rng_seed)); + } }
void __init check_bugs(void) --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -14,6 +14,7 @@ #include <sys/wait.h> #include <sys/mman.h> #include <sys/utsname.h> +#include <sys/random.h> #include <init.h> #include <os.h>
@@ -96,6 +97,11 @@ static inline void __attribute__ ((noret exit(127); }
+ssize_t os_getrandom(void *buf, size_t len, unsigned int flags) +{ + return getrandom(buf, len, flags); +} + /* * UML helper threads must not handle SIGWINCH/INT/TERM */
From: Fawzi Khaber fawzi.khaber@tdk.com
commit 5e1f91850365de55ca74945866c002fda8f00331 upstream.
iio_format_avail_range() should print range as follow [min, step, max], so the function was previously calling iio_format_list() with length = 3, length variable refers to the array size of values not the number of elements. In case of non IIO_VAL_INT values each element has integer part and decimal part. With length = 3 this would cause premature end of loop and result in printing only one element.
Signed-off-by: Fawzi Khaber fawzi.khaber@tdk.com Signed-off-by: Jean-Baptiste Maneyrol jean-baptiste.maneyrol@tdk.com Fixes: eda20ba1e25e ("iio: core: Consolidate iio_format_avail_{list,range}()") Link: https://lore.kernel.org/r/20220718130706.32571-1-jmaneyrol@invensense.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/industrialio-core.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
--- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -835,7 +835,23 @@ static ssize_t iio_format_avail_list(cha
static ssize_t iio_format_avail_range(char *buf, const int *vals, int type) { - return iio_format_list(buf, vals, type, 3, "[", "]"); + int length; + + /* + * length refers to the array size , not the number of elements. + * The purpose is to print the range [min , step ,max] so length should + * be 3 in case of int, and 6 for other types. + */ + switch (type) { + case IIO_VAL_INT: + length = 3; + break; + default: + length = 6; + break; + } + + return iio_format_list(buf, vals, type, length, "[", "]"); }
static ssize_t iio_read_channel_info_avail(struct device *dev,
From: Zheyu Ma zheyuma97@gmail.com
commit 06674fc7c003b9d0aa1d37fef7ab2c24802cc6ad upstream.
The driver use the non-managed form of the register function in isl29028_remove(). To keep the release order as mirroring the ordering in probe, the driver should use non-managed form in probe, too.
The following log reveals it:
[ 32.374955] isl29028 0-0010: remove [ 32.376861] general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] PREEMPT SMP KASAN PTI [ 32.377676] KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037] [ 32.379432] RIP: 0010:kernfs_find_and_get_ns+0x28/0xe0 [ 32.385461] Call Trace: [ 32.385807] sysfs_unmerge_group+0x59/0x110 [ 32.386110] dpm_sysfs_remove+0x58/0xc0 [ 32.386391] device_del+0x296/0xe50 [ 32.386959] cdev_device_del+0x1d/0xd0 [ 32.387231] devm_iio_device_unreg+0x27/0xb0 [ 32.387542] devres_release_group+0x319/0x3d0 [ 32.388162] i2c_device_remove+0x93/0x1f0
Fixes: 2db5054ac28d ("staging: iio: isl29028: add runtime power management support") Signed-off-by: Zheyu Ma zheyuma97@gmail.com Link: https://lore.kernel.org/r/20220717004241.2281028-1-zheyuma97@gmail.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/light/isl29028.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/light/isl29028.c +++ b/drivers/iio/light/isl29028.c @@ -625,7 +625,7 @@ static int isl29028_probe(struct i2c_cli ISL29028_POWER_OFF_DELAY_MS); pm_runtime_use_autosuspend(&client->dev);
- ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); + ret = iio_device_register(indio_dev); if (ret < 0) { dev_err(&client->dev, "%s(): iio registration failed with error %d\n",
From: James Smart jsmart2021@gmail.com
commit 0948a9c5386095baae4012190a6b65aba684a907 upstream.
VMID introduced an extra increment of cmd_pending, causing double-counting of the I/O. The normal increment ios performed in lpfc_get_scsi_buf.
Link: https://lore.kernel.org/r/20220701211425.2708-5-jsmart2021@gmail.com Fixes: 33c79741deaf ("scsi: lpfc: vmid: Introduce VMID in I/O path") Cc: stable@vger.kernel.org # v5.14+ Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/lpfc/lpfc_scsi.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5456,7 +5456,6 @@ lpfc_queuecommand(struct Scsi_Host *shos cur_iocbq->cmd_flag |= LPFC_IO_VMID; } } - atomic_inc(&ndlp->cmd_pending);
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS if (unlikely(phba->hdwqstat_on & LPFC_CHECK_SCSI_IO))
From: Tony Battersby tonyb@cybernetics.com
commit 3455607fd7be10b449f5135c00dc306b85dc0d21 upstream.
When a SCSI device is removed while in active use, currently sg will immediately return -ENODEV on any attempt to wait for active commands that were sent before the removal. This is problematic for commands that use SG_FLAG_DIRECT_IO since the data buffer may still be in use by the kernel when userspace frees or reuses it after getting ENODEV, leading to corrupted userspace memory (in the case of READ-type commands) or corrupted data being sent to the device (in the case of WRITE-type commands). This has been seen in practice when logging out of a iscsi_tcp session, where the iSCSI driver may still be processing commands after the device has been marked for removal.
Change the policy to allow userspace to wait for active sg commands even when the device is being removed. Return -ENODEV only when there are no more responses to read.
Link: https://lore.kernel.org/r/5ebea46f-fe83-2d0b-233d-d0dcb362dd0a@cybernetics.c... Cc: stable@vger.kernel.org Acked-by: Douglas Gilbert dgilbert@interlog.com Signed-off-by: Tony Battersby tonyb@cybernetics.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/sg.c | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-)
--- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -195,7 +195,7 @@ static void sg_link_reserve(Sg_fd * sfp, static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp); static Sg_fd *sg_add_sfp(Sg_device * sdp); static void sg_remove_sfp(struct kref *); -static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id); +static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id, bool *busy); static Sg_request *sg_add_request(Sg_fd * sfp); static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); static Sg_device *sg_get_dev(int dev); @@ -444,6 +444,7 @@ sg_read(struct file *filp, char __user * Sg_fd *sfp; Sg_request *srp; int req_pack_id = -1; + bool busy; sg_io_hdr_t *hp; struct sg_header *old_hdr; int retval; @@ -466,20 +467,16 @@ sg_read(struct file *filp, char __user * if (retval) return retval;
- srp = sg_get_rq_mark(sfp, req_pack_id); + srp = sg_get_rq_mark(sfp, req_pack_id, &busy); if (!srp) { /* now wait on packet to arrive */ - if (atomic_read(&sdp->detaching)) - return -ENODEV; if (filp->f_flags & O_NONBLOCK) return -EAGAIN; retval = wait_event_interruptible(sfp->read_wait, - (atomic_read(&sdp->detaching) || - (srp = sg_get_rq_mark(sfp, req_pack_id)))); - if (atomic_read(&sdp->detaching)) - return -ENODEV; - if (retval) - /* -ERESTARTSYS as signal hit process */ - return retval; + ((srp = sg_get_rq_mark(sfp, req_pack_id, &busy)) || + (!busy && atomic_read(&sdp->detaching)))); + if (!srp) + /* signal or detaching */ + return retval ? retval : -ENODEV; } if (srp->header.interface_id != '\0') return sg_new_read(sfp, buf, count, srp); @@ -940,9 +937,7 @@ sg_ioctl_common(struct file *filp, Sg_de if (result < 0) return result; result = wait_event_interruptible(sfp->read_wait, - (srp_done(sfp, srp) || atomic_read(&sdp->detaching))); - if (atomic_read(&sdp->detaching)) - return -ENODEV; + srp_done(sfp, srp)); write_lock_irq(&sfp->rq_list_lock); if (srp->done) { srp->done = 2; @@ -2079,19 +2074,28 @@ sg_unlink_reserve(Sg_fd * sfp, Sg_reques }
static Sg_request * -sg_get_rq_mark(Sg_fd * sfp, int pack_id) +sg_get_rq_mark(Sg_fd * sfp, int pack_id, bool *busy) { Sg_request *resp; unsigned long iflags;
+ *busy = false; write_lock_irqsave(&sfp->rq_list_lock, iflags); list_for_each_entry(resp, &sfp->rq_list, entry) { - /* look for requests that are ready + not SG_IO owned */ - if ((1 == resp->done) && (!resp->sg_io_owned) && + /* look for requests that are not SG_IO owned */ + if ((!resp->sg_io_owned) && ((-1 == pack_id) || (resp->header.pack_id == pack_id))) { - resp->done = 2; /* guard against other readers */ - write_unlock_irqrestore(&sfp->rq_list_lock, iflags); - return resp; + switch (resp->done) { + case 0: /* request active */ + *busy = true; + break; + case 1: /* request done; response ready to return */ + resp->done = 2; /* guard against other readers */ + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + return resp; + case 2: /* response already being returned */ + break; + } } } write_unlock_irqrestore(&sfp->rq_list_lock, iflags); @@ -2145,6 +2149,15 @@ sg_remove_request(Sg_fd * sfp, Sg_reques res = 1; } write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + + /* + * If the device is detaching, wakeup any readers in case we just + * removed the last response, which would leave nothing for them to + * return other than -ENODEV. + */ + if (unlikely(atomic_read(&sfp->parentdp->detaching))) + wake_up_interruptible_all(&sfp->read_wait); + return res; }
From: Bikash Hazarika bhazarika@marvell.com
commit cf3b4fb655796674e605268bd4bfb47a47c8bce6 upstream.
Replace display field with the correct field.
Link: https://lore.kernel.org/r/20220713052045.10683-3-njavali@marvell.com Fixes: 8777e4314d39 ("scsi: qla2xxx: Migrate NVME N2N handling into state machine") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Bikash Hazarika bhazarika@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_def.h | 1 + drivers/scsi/qla2xxx/qla_gs.c | 9 +++------ drivers/scsi/qla2xxx/qla_init.c | 2 ++ drivers/scsi/qla2xxx/qla_isr.c | 4 +--- 4 files changed, 7 insertions(+), 9 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3975,6 +3975,7 @@ struct qla_hw_data { /* SRB cache. */ #define SRB_MIN_REQ 128 mempool_t *srb_mempool; + u8 port_name[WWN_SIZE];
volatile struct { uint32_t mbox_int :1; --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -1596,7 +1596,6 @@ qla2x00_hba_attributes(scsi_qla_host_t * unsigned int callopt) { struct qla_hw_data *ha = vha->hw; - struct init_cb_24xx *icb24 = (void *)ha->init_cb; struct new_utsname *p_sysid = utsname(); struct ct_fdmi_hba_attr *eiter; uint16_t alen; @@ -1758,8 +1757,8 @@ qla2x00_hba_attributes(scsi_qla_host_t * /* MAX CT Payload Length */ eiter = entries + size; eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH); - eiter->a.max_ct_len = cpu_to_be32(le16_to_cpu(IS_FWI2_CAPABLE(ha) ? - icb24->frame_payload_size : ha->init_cb->frame_payload_size)); + eiter->a.max_ct_len = cpu_to_be32(ha->frame_payload_size >> 2); + alen = sizeof(eiter->a.max_ct_len); alen += FDMI_ATTR_TYPELEN(eiter); eiter->len = cpu_to_be16(alen); @@ -1851,7 +1850,6 @@ qla2x00_port_attributes(scsi_qla_host_t unsigned int callopt) { struct qla_hw_data *ha = vha->hw; - struct init_cb_24xx *icb24 = (void *)ha->init_cb; struct new_utsname *p_sysid = utsname(); char *hostname = p_sysid ? p_sysid->nodename : fc_host_system_hostname(vha->host); @@ -1903,8 +1901,7 @@ qla2x00_port_attributes(scsi_qla_host_t /* Max frame size. */ eiter = entries + size; eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); - eiter->a.max_frame_size = cpu_to_be32(le16_to_cpu(IS_FWI2_CAPABLE(ha) ? - icb24->frame_payload_size : ha->init_cb->frame_payload_size)); + eiter->a.max_frame_size = cpu_to_be32(ha->frame_payload_size); alen = sizeof(eiter->a.max_frame_size); alen += FDMI_ATTR_TYPELEN(eiter); eiter->len = cpu_to_be16(alen); --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4509,6 +4509,8 @@ qla2x00_init_rings(scsi_qla_host_t *vha) BIT_6) != 0; ql_dbg(ql_dbg_init, vha, 0x00bc, "FA-WWPN Support: %s.\n", (ha->flags.fawwpn_enabled) ? "enabled" : "disabled"); + /* Init_cb will be reused for other command(s). Save a backup copy of port_name */ + memcpy(ha->port_name, ha->init_cb->port_name, WWN_SIZE); }
/* ELS pass through payload is limit by frame size. */ --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1354,9 +1354,7 @@ skip_rio: if (!vha->vp_idx) { if (ha->flags.fawwpn_enabled && (ha->current_topology == ISP_CFG_F)) { - void *wwpn = ha->init_cb->port_name; - - memcpy(vha->port_name, wwpn, WWN_SIZE); + memcpy(vha->port_name, ha->port_name, WWN_SIZE); fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); ql_dbg(ql_dbg_init + ql_dbg_verbose,
From: Bikash Hazarika bhazarika@marvell.com
commit 6c96a3c7d49593ef15805f5e497601c87695abc9 upstream.
While requesting a new mailbox command, driver does not write any data to unused registers. Initialize the unused register value to zero while requesting a new mailbox command to prevent stale entry access by firmware.
Link: https://lore.kernel.org/r/20220713052045.10683-4-njavali@marvell.com Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Bikash Hazarika bhazarika@marvell.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_mbx.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -238,6 +238,8 @@ qla2x00_mailbox_command(scsi_qla_host_t ql_dbg(ql_dbg_mbx, vha, 0x1112, "mbox[%d]<-0x%04x\n", cnt, *iptr); wrt_reg_word(optr, *iptr); + } else { + wrt_reg_word(optr, 0); }
mboxes >>= 1;
From: Srinivas Kandagatla srinivas.kandagatla@linaro.org
commit aa1262ca66957183ea1fb32a067e145b995f3744 upstream.
As per hardware datasheet its recommended that we check the device status before reading devid assigned by auto-enumeration.
Without this patch we see SoundWire devices with invalid enumeration addresses on the bus.
Cc: stable@vger.kernel.org Fixes: a6e6581942ca ("soundwire: qcom: add auto enumeration support") Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20220706095644.5852-1-srinivas.kandagatla@linaro.o... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/soundwire/qcom.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -471,6 +471,10 @@ static int qcom_swrm_enumerate(struct sd char *buf1 = (char *)&val1, *buf2 = (char *)&val2;
for (i = 1; i <= SDW_MAX_DEVICES; i++) { + /* do not continue if the status is Not Present */ + if (!ctrl->status[i]) + continue; + /*SCP_Devid5 - Devid 4*/ ctrl->reg_read(ctrl, SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i), &val1);
From: Namjae Jeon linkinjeon@kernel.org
commit aa7253c2393f6dcd6a1468b0792f6da76edad917 upstream.
The allocated memory didn't free under an error path in smb2_handle_negotiate().
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-17815 Signed-off-by: Namjae Jeon linkinjeon@kernel.org Reviewed-by: Hyunchul Lee hyc.lee@gmail.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ksmbd/smb2pdu.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -1139,12 +1139,16 @@ int smb2_handle_negotiate(struct ksmbd_w status); rsp->hdr.Status = status; rc = -EINVAL; + kfree(conn->preauth_info); + conn->preauth_info = NULL; goto err_out; }
rc = init_smb3_11_server(conn); if (rc < 0) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; + kfree(conn->preauth_info); + conn->preauth_info = NULL; goto err_out; }
From: Hyunchul Lee hyc.lee@gmail.com
commit 824d4f64c20093275f72fc8101394d75ff6a249e upstream.
if Status is not 0 and PathLength is long, smb_strndup_from_utf16 could make out of bound read in smb2_tree_connnect.
This bug can lead an oops looking something like:
[ 1553.882047] BUG: KASAN: slab-out-of-bounds in smb_strndup_from_utf16+0x469/0x4c0 [ksmbd] [ 1553.882064] Read of size 2 at addr ffff88802c4eda04 by task kworker/0:2/42805 ... [ 1553.882095] Call Trace: [ 1553.882098] <TASK> [ 1553.882101] dump_stack_lvl+0x49/0x5f [ 1553.882107] print_report.cold+0x5e/0x5cf [ 1553.882112] ? smb_strndup_from_utf16+0x469/0x4c0 [ksmbd] [ 1553.882122] kasan_report+0xaa/0x120 [ 1553.882128] ? smb_strndup_from_utf16+0x469/0x4c0 [ksmbd] [ 1553.882139] __asan_report_load_n_noabort+0xf/0x20 [ 1553.882143] smb_strndup_from_utf16+0x469/0x4c0 [ksmbd] [ 1553.882155] ? smb_strtoUTF16+0x3b0/0x3b0 [ksmbd] [ 1553.882166] ? __kmalloc_node+0x185/0x430 [ 1553.882171] smb2_tree_connect+0x140/0xab0 [ksmbd] [ 1553.882185] handle_ksmbd_work+0x30e/0x1020 [ksmbd] [ 1553.882197] process_one_work+0x778/0x11c0 [ 1553.882201] ? _raw_spin_lock_irq+0x8e/0xe0 [ 1553.882206] worker_thread+0x544/0x1180 [ 1553.882209] ? __cpuidle_text_end+0x4/0x4 [ 1553.882214] kthread+0x282/0x320 [ 1553.882218] ? process_one_work+0x11c0/0x11c0 [ 1553.882221] ? kthread_complete_and_exit+0x30/0x30 [ 1553.882225] ret_from_fork+0x1f/0x30 [ 1553.882231] </TASK>
There is no need to check error request validation in server. This check allow invalid requests not to validate message.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-17818 Signed-off-by: Hyunchul Lee hyc.lee@gmail.com Acked-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 | 5 ----- 1 file changed, 5 deletions(-)
--- a/fs/ksmbd/smb2misc.c +++ b/fs/ksmbd/smb2misc.c @@ -90,11 +90,6 @@ static int smb2_get_data_area_len(unsign *off = 0; *len = 0;
- /* error reqeusts do not have data area */ - if (hdr->Status && hdr->Status != STATUS_MORE_PROCESSING_REQUIRED && - (((struct smb2_err_rsp *)hdr)->StructureSize) == SMB2_ERROR_STRUCTURE_SIZE2_LE) - return ret; - /* * Following commands have data areas so we have to get the location * of the data buffer offset and data buffer length for the particular
From: Hyunchul Lee hyc.lee@gmail.com
commit ac60778b87e45576d7bfdbd6f53df902654e6f09 upstream.
OOB read memory can be written to a file, if DataOffset is 0 and Length is too large in SMB2_WRITE request of compound request.
To prevent this, when checking the length of the data area of SMB2_WRITE in smb2_get_data_area_len(), let the minimum of DataOffset be the size of SMB2 header + the size of SMB2_WRITE header.
This bug can lead an oops looking something like:
[ 798.008715] BUG: KASAN: slab-out-of-bounds in copy_page_from_iter_atomic+0xd3d/0x14b0 [ 798.008724] Read of size 252 at addr ffff88800f863e90 by task kworker/0:2/2859 ... [ 798.008754] Call Trace: [ 798.008756] <TASK> [ 798.008759] dump_stack_lvl+0x49/0x5f [ 798.008764] print_report.cold+0x5e/0x5cf [ 798.008768] ? __filemap_get_folio+0x285/0x6d0 [ 798.008774] ? copy_page_from_iter_atomic+0xd3d/0x14b0 [ 798.008777] kasan_report+0xaa/0x120 [ 798.008781] ? copy_page_from_iter_atomic+0xd3d/0x14b0 [ 798.008784] kasan_check_range+0x100/0x1e0 [ 798.008788] memcpy+0x24/0x60 [ 798.008792] copy_page_from_iter_atomic+0xd3d/0x14b0 [ 798.008795] ? pagecache_get_page+0x53/0x160 [ 798.008799] ? iov_iter_get_pages_alloc+0x1590/0x1590 [ 798.008803] ? ext4_write_begin+0xfc0/0xfc0 [ 798.008807] ? current_time+0x72/0x210 [ 798.008811] generic_perform_write+0x2c8/0x530 [ 798.008816] ? filemap_fdatawrite_wbc+0x180/0x180 [ 798.008820] ? down_write+0xb4/0x120 [ 798.008824] ? down_write_killable+0x130/0x130 [ 798.008829] ext4_buffered_write_iter+0x137/0x2c0 [ 798.008833] ext4_file_write_iter+0x40b/0x1490 [ 798.008837] ? __fsnotify_parent+0x275/0xb20 [ 798.008842] ? __fsnotify_update_child_dentry_flags+0x2c0/0x2c0 [ 798.008846] ? ext4_buffered_write_iter+0x2c0/0x2c0 [ 798.008851] __kernel_write+0x3a1/0xa70 [ 798.008855] ? __x64_sys_preadv2+0x160/0x160 [ 798.008860] ? security_file_permission+0x4a/0xa0 [ 798.008865] kernel_write+0xbb/0x360 [ 798.008869] ksmbd_vfs_write+0x27e/0xb90 [ksmbd] [ 798.008881] ? ksmbd_vfs_read+0x830/0x830 [ksmbd] [ 798.008892] ? _raw_read_unlock+0x2a/0x50 [ 798.008896] smb2_write+0xb45/0x14e0 [ksmbd] [ 798.008909] ? __kasan_check_write+0x14/0x20 [ 798.008912] ? _raw_spin_lock_bh+0xd0/0xe0 [ 798.008916] ? smb2_read+0x15e0/0x15e0 [ksmbd] [ 798.008927] ? memcpy+0x4e/0x60 [ 798.008931] ? _raw_spin_unlock+0x19/0x30 [ 798.008934] ? ksmbd_smb2_check_message+0x16af/0x2350 [ksmbd] [ 798.008946] ? _raw_spin_lock_bh+0xe0/0xe0 [ 798.008950] handle_ksmbd_work+0x30e/0x1020 [ksmbd] [ 798.008962] process_one_work+0x778/0x11c0 [ 798.008966] ? _raw_spin_lock_irq+0x8e/0xe0 [ 798.008970] worker_thread+0x544/0x1180 [ 798.008973] ? __cpuidle_text_end+0x4/0x4 [ 798.008977] kthread+0x282/0x320 [ 798.008982] ? process_one_work+0x11c0/0x11c0 [ 798.008985] ? kthread_complete_and_exit+0x30/0x30 [ 798.008989] ret_from_fork+0x1f/0x30 [ 798.008995] </TASK>
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-17817 Signed-off-by: Hyunchul Lee hyc.lee@gmail.com Acked-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 | 7 +++++-- fs/ksmbd/smb2pdu.c | 8 +++----- 2 files changed, 8 insertions(+), 7 deletions(-)
--- a/fs/ksmbd/smb2misc.c +++ b/fs/ksmbd/smb2misc.c @@ -131,8 +131,11 @@ static int smb2_get_data_area_len(unsign *len = le16_to_cpu(((struct smb2_read_req *)hdr)->ReadChannelInfoLength); break; case SMB2_WRITE: - if (((struct smb2_write_req *)hdr)->DataOffset) { - *off = le16_to_cpu(((struct smb2_write_req *)hdr)->DataOffset); + if (((struct smb2_write_req *)hdr)->DataOffset || + ((struct smb2_write_req *)hdr)->Length) { + *off = max_t(unsigned int, + le16_to_cpu(((struct smb2_write_req *)hdr)->DataOffset), + offsetof(struct smb2_write_req, Buffer)); *len = le32_to_cpu(((struct smb2_write_req *)hdr)->Length); break; } --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -6499,14 +6499,12 @@ int smb2_write(struct ksmbd_work *work) writethrough = true;
if (is_rdma_channel == false) { - if ((u64)le16_to_cpu(req->DataOffset) + length > - get_rfc1002_len(work->request_buf)) { - pr_err("invalid write data offset %u, smb_len %u\n", - le16_to_cpu(req->DataOffset), - get_rfc1002_len(work->request_buf)); + if (le16_to_cpu(req->DataOffset) < + offsetof(struct smb2_write_req, Buffer)) { err = -EINVAL; goto out; } + data_buf = (char *)(((char *)&req->hdr.ProtocolId) + le16_to_cpu(req->DataOffset));
From: Namjae Jeon linkinjeon@kernel.org
commit cf6531d98190fa2cf92a6d8bbc8af0a4740a223c upstream.
smb2_tree_disconnect() freed the struct ksmbd_tree_connect, but it left the dangling pointer. It can be accessed again under compound requests.
This bug can lead an oops looking something link:
[ 1685.468014 ] BUG: KASAN: use-after-free in ksmbd_tree_conn_disconnect+0x131/0x160 [ksmbd] [ 1685.468068 ] Read of size 4 at addr ffff888102172180 by task kworker/1:2/4807 ... [ 1685.468130 ] Call Trace: [ 1685.468132 ] <TASK> [ 1685.468135 ] dump_stack_lvl+0x49/0x5f [ 1685.468141 ] print_report.cold+0x5e/0x5cf [ 1685.468145 ] ? ksmbd_tree_conn_disconnect+0x131/0x160 [ksmbd] [ 1685.468157 ] kasan_report+0xaa/0x120 [ 1685.468194 ] ? ksmbd_tree_conn_disconnect+0x131/0x160 [ksmbd] [ 1685.468206 ] __asan_report_load4_noabort+0x14/0x20 [ 1685.468210 ] ksmbd_tree_conn_disconnect+0x131/0x160 [ksmbd] [ 1685.468222 ] smb2_tree_disconnect+0x175/0x250 [ksmbd] [ 1685.468235 ] handle_ksmbd_work+0x30e/0x1020 [ksmbd] [ 1685.468247 ] process_one_work+0x778/0x11c0 [ 1685.468251 ] ? _raw_spin_lock_irq+0x8e/0xe0 [ 1685.468289 ] worker_thread+0x544/0x1180 [ 1685.468293 ] ? __cpuidle_text_end+0x4/0x4 [ 1685.468297 ] kthread+0x282/0x320 [ 1685.468301 ] ? process_one_work+0x11c0/0x11c0 [ 1685.468305 ] ? kthread_complete_and_exit+0x30/0x30 [ 1685.468309 ] ret_from_fork+0x1f/0x30
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-17816 Signed-off-by: Namjae Jeon linkinjeon@kernel.org Reviewed-by: Hyunchul Lee hyc.lee@gmail.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ksmbd/smb2pdu.c | 1 + 1 file changed, 1 insertion(+)
--- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -2043,6 +2043,7 @@ int smb2_tree_disconnect(struct ksmbd_wo
ksmbd_close_tree_conn_fds(work); ksmbd_tree_conn_disconnect(sess, tcon); + work->tcon = NULL; return 0; }
From: Namjae Jeon linkinjeon@kernel.org
commit 8f0541186e9ad1b62accc9519cc2b7a7240272a7 upstream.
The testcase use SMB2_SET_INFO_HE command to set a malformed file attribute under the label `security.NTACL`. SMB2_QUERY_INFO_HE command in testcase trigger the following overflow.
[ 4712.003781] ================================================================== [ 4712.003790] BUG: KASAN: slab-out-of-bounds in build_sec_desc+0x842/0x1dd0 [ksmbd] [ 4712.003807] Write of size 1060 at addr ffff88801e34c068 by task kworker/0:0/4190
[ 4712.003813] CPU: 0 PID: 4190 Comm: kworker/0:0 Not tainted 5.19.0-rc5 #1 [ 4712.003850] Workqueue: ksmbd-io handle_ksmbd_work [ksmbd] [ 4712.003867] Call Trace: [ 4712.003870] <TASK> [ 4712.003873] dump_stack_lvl+0x49/0x5f [ 4712.003935] print_report.cold+0x5e/0x5cf [ 4712.003972] ? ksmbd_vfs_get_sd_xattr+0x16d/0x500 [ksmbd] [ 4712.003984] ? cmp_map_id+0x200/0x200 [ 4712.003988] ? build_sec_desc+0x842/0x1dd0 [ksmbd] [ 4712.004000] kasan_report+0xaa/0x120 [ 4712.004045] ? build_sec_desc+0x842/0x1dd0 [ksmbd] [ 4712.004056] kasan_check_range+0x100/0x1e0 [ 4712.004060] memcpy+0x3c/0x60 [ 4712.004064] build_sec_desc+0x842/0x1dd0 [ksmbd] [ 4712.004076] ? parse_sec_desc+0x580/0x580 [ksmbd] [ 4712.004088] ? ksmbd_acls_fattr+0x281/0x410 [ksmbd] [ 4712.004099] smb2_query_info+0xa8f/0x6110 [ksmbd] [ 4712.004111] ? psi_group_change+0x856/0xd70 [ 4712.004148] ? update_load_avg+0x1c3/0x1af0 [ 4712.004152] ? asym_cpu_capacity_scan+0x5d0/0x5d0 [ 4712.004157] ? xas_load+0x23/0x300 [ 4712.004162] ? smb2_query_dir+0x1530/0x1530 [ksmbd] [ 4712.004173] ? _raw_spin_lock_bh+0xe0/0xe0 [ 4712.004179] handle_ksmbd_work+0x30e/0x1020 [ksmbd] [ 4712.004192] process_one_work+0x778/0x11c0 [ 4712.004227] ? _raw_spin_lock_irq+0x8e/0xe0 [ 4712.004231] worker_thread+0x544/0x1180 [ 4712.004234] ? __cpuidle_text_end+0x4/0x4 [ 4712.004239] kthread+0x282/0x320 [ 4712.004243] ? process_one_work+0x11c0/0x11c0 [ 4712.004246] ? kthread_complete_and_exit+0x30/0x30 [ 4712.004282] ret_from_fork+0x1f/0x30
This patch add the buffer validation for security descriptor that is stored by malformed SMB2_SET_INFO_HE command. and allocate large response buffer about SMB2_O_INFO_SECURITY file info class.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-17771 Reviewed-by: Hyunchul Lee hyc.lee@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/smb2pdu.c | 39 ++++++++++----- fs/ksmbd/smbacl.c | 130 +++++++++++++++++++++++++++++++++++------------------ fs/ksmbd/smbacl.h | 2 fs/ksmbd/vfs.c | 5 ++ 4 files changed, 119 insertions(+), 57 deletions(-)
--- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -535,9 +535,10 @@ int smb2_allocate_rsp_buf(struct ksmbd_w struct smb2_query_info_req *req;
req = smb2_get_msg(work->request_buf); - if (req->InfoType == SMB2_O_INFO_FILE && - (req->FileInfoClass == FILE_FULL_EA_INFORMATION || - req->FileInfoClass == FILE_ALL_INFORMATION)) + if ((req->InfoType == SMB2_O_INFO_FILE && + (req->FileInfoClass == FILE_FULL_EA_INFORMATION || + req->FileInfoClass == FILE_ALL_INFORMATION)) || + req->InfoType == SMB2_O_INFO_SECURITY) sz = large_sz; }
@@ -2974,7 +2975,7 @@ int smb2_open(struct ksmbd_work *work) goto err_out;
rc = build_sec_desc(user_ns, - pntsd, NULL, + pntsd, NULL, 0, OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO, @@ -3819,6 +3820,15 @@ static int verify_info_level(int info_le return 0; }
+static int smb2_resp_buf_len(struct ksmbd_work *work, unsigned short hdr2_len) +{ + int free_len; + + free_len = (int)(work->response_sz - + (get_rfc1002_len(work->response_buf) + 4)) - hdr2_len; + return free_len; +} + static int smb2_calc_max_out_buf_len(struct ksmbd_work *work, unsigned short hdr2_len, unsigned int out_buf_len) @@ -3828,9 +3838,7 @@ static int smb2_calc_max_out_buf_len(str if (out_buf_len > work->conn->vals->max_trans_size) return -EINVAL;
- free_len = (int)(work->response_sz - - (get_rfc1002_len(work->response_buf) + 4)) - - hdr2_len; + free_len = smb2_resp_buf_len(work, hdr2_len); if (free_len < 0) return -EINVAL;
@@ -5093,10 +5101,10 @@ static int smb2_get_info_sec(struct ksmb struct smb_ntsd *pntsd = (struct smb_ntsd *)rsp->Buffer, *ppntsd = NULL; struct smb_fattr fattr = {{0}}; struct inode *inode; - __u32 secdesclen; + __u32 secdesclen = 0; unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID; int addition_info = le32_to_cpu(req->AdditionalInformation); - int rc; + int rc = 0, ppntsd_size = 0;
if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO | PROTECTED_DACL_SECINFO | @@ -5142,11 +5150,14 @@ static int smb2_get_info_sec(struct ksmb
if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) - ksmbd_vfs_get_sd_xattr(work->conn, user_ns, - fp->filp->f_path.dentry, &ppntsd); - - rc = build_sec_desc(user_ns, pntsd, ppntsd, addition_info, - &secdesclen, &fattr); + ppntsd_size = ksmbd_vfs_get_sd_xattr(work->conn, user_ns, + fp->filp->f_path.dentry, + &ppntsd); + + /* Check if sd buffer size exceeds response buffer size */ + if (smb2_resp_buf_len(work, 8) > ppntsd_size) + rc = build_sec_desc(user_ns, pntsd, ppntsd, ppntsd_size, + addition_info, &secdesclen, &fattr); posix_acl_release(fattr.cf_acls); posix_acl_release(fattr.cf_dacls); kfree(ppntsd); --- a/fs/ksmbd/smbacl.c +++ b/fs/ksmbd/smbacl.c @@ -690,6 +690,7 @@ posix_default_acl: static void set_ntacl_dacl(struct user_namespace *user_ns, struct smb_acl *pndacl, struct smb_acl *nt_dacl, + unsigned int aces_size, const struct smb_sid *pownersid, const struct smb_sid *pgrpsid, struct smb_fattr *fattr) @@ -703,9 +704,19 @@ static void set_ntacl_dacl(struct user_n if (nt_num_aces) { ntace = (struct smb_ace *)((char *)nt_dacl + sizeof(struct smb_acl)); for (i = 0; i < nt_num_aces; i++) { - memcpy((char *)pndace + size, ntace, le16_to_cpu(ntace->size)); - size += le16_to_cpu(ntace->size); - ntace = (struct smb_ace *)((char *)ntace + le16_to_cpu(ntace->size)); + unsigned short nt_ace_size; + + if (offsetof(struct smb_ace, access_req) > aces_size) + break; + + nt_ace_size = le16_to_cpu(ntace->size); + if (nt_ace_size > aces_size) + break; + + memcpy((char *)pndace + size, ntace, nt_ace_size); + size += nt_ace_size; + aces_size -= nt_ace_size; + ntace = (struct smb_ace *)((char *)ntace + nt_ace_size); num_aces++; } } @@ -878,7 +889,7 @@ int parse_sec_desc(struct user_namespace /* Convert permission bits from mode to equivalent CIFS ACL */ int build_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd, - int addition_info, __u32 *secdesclen, + int ppntsd_size, int addition_info, __u32 *secdesclen, struct smb_fattr *fattr) { int rc = 0; @@ -938,15 +949,25 @@ int build_sec_desc(struct user_namespace
if (!ppntsd) { set_mode_dacl(user_ns, dacl_ptr, fattr); - } else if (!ppntsd->dacloffset) { - goto out; } else { struct smb_acl *ppdacl_ptr; + unsigned int dacl_offset = le32_to_cpu(ppntsd->dacloffset); + int ppdacl_size, ntacl_size = ppntsd_size - dacl_offset; + + if (!dacl_offset || + (dacl_offset + sizeof(struct smb_acl) > ppntsd_size)) + goto out; + + ppdacl_ptr = (struct smb_acl *)((char *)ppntsd + dacl_offset); + ppdacl_size = le16_to_cpu(ppdacl_ptr->size); + if (ppdacl_size > ntacl_size || + ppdacl_size < sizeof(struct smb_acl)) + goto out;
- ppdacl_ptr = (struct smb_acl *)((char *)ppntsd + - le32_to_cpu(ppntsd->dacloffset)); set_ntacl_dacl(user_ns, dacl_ptr, ppdacl_ptr, - nowner_sid_ptr, ngroup_sid_ptr, fattr); + ntacl_size - sizeof(struct smb_acl), + nowner_sid_ptr, ngroup_sid_ptr, + fattr); } pntsd->dacloffset = cpu_to_le32(offset); offset += le16_to_cpu(dacl_ptr->size); @@ -980,24 +1001,31 @@ int smb_inherit_dacl(struct ksmbd_conn * struct smb_sid owner_sid, group_sid; struct dentry *parent = path->dentry->d_parent; struct user_namespace *user_ns = mnt_user_ns(path->mnt); - int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0; - int rc = 0, num_aces, dacloffset, pntsd_type, acl_len; + int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0, pdacl_size; + int rc = 0, num_aces, dacloffset, pntsd_type, pntsd_size, acl_len, aces_size; char *aces_base; bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
- acl_len = ksmbd_vfs_get_sd_xattr(conn, user_ns, - parent, &parent_pntsd); - if (acl_len <= 0) + pntsd_size = ksmbd_vfs_get_sd_xattr(conn, user_ns, + parent, &parent_pntsd); + if (pntsd_size <= 0) return -ENOENT; dacloffset = le32_to_cpu(parent_pntsd->dacloffset); - if (!dacloffset) { + if (!dacloffset || (dacloffset + sizeof(struct smb_acl) > pntsd_size)) { rc = -EINVAL; goto free_parent_pntsd; }
parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset); + acl_len = pntsd_size - dacloffset; num_aces = le32_to_cpu(parent_pdacl->num_aces); pntsd_type = le16_to_cpu(parent_pntsd->type); + pdacl_size = le16_to_cpu(parent_pdacl->size); + + if (pdacl_size > acl_len || pdacl_size < sizeof(struct smb_acl)) { + rc = -EINVAL; + goto free_parent_pntsd; + }
aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, GFP_KERNEL); if (!aces_base) { @@ -1008,11 +1036,23 @@ int smb_inherit_dacl(struct ksmbd_conn * aces = (struct smb_ace *)aces_base; parent_aces = (struct smb_ace *)((char *)parent_pdacl + sizeof(struct smb_acl)); + aces_size = acl_len - sizeof(struct smb_acl);
if (pntsd_type & DACL_AUTO_INHERITED) inherited_flags = INHERITED_ACE;
for (i = 0; i < num_aces; i++) { + int pace_size; + + if (offsetof(struct smb_ace, access_req) > aces_size) + break; + + pace_size = le16_to_cpu(parent_aces->size); + if (pace_size > aces_size) + break; + + aces_size -= pace_size; + flags = parent_aces->flags; if (!smb_inherit_flags(flags, is_dir)) goto pass; @@ -1057,8 +1097,7 @@ int smb_inherit_dacl(struct ksmbd_conn * aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size)); ace_cnt++; pass: - parent_aces = - (struct smb_ace *)((char *)parent_aces + le16_to_cpu(parent_aces->size)); + parent_aces = (struct smb_ace *)((char *)parent_aces + pace_size); }
if (nt_size > 0) { @@ -1153,7 +1192,7 @@ int smb_check_perm_dacl(struct ksmbd_con struct smb_ntsd *pntsd = NULL; struct smb_acl *pdacl; struct posix_acl *posix_acls; - int rc = 0, acl_size; + int rc = 0, pntsd_size, acl_size, aces_size, pdacl_size, dacl_offset; struct smb_sid sid; int granted = le32_to_cpu(*pdaccess & ~FILE_MAXIMAL_ACCESS_LE); struct smb_ace *ace; @@ -1162,37 +1201,33 @@ int smb_check_perm_dacl(struct ksmbd_con struct smb_ace *others_ace = NULL; struct posix_acl_entry *pa_entry; unsigned int sid_type = SIDOWNER; - char *end_of_acl; + unsigned short ace_size;
ksmbd_debug(SMB, "check permission using windows acl\n"); - acl_size = ksmbd_vfs_get_sd_xattr(conn, user_ns, - path->dentry, &pntsd); - if (acl_size <= 0 || !pntsd || !pntsd->dacloffset) { - kfree(pntsd); - return 0; - } + pntsd_size = ksmbd_vfs_get_sd_xattr(conn, user_ns, + path->dentry, &pntsd); + if (pntsd_size <= 0 || !pntsd) + goto err_out; + + dacl_offset = le32_to_cpu(pntsd->dacloffset); + if (!dacl_offset || + (dacl_offset + sizeof(struct smb_acl) > pntsd_size)) + goto err_out;
pdacl = (struct smb_acl *)((char *)pntsd + le32_to_cpu(pntsd->dacloffset)); - end_of_acl = ((char *)pntsd) + acl_size; - if (end_of_acl <= (char *)pdacl) { - kfree(pntsd); - return 0; - } + acl_size = pntsd_size - dacl_offset; + pdacl_size = le16_to_cpu(pdacl->size);
- if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size) || - le16_to_cpu(pdacl->size) < sizeof(struct smb_acl)) { - kfree(pntsd); - return 0; - } + if (pdacl_size > acl_size || pdacl_size < sizeof(struct smb_acl)) + goto err_out;
if (!pdacl->num_aces) { - if (!(le16_to_cpu(pdacl->size) - sizeof(struct smb_acl)) && + if (!(pdacl_size - sizeof(struct smb_acl)) && *pdaccess & ~(FILE_READ_CONTROL_LE | FILE_WRITE_DAC_LE)) { rc = -EACCES; goto err_out; } - kfree(pntsd); - return 0; + goto err_out; }
if (*pdaccess & FILE_MAXIMAL_ACCESS_LE) { @@ -1200,11 +1235,16 @@ int smb_check_perm_dacl(struct ksmbd_con DELETE;
ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl)); + aces_size = acl_size - sizeof(struct smb_acl); for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) { + if (offsetof(struct smb_ace, access_req) > aces_size) + break; + ace_size = le16_to_cpu(ace->size); + if (ace_size > aces_size) + break; + aces_size -= ace_size; granted |= le32_to_cpu(ace->access_req); ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size)); - if (end_of_acl < (char *)ace) - goto err_out; }
if (!pdacl->num_aces) @@ -1216,7 +1256,15 @@ int smb_check_perm_dacl(struct ksmbd_con id_to_sid(uid, sid_type, &sid);
ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl)); + aces_size = acl_size - sizeof(struct smb_acl); for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) { + if (offsetof(struct smb_ace, access_req) > aces_size) + break; + ace_size = le16_to_cpu(ace->size); + if (ace_size > aces_size) + break; + aces_size -= ace_size; + if (!compare_sids(&sid, &ace->sid) || !compare_sids(&sid_unix_NFS_mode, &ace->sid)) { found = 1; @@ -1226,8 +1274,6 @@ int smb_check_perm_dacl(struct ksmbd_con others_ace = ace;
ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size)); - if (end_of_acl < (char *)ace) - goto err_out; }
if (*pdaccess & FILE_MAXIMAL_ACCESS_LE && found) { --- a/fs/ksmbd/smbacl.h +++ b/fs/ksmbd/smbacl.h @@ -193,7 +193,7 @@ struct posix_acl_state { int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd, int acl_len, struct smb_fattr *fattr); int build_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd, - struct smb_ntsd *ppntsd, int addition_info, + struct smb_ntsd *ppntsd, int ppntsd_size, int addition_info, __u32 *secdesclen, struct smb_fattr *fattr); int init_acl_state(struct posix_acl_state *state, int cnt); void free_acl_state(struct posix_acl_state *state); --- a/fs/ksmbd/vfs.c +++ b/fs/ksmbd/vfs.c @@ -1540,6 +1540,11 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_ }
*pntsd = acl.sd_buf; + if (acl.sd_size < sizeof(struct smb_ntsd)) { + pr_err("sd size is invalid\n"); + goto out_free; + } + (*pntsd)->osidoffset = cpu_to_le32(le32_to_cpu((*pntsd)->osidoffset) - NDR_NTSD_OFFSETOF); (*pntsd)->gsidoffset = cpu_to_le32(le32_to_cpu((*pntsd)->gsidoffset) -
From: Miklos Szeredi mszeredi@redhat.com
commit 47912eaa061a6a81e4aa790591a1874c650733c0 upstream.
Limit nanoseconds to 0..999999999.
Fixes: d8a5ba45457e ("[PATCH] FUSE - core") Cc: stable@vger.kernel.org Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fuse/inode.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -180,6 +180,12 @@ void fuse_change_attributes_common(struc inode->i_uid = make_kuid(fc->user_ns, attr->uid); inode->i_gid = make_kgid(fc->user_ns, attr->gid); inode->i_blocks = attr->blocks; + + /* Sanitize nsecs */ + attr->atimensec = min_t(u32, attr->atimensec, NSEC_PER_SEC - 1); + attr->mtimensec = min_t(u32, attr->mtimensec, NSEC_PER_SEC - 1); + attr->ctimensec = min_t(u32, attr->ctimensec, NSEC_PER_SEC - 1); + inode->i_atime.tv_sec = attr->atime; inode->i_atime.tv_nsec = attr->atimensec; /* mtime from server may be stale due to local buffered write */
From: Miklos Szeredi mszeredi@redhat.com
commit 02c0cab8e7345b06f1c0838df444e2902e4138d3 upstream.
Overlayfs may fail to complete updates when a filesystem lacks fileattr/xattr syscall support and responds with an ENOSYS error code, resulting in an unexpected "Function not implemented" error.
This bug may occur with FUSE filesystems, such as davfs2.
Steps to reproduce:
# install davfs2, e.g., apk add davfs2 mkdir /test mkdir /test/lower /test/upper /test/work /test/mnt yes '' | mount -t davfs -o ro http://some-web-dav-server/path \ /test/lower mount -t overlay -o upperdir=/test/upper,lowerdir=/test/lower \ -o workdir=/test/work overlay /test/mnt
# when "some-file" exists in the lowerdir, this fails with "Function # not implemented", with dmesg showing "overlayfs: failed to retrieve # lower fileattr (/some-file, err=-38)" touch /test/mnt/some-file
The underlying cause of this regresion is actually in FUSE, which fails to translate the ENOSYS error code returned by userspace filesystem (which means that the ioctl operation is not supported) to ENOTTY.
Reported-by: Christian Kohlschütter christian@kohlschutter.com Fixes: 72db82115d2b ("ovl: copy up sync/noatime fileattr flags") Fixes: 59efec7b9039 ("fuse: implement ioctl support") Cc: stable@vger.kernel.org Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fuse/ioctl.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
--- a/fs/fuse/ioctl.c +++ b/fs/fuse/ioctl.c @@ -9,6 +9,17 @@ #include <linux/compat.h> #include <linux/fileattr.h>
+static ssize_t fuse_send_ioctl(struct fuse_mount *fm, struct fuse_args *args) +{ + ssize_t ret = fuse_simple_request(fm, args); + + /* Translate ENOSYS, which shouldn't be returned from fs */ + if (ret == -ENOSYS) + ret = -ENOTTY; + + return ret; +} + /* * CUSE servers compiled on 32bit broke on 64bit kernels because the * ABI was defined to be 'struct iovec' which is different on 32bit @@ -259,7 +270,7 @@ long fuse_do_ioctl(struct file *file, un ap.args.out_pages = true; ap.args.out_argvar = true;
- transferred = fuse_simple_request(fm, &ap.args); + transferred = fuse_send_ioctl(fm, &ap.args); err = transferred; if (transferred < 0) goto out; @@ -393,7 +404,7 @@ static int fuse_priv_ioctl(struct inode args.out_args[1].size = inarg.out_size; args.out_args[1].value = ptr;
- err = fuse_simple_request(fm, &args); + err = fuse_send_ioctl(fm, &args); if (!err) { if (outarg.result < 0) err = outarg.result;
From: Miklos Szeredi mszeredi@redhat.com
commit 035ff33cf4db101250fb980a3941bf078f37a544 upstream.
A race between write(2) and close(2) allows pages to be dirtied after fuse_flush -> write_inode_now(). If these pages are not flushed from fuse_release(), then there might not be a writable open file later. So any remaining dirty pages must be written back before the file is released.
This is a partial revert of the blamed commit.
Reported-by: syzbot+6e1efbd8efaaa6860e91@syzkaller.appspotmail.com Fixes: 36ea23374d1f ("fuse: write inode in fuse_vma_close() instead of fuse_release()") Cc: stable@vger.kernel.org # v5.16 Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fuse/file.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -338,6 +338,15 @@ static int fuse_open(struct inode *inode
static int fuse_release(struct inode *inode, struct file *file) { + struct fuse_conn *fc = get_fuse_conn(inode); + + /* + * Dirty pages might remain despite write_inode_now() call from + * fuse_flush() due to writes racing with the close. + */ + if (fc->writeback_cache) + write_inode_now(inode, 1); + fuse_release_common(file, false);
/* return value is ignored by VFS */
From: Miklos Szeredi mszeredi@redhat.com
commit 2fdbb8dd01556e1501132b5ad3826e8f71e24a8b upstream.
fuse_finish_open() will be called with FUSE_NOWRITE set in case of atomic O_TRUNC open(), so commit 76224355db75 ("fuse: truncate pagecache on atomic_o_trunc") replaced invalidate_inode_pages2() by truncate_pagecache() in such a case to avoid the A-A deadlock. However, we found another A-B-B-A deadlock related to the case above, which will cause the xfstests generic/464 testcase hung in our virtio-fs test environment.
For example, consider two processes concurrently open one same file, one with O_TRUNC and another without O_TRUNC. The deadlock case is described below, if open(O_TRUNC) is already set_nowrite(acquired A), and is trying to lock a page (acquiring B), open() could have held the page lock (acquired B), and waiting on the page writeback (acquiring A). This would lead to deadlocks.
open(O_TRUNC) ---------------------------------------------------------------- fuse_open_common inode_lock [C acquire] fuse_set_nowrite [A acquire]
fuse_finish_open truncate_pagecache lock_page [B acquire] truncate_inode_page unlock_page [B release]
fuse_release_nowrite [A release] inode_unlock [C release] ----------------------------------------------------------------
open() ---------------------------------------------------------------- fuse_open_common fuse_finish_open invalidate_inode_pages2 lock_page [B acquire] fuse_launder_page fuse_wait_on_page_writeback [A acquire & release] unlock_page [B release] ----------------------------------------------------------------
Besides this case, all calls of invalidate_inode_pages2() and invalidate_inode_pages2_range() in fuse code also can deadlock with open(O_TRUNC).
Fix by moving the truncate_pagecache() call outside the nowrite protected region. The nowrite protection is only for delayed writeback (writeback_cache) case, where inode lock does not protect against truncation racing with writes on the server. Write syscalls racing with page cache truncation still get the inode lock protection.
This patch also changes the order of filemap_invalidate_lock() vs. fuse_set_nowrite() in fuse_open_common(). This new order matches the order found in fuse_file_fallocate() and fuse_do_setattr().
Reported-by: Jiachen Zhang zhangjiachen.jaycee@bytedance.com Tested-by: Jiachen Zhang zhangjiachen.jaycee@bytedance.com Fixes: e4648309b85a ("fuse: truncate pending writes on O_TRUNC") Cc: stable@vger.kernel.org Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fuse/dir.c | 7 ++++++- fs/fuse/file.c | 30 +++++++++++++++++------------- 2 files changed, 23 insertions(+), 14 deletions(-)
--- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -537,6 +537,7 @@ static int fuse_create_open(struct inode struct fuse_file *ff; void *security_ctx = NULL; u32 security_ctxlen; + bool trunc = flags & O_TRUNC;
/* Userspace expects S_IFREG in create mode */ BUG_ON((mode & S_IFMT) != S_IFREG); @@ -561,7 +562,7 @@ static int fuse_create_open(struct inode inarg.mode = mode; inarg.umask = current_umask();
- if (fm->fc->handle_killpriv_v2 && (flags & O_TRUNC) && + if (fm->fc->handle_killpriv_v2 && trunc && !(flags & O_EXCL) && !capable(CAP_FSETID)) { inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID; } @@ -623,6 +624,10 @@ static int fuse_create_open(struct inode } else { file->private_data = ff; fuse_finish_open(inode, file); + if (fm->fc->atomic_o_trunc && trunc) + truncate_pagecache(inode, 0); + else if (!(ff->open_flags & FOPEN_KEEP_CACHE)) + invalidate_inode_pages2(inode->i_mapping); } return err;
--- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -210,13 +210,9 @@ void fuse_finish_open(struct inode *inod fi->attr_version = atomic64_inc_return(&fc->attr_version); i_size_write(inode, 0); spin_unlock(&fi->lock); - truncate_pagecache(inode, 0); file_update_time(file); fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE); - } else if (!(ff->open_flags & FOPEN_KEEP_CACHE)) { - invalidate_inode_pages2(inode->i_mapping); } - if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache) fuse_link_write_file(file); } @@ -239,30 +235,38 @@ int fuse_open_common(struct inode *inode if (err) return err;
- if (is_wb_truncate || dax_truncate) { + if (is_wb_truncate || dax_truncate) inode_lock(inode); - fuse_set_nowrite(inode); - }
if (dax_truncate) { filemap_invalidate_lock(inode->i_mapping); err = fuse_dax_break_layouts(inode, 0, 0); if (err) - goto out; + goto out_inode_unlock; }
+ if (is_wb_truncate || dax_truncate) + fuse_set_nowrite(inode); + err = fuse_do_open(fm, get_node_id(inode), file, isdir); if (!err) fuse_finish_open(inode, file);
-out: + if (is_wb_truncate || dax_truncate) + fuse_release_nowrite(inode); + if (!err) { + struct fuse_file *ff = file->private_data; + + if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) + truncate_pagecache(inode, 0); + else if (!(ff->open_flags & FOPEN_KEEP_CACHE)) + invalidate_inode_pages2(inode->i_mapping); + } if (dax_truncate) filemap_invalidate_unlock(inode->i_mapping); - - if (is_wb_truncate | dax_truncate) { - fuse_release_nowrite(inode); +out_inode_unlock: + if (is_wb_truncate || dax_truncate) inode_unlock(inode); - }
return err; }
From: Narendra Hadke nhadke@marvell.com
commit a7209541239e5dd44d981289e5f9059222d40fd1 upstream.
For mvebu uart2, error bits are not cleared on buffer read. This causes interrupt loop and system hang.
Cc: stable@vger.kernel.org Reviewed-by: Yi Guo yi.guo@cavium.com Reviewed-by: Nadav Haklai nadavh@marvell.com Signed-off-by: Narendra Hadke nhadke@marvell.com Signed-off-by: Pali Rohár pali@kernel.org Link: https://lore.kernel.org/r/20220726091221.12358-1-pali@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/mvebu-uart.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 0429c2a54290..ff61a8d00014 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -265,6 +265,7 @@ static void mvebu_uart_rx_chars(struct uart_port *port, unsigned int status) struct tty_port *tport = &port->state->port; unsigned char ch = 0; char flag = 0; + int ret;
do { if (status & STAT_RX_RDY(port)) { @@ -277,6 +278,16 @@ static void mvebu_uart_rx_chars(struct uart_port *port, unsigned int status) port->icount.parity++; }
+ /* + * For UART2, error bits are not cleared on buffer read. + * This causes interrupt loop and system hang. + */ + if (IS_EXTENDED(port) && (status & STAT_BRK_ERR)) { + ret = readl(port->membase + UART_STAT); + ret |= STAT_BRK_ERR; + writel(ret, port->membase + UART_STAT); + } + if (status & STAT_BRK_DET) { port->icount.brk++; status &= ~(STAT_FRM_ERR | STAT_PAR_ERR);
From: Mikulas Patocka mpatocka@redhat.com
commit e151db8ecfb019b7da31d076130a794574c89f6f upstream.
When we ran the lvm test "shell/integrity-blocksize-3.sh" on a kernel with kasan, we got failure in write_page.
The reason for the failure is that md_bitmap_destroy is called before destroying the thread and the thread may be waiting in the function write_page for the bio to complete. When the thread finishes waiting, it executes "if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))", which triggers the kasan warning.
Note that the commit 48df498daf62 that caused this bug claims that it is neede for md-cluster, you should check md-cluster and possibly find another bugfix for it.
BUG: KASAN: use-after-free in write_page+0x18d/0x680 [md_mod] Read of size 8 at addr ffff889162030c78 by task mdX_raid1/5539
CPU: 10 PID: 5539 Comm: mdX_raid1 Not tainted 5.19.0-rc2 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x34/0x44 print_report.cold+0x45/0x57a ? __lock_text_start+0x18/0x18 ? write_page+0x18d/0x680 [md_mod] kasan_report+0xa8/0xe0 ? write_page+0x18d/0x680 [md_mod] kasan_check_range+0x13f/0x180 write_page+0x18d/0x680 [md_mod] ? super_sync+0x4d5/0x560 [dm_raid] ? md_bitmap_file_kick+0xa0/0xa0 [md_mod] ? rs_set_dev_and_array_sectors+0x2e0/0x2e0 [dm_raid] ? mutex_trylock+0x120/0x120 ? preempt_count_add+0x6b/0xc0 ? preempt_count_sub+0xf/0xc0 md_update_sb+0x707/0xe40 [md_mod] md_reap_sync_thread+0x1b2/0x4a0 [md_mod] md_check_recovery+0x533/0x960 [md_mod] raid1d+0xc8/0x2a20 [raid1] ? var_wake_function+0xe0/0xe0 ? psi_group_change+0x411/0x500 ? preempt_count_sub+0xf/0xc0 ? _raw_spin_lock_irqsave+0x78/0xc0 ? __lock_text_start+0x18/0x18 ? raid1_end_read_request+0x2a0/0x2a0 [raid1] ? preempt_count_sub+0xf/0xc0 ? _raw_spin_unlock_irqrestore+0x19/0x40 ? del_timer_sync+0xa9/0x100 ? try_to_del_timer_sync+0xc0/0xc0 ? _raw_spin_lock_irqsave+0x78/0xc0 ? __lock_text_start+0x18/0x18 ? __list_del_entry_valid+0x68/0xa0 ? finish_wait+0xa3/0x100 md_thread+0x161/0x260 [md_mod] ? unregister_md_personality+0xa0/0xa0 [md_mod] ? _raw_spin_lock_irqsave+0x78/0xc0 ? prepare_to_wait_event+0x2c0/0x2c0 ? unregister_md_personality+0xa0/0xa0 [md_mod] kthread+0x148/0x180 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x1f/0x30 </TASK>
Allocated by task 5522: kasan_save_stack+0x1e/0x40 __kasan_kmalloc+0x80/0xa0 md_bitmap_create+0xa8/0xe80 [md_mod] md_run+0x777/0x1300 [md_mod] raid_ctr+0x249c/0x4a30 [dm_raid] dm_table_add_target+0x2b0/0x620 [dm_mod] table_load+0x1c8/0x400 [dm_mod] ctl_ioctl+0x29e/0x560 [dm_mod] dm_compat_ctl_ioctl+0x7/0x20 [dm_mod] __do_compat_sys_ioctl+0xfa/0x160 do_syscall_64+0x90/0xc0 entry_SYSCALL_64_after_hwframe+0x46/0xb0
Freed by task 5680: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x40 kasan_set_free_info+0x20/0x40 __kasan_slab_free+0xf7/0x140 kfree+0x80/0x240 md_bitmap_free+0x1c3/0x280 [md_mod] __md_stop+0x21/0x120 [md_mod] md_stop+0x9/0x40 [md_mod] raid_dtr+0x1b/0x40 [dm_raid] dm_table_destroy+0x98/0x1e0 [dm_mod] __dm_destroy+0x199/0x360 [dm_mod] dev_remove+0x10c/0x160 [dm_mod] ctl_ioctl+0x29e/0x560 [dm_mod] dm_compat_ctl_ioctl+0x7/0x20 [dm_mod] __do_compat_sys_ioctl+0xfa/0x160 do_syscall_64+0x90/0xc0 entry_SYSCALL_64_after_hwframe+0x46/0xb0
Signed-off-by: Mikulas Patocka mpatocka@redhat.com Cc: stable@vger.kernel.org Fixes: 48df498daf62 ("md: move bitmap_destroy to the beginning of __md_stop") Signed-off-by: Song Liu song@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/md.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6244,11 +6244,11 @@ static void mddev_detach(struct mddev *m static void __md_stop(struct mddev *mddev) { struct md_personality *pers = mddev->pers; - md_bitmap_destroy(mddev); mddev_detach(mddev); /* Ensure ->event_work is done */ if (mddev->event_work.func) flush_workqueue(md_misc_wq); + md_bitmap_destroy(mddev); spin_lock(&mddev->lock); mddev->pers = NULL; spin_unlock(&mddev->lock);
From: Mikulas Patocka mpatocka@redhat.com
commit d17f744e883b2f8d13cca252d71cfe8ace346f7d upstream.
There's a KASAN warning in raid10_remove_disk when running the lvm test lvconvert-raid-reshape.sh. We fix this warning by verifying that the value "number" is valid.
BUG: KASAN: slab-out-of-bounds in raid10_remove_disk+0x61/0x2a0 [raid10] Read of size 8 at addr ffff889108f3d300 by task mdX_raid10/124682
CPU: 3 PID: 124682 Comm: mdX_raid10 Not tainted 5.19.0-rc6 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x34/0x44 print_report.cold+0x45/0x57a ? __lock_text_start+0x18/0x18 ? raid10_remove_disk+0x61/0x2a0 [raid10] kasan_report+0xa8/0xe0 ? raid10_remove_disk+0x61/0x2a0 [raid10] raid10_remove_disk+0x61/0x2a0 [raid10] Buffer I/O error on dev dm-76, logical block 15344, async page read ? __mutex_unlock_slowpath.constprop.0+0x1e0/0x1e0 remove_and_add_spares+0x367/0x8a0 [md_mod] ? super_written+0x1c0/0x1c0 [md_mod] ? mutex_trylock+0xac/0x120 ? _raw_spin_lock+0x72/0xc0 ? _raw_spin_lock_bh+0xc0/0xc0 md_check_recovery+0x848/0x960 [md_mod] raid10d+0xcf/0x3360 [raid10] ? sched_clock_cpu+0x185/0x1a0 ? rb_erase+0x4d4/0x620 ? var_wake_function+0xe0/0xe0 ? psi_group_change+0x411/0x500 ? preempt_count_sub+0xf/0xc0 ? _raw_spin_lock_irqsave+0x78/0xc0 ? __lock_text_start+0x18/0x18 ? raid10_sync_request+0x36c0/0x36c0 [raid10] ? preempt_count_sub+0xf/0xc0 ? _raw_spin_unlock_irqrestore+0x19/0x40 ? del_timer_sync+0xa9/0x100 ? try_to_del_timer_sync+0xc0/0xc0 ? _raw_spin_lock_irqsave+0x78/0xc0 ? __lock_text_start+0x18/0x18 ? _raw_spin_unlock_irq+0x11/0x24 ? __list_del_entry_valid+0x68/0xa0 ? finish_wait+0xa3/0x100 md_thread+0x161/0x260 [md_mod] ? unregister_md_personality+0xa0/0xa0 [md_mod] ? _raw_spin_lock_irqsave+0x78/0xc0 ? prepare_to_wait_event+0x2c0/0x2c0 ? unregister_md_personality+0xa0/0xa0 [md_mod] kthread+0x148/0x180 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x1f/0x30 </TASK>
Allocated by task 124495: kasan_save_stack+0x1e/0x40 __kasan_kmalloc+0x80/0xa0 setup_conf+0x140/0x5c0 [raid10] raid10_run+0x4cd/0x740 [raid10] md_run+0x6f9/0x1300 [md_mod] raid_ctr+0x2531/0x4ac0 [dm_raid] dm_table_add_target+0x2b0/0x620 [dm_mod] table_load+0x1c8/0x400 [dm_mod] ctl_ioctl+0x29e/0x560 [dm_mod] dm_compat_ctl_ioctl+0x7/0x20 [dm_mod] __do_compat_sys_ioctl+0xfa/0x160 do_syscall_64+0x90/0xc0 entry_SYSCALL_64_after_hwframe+0x46/0xb0
Last potentially related work creation: kasan_save_stack+0x1e/0x40 __kasan_record_aux_stack+0x9e/0xc0 kvfree_call_rcu+0x84/0x480 timerfd_release+0x82/0x140 L __fput+0xfa/0x400 task_work_run+0x80/0xc0 exit_to_user_mode_prepare+0x155/0x160 syscall_exit_to_user_mode+0x12/0x40 do_syscall_64+0x42/0xc0 entry_SYSCALL_64_after_hwframe+0x46/0xb0
Second to last potentially related work creation: kasan_save_stack+0x1e/0x40 __kasan_record_aux_stack+0x9e/0xc0 kvfree_call_rcu+0x84/0x480 timerfd_release+0x82/0x140 __fput+0xfa/0x400 task_work_run+0x80/0xc0 exit_to_user_mode_prepare+0x155/0x160 syscall_exit_to_user_mode+0x12/0x40 do_syscall_64+0x42/0xc0 entry_SYSCALL_64_after_hwframe+0x46/0xb0
The buggy address belongs to the object at ffff889108f3d200 which belongs to the cache kmalloc-256 of size 256 The buggy address is located 0 bytes to the right of 256-byte region [ffff889108f3d200, ffff889108f3d300)
The buggy address belongs to the physical page: page:000000007ef2a34c refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1108f3c head:000000007ef2a34c order:2 compound_mapcount:0 compound_pincount:0 flags: 0x4000000000010200(slab|head|zone=2) raw: 4000000000010200 0000000000000000 dead000000000001 ffff889100042b40 raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff889108f3d200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff889108f3d280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff889108f3d300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
^ ffff889108f3d380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff889108f3d400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Signed-off-by: Mikulas Patocka mpatocka@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Song Liu song@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/raid10.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2167,9 +2167,12 @@ static int raid10_remove_disk(struct mdd int err = 0; int number = rdev->raid_disk; struct md_rdev **rdevp; - struct raid10_info *p = conf->mirrors + number; + struct raid10_info *p;
print_conf(conf); + if (unlikely(number >= mddev->raid_disks)) + return 0; + p = conf->mirrors + number; if (rdev == p->rdev) rdevp = &p->rdev; else if (rdev == p->replacement)
From: Jan Kara jack@suse.cz
commit 58318914186c157477b978b1739dfe2f1b9dc0fe upstream.
Do not reclaim entries that are currently used by somebody from a shrinker. Firstly, these entries are likely useful. Secondly, we will need to keep such entries to protect pending increment of xattr block refcount.
CC: stable@vger.kernel.org Fixes: 82939d7999df ("ext4: convert to mbcache2") Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220712105436.32204-1-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/mbcache.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
--- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -288,7 +288,7 @@ static unsigned long mb_cache_shrink(str while (nr_to_scan-- && !list_empty(&cache->c_list)) { entry = list_first_entry(&cache->c_list, struct mb_cache_entry, e_list); - if (entry->e_referenced) { + if (entry->e_referenced || atomic_read(&entry->e_refcnt) > 2) { entry->e_referenced = 0; list_move_tail(&entry->e_list, &cache->c_list); continue; @@ -302,6 +302,14 @@ static unsigned long mb_cache_shrink(str spin_unlock(&cache->c_list_lock); head = mb_cache_entry_head(cache, entry->e_key); hlist_bl_lock(head); + /* Now a reliable check if the entry didn't get used... */ + if (atomic_read(&entry->e_refcnt) > 2) { + hlist_bl_unlock(head); + spin_lock(&cache->c_list_lock); + list_add_tail(&entry->e_list, &cache->c_list); + cache->c_entry_count++; + continue; + } if (!hlist_bl_unhashed(&entry->e_hash_list)) { hlist_bl_del_init(&entry->e_hash_list); atomic_dec(&entry->e_refcnt);
From: Jan Kara jack@suse.cz
commit 3dc96bba65f53daa217f0a8f43edad145286a8f5 upstream.
Add function mb_cache_entry_delete_or_get() to delete mbcache entry if it is unused and also add a function to wait for entry to become unused - mb_cache_entry_wait_unused(). We do not share code between the two deleting function as one of them will go away soon.
CC: stable@vger.kernel.org Fixes: 82939d7999df ("ext4: convert to mbcache2") Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220712105436.32204-2-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/mbcache.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++-- include/linux/mbcache.h | 10 ++++++- 2 files changed, 73 insertions(+), 3 deletions(-)
--- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -11,7 +11,7 @@ /* * Mbcache is a simple key-value store. Keys need not be unique, however * key-value pairs are expected to be unique (we use this fact in - * mb_cache_entry_delete()). + * mb_cache_entry_delete_or_get()). * * Ext2 and ext4 use this cache for deduplication of extended attribute blocks. * Ext4 also uses it for deduplication of xattr values stored in inodes. @@ -125,6 +125,19 @@ void __mb_cache_entry_free(struct mb_cac } EXPORT_SYMBOL(__mb_cache_entry_free);
+/* + * mb_cache_entry_wait_unused - wait to be the last user of the entry + * + * @entry - entry to work on + * + * Wait to be the last user of the entry. + */ +void mb_cache_entry_wait_unused(struct mb_cache_entry *entry) +{ + wait_var_event(&entry->e_refcnt, atomic_read(&entry->e_refcnt) <= 3); +} +EXPORT_SYMBOL(mb_cache_entry_wait_unused); + static struct mb_cache_entry *__entry_find(struct mb_cache *cache, struct mb_cache_entry *entry, u32 key) @@ -217,7 +230,7 @@ out: } EXPORT_SYMBOL(mb_cache_entry_get);
-/* mb_cache_entry_delete - remove a cache entry +/* mb_cache_entry_delete - try to remove a cache entry * @cache - cache we work with * @key - key * @value - value @@ -254,6 +267,55 @@ void mb_cache_entry_delete(struct mb_cac } EXPORT_SYMBOL(mb_cache_entry_delete);
+/* mb_cache_entry_delete_or_get - remove a cache entry if it has no users + * @cache - cache we work with + * @key - key + * @value - value + * + * Remove entry from cache @cache with key @key and value @value. The removal + * happens only if the entry is unused. The function returns NULL in case the + * entry was successfully removed or there's no entry in cache. Otherwise the + * function grabs reference of the entry that we failed to delete because it + * still has users and return it. + */ +struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache, + u32 key, u64 value) +{ + struct hlist_bl_node *node; + struct hlist_bl_head *head; + struct mb_cache_entry *entry; + + head = mb_cache_entry_head(cache, key); + hlist_bl_lock(head); + hlist_bl_for_each_entry(entry, node, head, e_hash_list) { + if (entry->e_key == key && entry->e_value == value) { + if (atomic_read(&entry->e_refcnt) > 2) { + atomic_inc(&entry->e_refcnt); + hlist_bl_unlock(head); + return entry; + } + /* We keep hash list reference to keep entry alive */ + hlist_bl_del_init(&entry->e_hash_list); + hlist_bl_unlock(head); + spin_lock(&cache->c_list_lock); + if (!list_empty(&entry->e_list)) { + list_del_init(&entry->e_list); + if (!WARN_ONCE(cache->c_entry_count == 0, + "mbcache: attempt to decrement c_entry_count past zero")) + cache->c_entry_count--; + atomic_dec(&entry->e_refcnt); + } + spin_unlock(&cache->c_list_lock); + mb_cache_entry_put(cache, entry); + return NULL; + } + } + hlist_bl_unlock(head); + + return NULL; +} +EXPORT_SYMBOL(mb_cache_entry_delete_or_get); + /* mb_cache_entry_touch - cache entry got used * @cache - cache the entry belongs to * @entry - entry that got used --- a/include/linux/mbcache.h +++ b/include/linux/mbcache.h @@ -30,15 +30,23 @@ void mb_cache_destroy(struct mb_cache *c int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key, u64 value, bool reusable); void __mb_cache_entry_free(struct mb_cache_entry *entry); +void mb_cache_entry_wait_unused(struct mb_cache_entry *entry); static inline int mb_cache_entry_put(struct mb_cache *cache, struct mb_cache_entry *entry) { - if (!atomic_dec_and_test(&entry->e_refcnt)) + unsigned int cnt = atomic_dec_return(&entry->e_refcnt); + + if (cnt > 0) { + if (cnt <= 3) + wake_up_var(&entry->e_refcnt); return 0; + } __mb_cache_entry_free(entry); return 1; }
+struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache, + u32 key, u64 value); void mb_cache_entry_delete(struct mb_cache *cache, u32 key, u64 value); struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *cache, u32 key, u64 value);
From: Randy Dunlap rdunlap@infradead.org
commit 81e005842d0b8167c059553a1c29c36d8a7a9329 upstream.
Fix build error when VIDEO_ISL7998X=y and V4L2_FWNODE=m by selecting V4L2_FWNODE.
microblaze-linux-ld: drivers/media/i2c/isl7998x.o: in function `isl7998x_probe': (.text+0x8f4): undefined reference to `v4l2_fwnode_endpoint_parse'
Cc: stable@vger.kernel.org # 5.18 and above Fixes: 51ef2be546e2 ("media: i2c: isl7998x: Add driver for Intersil ISL7998x") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Cc: Marek Vasut marex@denx.de Cc: Pengutronix Kernel Team kernel@pengutronix.de Reviewed-by: Michael Tretter m.tretter@pengutronix.de Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/i2c/Kconfig | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -1178,6 +1178,7 @@ config VIDEO_ISL7998X depends on OF_GPIO select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API + select V4L2_FWNODE help Support for Intersil ISL7998x analog to MIPI-CSI2 or BT.656 decoder.
From: Xiaomeng Tong xiam0nd.tong@gmail.com
commit 09b204eb9de9fdf07d028c41c4331b5cfeb70dd7 upstream.
The three bugs are here: __func__, s3a_buf->s3a_data->exp_id); __func__, md_buf->metadata->exp_id); __func__, dis_buf->dis_data->exp_id);
The list iterator 's3a_buf/md_buf/dis_buf' will point to a bogus position containing HEAD if the list is empty or no element is found. This case must be checked before any use of the iterator, otherwise it will lead to a invalid memory access.
To fix this bug, add an check. Use a new variable '*_iter' as the list iterator, while use the old variable '*_buf' as a dedicated pointer to point to the found element.
Link: https://lore.kernel.org/linux-media/20220414041415.3342-1-xiam0nd.tong@gmail... Cc: stable@vger.kernel.org Fixes: ad85094b293e4 ("Revert "media: staging: atomisp: Remove driver"") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/media/atomisp/pci/atomisp_cmd.c | 57 +++++++++++++++--------- 1 file changed, 36 insertions(+), 21 deletions(-)
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -901,9 +901,9 @@ void atomisp_buf_done(struct atomisp_sub int err; unsigned long irqflags; struct ia_css_frame *frame = NULL; - struct atomisp_s3a_buf *s3a_buf = NULL, *_s3a_buf_tmp; - struct atomisp_dis_buf *dis_buf = NULL, *_dis_buf_tmp; - struct atomisp_metadata_buf *md_buf = NULL, *_md_buf_tmp; + struct atomisp_s3a_buf *s3a_buf = NULL, *_s3a_buf_tmp, *s3a_iter; + struct atomisp_dis_buf *dis_buf = NULL, *_dis_buf_tmp, *dis_iter; + struct atomisp_metadata_buf *md_buf = NULL, *_md_buf_tmp, *md_iter; enum atomisp_metadata_type md_type; struct atomisp_device *isp = asd->isp; struct v4l2_control ctrl; @@ -942,60 +942,75 @@ void atomisp_buf_done(struct atomisp_sub
switch (buf_type) { case IA_CSS_BUFFER_TYPE_3A_STATISTICS: - list_for_each_entry_safe(s3a_buf, _s3a_buf_tmp, + list_for_each_entry_safe(s3a_iter, _s3a_buf_tmp, &asd->s3a_stats_in_css, list) { - if (s3a_buf->s3a_data == + if (s3a_iter->s3a_data == buffer.css_buffer.data.stats_3a) { - list_del_init(&s3a_buf->list); - list_add_tail(&s3a_buf->list, + list_del_init(&s3a_iter->list); + list_add_tail(&s3a_iter->list, &asd->s3a_stats_ready); + s3a_buf = s3a_iter; break; } }
asd->s3a_bufs_in_css[css_pipe_id]--; atomisp_3a_stats_ready_event(asd, buffer.css_buffer.exp_id); - dev_dbg(isp->dev, "%s: s3a stat with exp_id %d is ready\n", - __func__, s3a_buf->s3a_data->exp_id); + if (s3a_buf) + dev_dbg(isp->dev, "%s: s3a stat with exp_id %d is ready\n", + __func__, s3a_buf->s3a_data->exp_id); + else + dev_dbg(isp->dev, "%s: s3a stat is ready with no exp_id found\n", + __func__); break; case IA_CSS_BUFFER_TYPE_METADATA: if (error) break;
md_type = atomisp_get_metadata_type(asd, css_pipe_id); - list_for_each_entry_safe(md_buf, _md_buf_tmp, + list_for_each_entry_safe(md_iter, _md_buf_tmp, &asd->metadata_in_css[md_type], list) { - if (md_buf->metadata == + if (md_iter->metadata == buffer.css_buffer.data.metadata) { - list_del_init(&md_buf->list); - list_add_tail(&md_buf->list, + list_del_init(&md_iter->list); + list_add_tail(&md_iter->list, &asd->metadata_ready[md_type]); + md_buf = md_iter; break; } } asd->metadata_bufs_in_css[stream_id][css_pipe_id]--; atomisp_metadata_ready_event(asd, md_type); - dev_dbg(isp->dev, "%s: metadata with exp_id %d is ready\n", - __func__, md_buf->metadata->exp_id); + if (md_buf) + dev_dbg(isp->dev, "%s: metadata with exp_id %d is ready\n", + __func__, md_buf->metadata->exp_id); + else + dev_dbg(isp->dev, "%s: metadata is ready with no exp_id found\n", + __func__); break; case IA_CSS_BUFFER_TYPE_DIS_STATISTICS: - list_for_each_entry_safe(dis_buf, _dis_buf_tmp, + list_for_each_entry_safe(dis_iter, _dis_buf_tmp, &asd->dis_stats_in_css, list) { - if (dis_buf->dis_data == + if (dis_iter->dis_data == buffer.css_buffer.data.stats_dvs) { spin_lock_irqsave(&asd->dis_stats_lock, irqflags); - list_del_init(&dis_buf->list); - list_add(&dis_buf->list, &asd->dis_stats); + list_del_init(&dis_iter->list); + list_add(&dis_iter->list, &asd->dis_stats); asd->params.dis_proj_data_valid = true; spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags); + dis_buf = dis_iter; break; } } asd->dis_bufs_in_css--; - dev_dbg(isp->dev, "%s: dis stat with exp_id %d is ready\n", - __func__, dis_buf->dis_data->exp_id); + if (dis_buf) + dev_dbg(isp->dev, "%s: dis stat with exp_id %d is ready\n", + __func__, dis_buf->dis_data->exp_id); + else + dev_dbg(isp->dev, "%s: dis stat is ready with no exp_id found\n", + __func__); break; case IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME: case IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME:
From: Alexander Lobakin alexandr.lobakin@intel.com
commit e5a16a5c4602c119262f350274021f90465f479d upstream.
test_bit(), as any other bitmap op, takes `unsigned long *` as a second argument (pointer to the actual bitmap), as any bitmap itself is an array of unsigned longs. However, the ia64_get_irr() code passes a ref to `u64` as a second argument. This works with the ia64 bitops implementation due to that they have `void *` as the second argument and then cast it later on. This works with the bitmap API itself due to that `unsigned long` has the same size on ia64 as `u64` (`unsigned long long`), but from the compiler PoV those two are different. Define @irr as `unsigned long` to fix that. That implies no functional changes. Has been hidden for 16 years!
Fixes: a58786917ce2 ("[IA64] avoid broken SAL_CACHE_FLUSH implementations") Cc: stable@vger.kernel.org # 2.6.16+ Reported-by: kernel test robot lkp@intel.com Signed-off-by: Alexander Lobakin alexandr.lobakin@intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Reviewed-by: Yury Norov yury.norov@gmail.com Signed-off-by: Yury Norov yury.norov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/ia64/include/asm/processor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/ia64/include/asm/processor.h +++ b/arch/ia64/include/asm/processor.h @@ -538,7 +538,7 @@ ia64_get_irr(unsigned int vector) { unsigned int reg = vector / 64; unsigned int bit = vector % 64; - u64 irr; + unsigned long irr;
switch (reg) { case 0: irr = ia64_getreg(_IA64_REG_CR_IRR0); break;
From: Christophe Leroy christophe.leroy@csgroup.eu
commit 92f89ec1b534b6eca2b81bae97d30a786932f51a upstream.
Commit f9b3cd245784 ("Kconfig.debug: make DEBUG_INFO selectable from a choice") broke the selection of CONFIG_DEBUG_INFO by powerpc defconfigs.
It is now necessary to select one of the three DEBUG_INFO_DWARF* options to get DEBUG_INFO enabled.
Replace DEBUG_INFO=y by DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y in all defconfigs using the following command:
sed -i s/DEBUG_INFO=y/DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y/g `git grep -l DEBUG_INFO arch/powerpc/configs/`
Fixes: f9b3cd245784 ("Kconfig.debug: make DEBUG_INFO selectable from a choice") Cc: stable@vger.kernel.org Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/98a4c2603bf9e4b776e219f5b8541d23aa24e854.165493030... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/configs/44x/akebono_defconfig | 2 +- arch/powerpc/configs/44x/currituck_defconfig | 2 +- arch/powerpc/configs/44x/fsp2_defconfig | 2 +- arch/powerpc/configs/44x/iss476-smp_defconfig | 2 +- arch/powerpc/configs/44x/warp_defconfig | 2 +- arch/powerpc/configs/52xx/lite5200b_defconfig | 2 +- arch/powerpc/configs/52xx/motionpro_defconfig | 2 +- arch/powerpc/configs/52xx/tqm5200_defconfig | 2 +- arch/powerpc/configs/adder875_defconfig | 2 +- arch/powerpc/configs/ep8248e_defconfig | 2 +- arch/powerpc/configs/ep88xc_defconfig | 2 +- arch/powerpc/configs/fsl-emb-nonhw.config | 2 +- arch/powerpc/configs/mgcoge_defconfig | 2 +- arch/powerpc/configs/mpc5200_defconfig | 2 +- arch/powerpc/configs/mpc8272_ads_defconfig | 2 +- arch/powerpc/configs/mpc885_ads_defconfig | 2 +- arch/powerpc/configs/ppc6xx_defconfig | 2 +- arch/powerpc/configs/pq2fads_defconfig | 2 +- arch/powerpc/configs/ps3_defconfig | 2 +- arch/powerpc/configs/tqm8xx_defconfig | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-)
--- a/arch/powerpc/configs/44x/akebono_defconfig +++ b/arch/powerpc/configs/44x/akebono_defconfig @@ -118,7 +118,7 @@ CONFIG_CRAMFS=y CONFIG_NLS_DEFAULT="n" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_XMON=y --- a/arch/powerpc/configs/44x/currituck_defconfig +++ b/arch/powerpc/configs/44x/currituck_defconfig @@ -73,7 +73,7 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_NLS_DEFAULT="n" -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_XMON=y --- a/arch/powerpc/configs/44x/fsp2_defconfig +++ b/arch/powerpc/configs/44x/fsp2_defconfig @@ -110,7 +110,7 @@ CONFIG_XZ_DEC=y CONFIG_PRINTK_TIME=y CONFIG_MESSAGE_LOGLEVEL_DEFAULT=3 CONFIG_DYNAMIC_DEBUG=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_CRYPTO_CBC=y --- a/arch/powerpc/configs/44x/iss476-smp_defconfig +++ b/arch/powerpc/configs/44x/iss476-smp_defconfig @@ -56,7 +56,7 @@ CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_CRAMFS=y # CONFIG_NETWORK_FILESYSTEMS is not set -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_PPC_EARLY_DEBUG=y --- a/arch/powerpc/configs/44x/warp_defconfig +++ b/arch/powerpc/configs/44x/warp_defconfig @@ -88,7 +88,7 @@ CONFIG_NLS_UTF8=y CONFIG_CRC_CCITT=y CONFIG_CRC_T10DIF=y CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y --- a/arch/powerpc/configs/52xx/lite5200b_defconfig +++ b/arch/powerpc/configs/52xx/lite5200b_defconfig @@ -58,6 +58,6 @@ CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set --- a/arch/powerpc/configs/52xx/motionpro_defconfig +++ b/arch/powerpc/configs/52xx/motionpro_defconfig @@ -84,7 +84,7 @@ CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_CRYPTO_ECB=y --- a/arch/powerpc/configs/52xx/tqm5200_defconfig +++ b/arch/powerpc/configs/52xx/tqm5200_defconfig @@ -85,7 +85,7 @@ CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_CRYPTO_ECB=y --- a/arch/powerpc/configs/adder875_defconfig +++ b/arch/powerpc/configs/adder875_defconfig @@ -45,7 +45,7 @@ CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_CRC32_SLICEBY4=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y --- a/arch/powerpc/configs/ep8248e_defconfig +++ b/arch/powerpc/configs/ep8248e_defconfig @@ -59,7 +59,7 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y CONFIG_NLS_UTF8=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_MAGIC_SYSRQ=y # CONFIG_SCHED_DEBUG is not set CONFIG_BDI_SWITCH=y --- a/arch/powerpc/configs/ep88xc_defconfig +++ b/arch/powerpc/configs/ep88xc_defconfig @@ -48,6 +48,6 @@ CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_CRC32_SLICEBY4=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y --- a/arch/powerpc/configs/fsl-emb-nonhw.config +++ b/arch/powerpc/configs/fsl-emb-nonhw.config @@ -24,7 +24,7 @@ CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_DEBUG_FS=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_HUNG_TASK=y --- a/arch/powerpc/configs/mgcoge_defconfig +++ b/arch/powerpc/configs/mgcoge_defconfig @@ -73,7 +73,7 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y CONFIG_NLS_UTF8=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y # CONFIG_SCHED_DEBUG is not set --- a/arch/powerpc/configs/mpc5200_defconfig +++ b/arch/powerpc/configs/mpc5200_defconfig @@ -122,6 +122,6 @@ CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y --- a/arch/powerpc/configs/mpc8272_ads_defconfig +++ b/arch/powerpc/configs/mpc8272_ads_defconfig @@ -67,7 +67,7 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y CONFIG_NLS_UTF8=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_BDI_SWITCH=y --- a/arch/powerpc/configs/mpc885_ads_defconfig +++ b/arch/powerpc/configs/mpc885_ads_defconfig @@ -71,7 +71,7 @@ CONFIG_ROOT_NFS=y CONFIG_CRYPTO=y CONFIG_CRYPTO_DEV_TALITOS=y CONFIG_CRC32_SLICEBY4=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y CONFIG_DEBUG_VM_PGTABLE=y --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -1065,7 +1065,7 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_HEADERS_INSTALL=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y --- a/arch/powerpc/configs/pq2fads_defconfig +++ b/arch/powerpc/configs/pq2fads_defconfig @@ -68,7 +68,7 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y CONFIG_NLS_UTF8=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig @@ -153,7 +153,7 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_CRC_CCITT=m CONFIG_CRC_T10DIF=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_STACKOVERFLOW=y --- a/arch/powerpc/configs/tqm8xx_defconfig +++ b/arch/powerpc/configs/tqm8xx_defconfig @@ -55,6 +55,6 @@ CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_CRC32_SLICEBY4=y -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y
From: Christophe Leroy christophe.leroy@csgroup.eu
commit 09317643117ade87c03158341e87466413fa8f1a upstream.
With KUAP, the TLB miss handler bails out when an access to user memory is performed with a nul TID.
But the normal TLB miss routine which is only used early during boot does the check regardless for all memory areas, not only user memory.
By chance there is no early IO or vmalloc access, but when KASAN come we will start having early TLB misses.
Fix it by creating a special branch for user accesses similar to the one in the 'bolted' TLB miss handlers. Unfortunately SPRN_MAS1 is now read too early and there are no registers available to preserve it so it will be read a second time.
Fixes: 57bc963837f5 ("powerpc/kuap: Wire-up KUAP on book3e/64") Cc: stable@vger.kernel.org Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/8d6c5859a45935d6e1a336da4dc20be421e8cea7.165642770... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/mm/nohash/tlb_low_64e.S | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
--- a/arch/powerpc/mm/nohash/tlb_low_64e.S +++ b/arch/powerpc/mm/nohash/tlb_low_64e.S @@ -583,7 +583,7 @@ itlb_miss_fault_e6500: */ rlwimi r11,r14,32-19,27,27 rlwimi r11,r14,32-16,19,19 - beq normal_tlb_miss + beq normal_tlb_miss_user /* XXX replace the RMW cycles with immediate loads + writes */ 1: mfspr r10,SPRN_MAS1 cmpldi cr0,r15,8 /* Check for vmalloc region */ @@ -626,7 +626,7 @@ itlb_miss_fault_e6500:
cmpldi cr0,r15,0 /* Check for user region */ std r14,EX_TLB_ESR(r12) /* write crazy -1 to frame */ - beq normal_tlb_miss + beq normal_tlb_miss_user
li r11,_PAGE_PRESENT|_PAGE_BAP_SX /* Base perm */ oris r11,r11,_PAGE_ACCESSED@h @@ -653,6 +653,12 @@ itlb_miss_fault_e6500: * r11 = PTE permission mask * r10 = crap (free to use) */ +normal_tlb_miss_user: +#ifdef CONFIG_PPC_KUAP + mfspr r14,SPRN_MAS1 + rlwinm. r14,r14,0,0x3fff0000 + beq- normal_tlb_miss_access_fault /* KUAP fault */ +#endif normal_tlb_miss: /* So we first construct the page table address. We do that by * shifting the bottom of the address (not the region ID) by @@ -683,11 +689,6 @@ finish_normal_tlb_miss: /* Check if required permissions are met */ andc. r15,r11,r14 bne- normal_tlb_miss_access_fault -#ifdef CONFIG_PPC_KUAP - mfspr r11,SPRN_MAS1 - rlwinm. r10,r11,0,0x3fff0000 - beq- normal_tlb_miss_access_fault /* KUAP fault */ -#endif
/* Now we build the MAS: * @@ -709,9 +710,7 @@ finish_normal_tlb_miss: rldicl r10,r14,64-8,64-8 cmpldi cr0,r10,BOOK3E_PAGESZ_4K beq- 1f -#ifndef CONFIG_PPC_KUAP mfspr r11,SPRN_MAS1 -#endif rlwimi r11,r14,31,21,24 rlwinm r11,r11,0,21,19 mtspr SPRN_MAS1,r11
From: Pali Rohár pali@kernel.org
commit 0c551abfa004ce154d487d91777bf221c808a64f upstream.
By default old pre-3.0 Freescale PCIe controllers reports invalid PCI Class Code 0x0b20 for PCIe Root Port. It can be seen by lspci -b output on P2020 board which has this pre-3.0 controller:
$ lspci -bvnn 00:00.0 Power PC [0b20]: Freescale Semiconductor Inc P2020E [1957:0070] (rev 21) !!! Invalid class 0b20 for header type 01 Capabilities: [4c] Express Root Port (Slot-), MSI 00
Fix this issue by programming correct PCI Class Code 0x0604 for PCIe Root Port to the Freescale specific PCIe register 0x474.
With this change lspci -b output is:
$ lspci -bvnn 00:00.0 PCI bridge [0604]: Freescale Semiconductor Inc P2020E [1957:0070] (rev 21) (prog-if 00 [Normal decode]) Capabilities: [4c] Express Root Port (Slot-), MSI 00
Without any "Invalid class" error. So class code was properly reflected into standard (read-only) PCI register 0x08.
Same fix is already implemented in U-Boot pcie_fsl.c driver in commit: http://source.denx.de/u-boot/u-boot/-/commit/d18d06ac35229345a0af80977a408cf...
Fix activated by U-Boot stay active also after booting Linux kernel. But boards which use older U-Boot version without that fix are affected and still require this fix.
So implement this class code fix also in kernel fsl_pci.c driver.
Cc: stable@vger.kernel.org Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220706101043.4867-1-pali@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/sysdev/fsl_pci.c | 8 ++++++++ arch/powerpc/sysdev/fsl_pci.h | 1 + 2 files changed, 9 insertions(+)
--- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -521,6 +521,7 @@ int fsl_add_bridge(struct platform_devic struct resource rsrc; const int *bus_range; u8 hdr_type, progif; + u32 class_code; struct device_node *dev; struct ccsr_pci __iomem *pci; u16 temp; @@ -594,6 +595,13 @@ int fsl_add_bridge(struct platform_devic PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS; if (fsl_pcie_check_link(hose)) hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; + /* Fix Class Code to PCI_CLASS_BRIDGE_PCI_NORMAL for pre-3.0 controller */ + if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) { + early_read_config_dword(hose, 0, 0, PCIE_FSL_CSR_CLASSCODE, &class_code); + class_code &= 0xff; + class_code |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8; + early_write_config_dword(hose, 0, 0, PCIE_FSL_CSR_CLASSCODE, class_code); + } } else { /* * Set PBFR(PCI Bus Function Register)[10] = 1 to --- a/arch/powerpc/sysdev/fsl_pci.h +++ b/arch/powerpc/sysdev/fsl_pci.h @@ -18,6 +18,7 @@ struct platform_device;
#define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */ #define PCIE_LTSSM_L0 0x16 /* L0 state */ +#define PCIE_FSL_CSR_CLASSCODE 0x474 /* FSL GPEX CSR */ #define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */ #define PCIE_IP_REV_3_0 0x02080300 /* PCIE IP block version Rev3.0 */ #define PIWAR_EN 0x80000000 /* Enable */
From: Christophe Leroy christophe.leroy@csgroup.eu
commit dd8de84b57b02ba9c1fe530a6d916c0853f136bd upstream.
On FSL_BOOK3E, _PAGE_RW is defined with two bits, one for user and one for supervisor. As soon as one of the two bits is set, the page has to be display as RW. But the way it is implemented today requires both bits to be set in order to display it as RW.
Instead of display RW when _PAGE_RW bits are set and R otherwise, reverse the logic and display R when _PAGE_RW bits are all 0 and RW otherwise.
This change has no impact on other platforms as _PAGE_RW is a single bit on all of them.
Fixes: 8eb07b187000 ("powerpc/mm: Dump linux pagetables") Cc: stable@vger.kernel.org Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/0c33b96317811edf691e81698aaee8fa45ec3449.165642739... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/mm/ptdump/shared.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/arch/powerpc/mm/ptdump/shared.c +++ b/arch/powerpc/mm/ptdump/shared.c @@ -17,9 +17,9 @@ static const struct flag_info flag_array .clear = " ", }, { .mask = _PAGE_RW, - .val = _PAGE_RW, - .set = "rw", - .clear = "r ", + .val = 0, + .set = "r ", + .clear = "rw", }, { .mask = _PAGE_EXEC, .val = _PAGE_EXEC,
From: Michael Ellerman mpe@ellerman.id.au
commit 90b5d4fe0b3ba7f589c6723c6bfb559d9e83956a upstream.
On a bare-metal Power8 system that doesn't have an "ibm,power-rng", a malicious QEMU and guest that ignore the absence of the KVM_CAP_PPC_HWRNG flag, and calls H_RANDOM anyway, will dereference a NULL pointer.
In practice all Power8 machines have an "ibm,power-rng", but let's not rely on that, add a NULL check and early return in powernv_get_random_real_mode().
Fixes: e928e9cb3601 ("KVM: PPC: Book3S HV: Add fast real-mode H_RANDOM implementation.") Cc: stable@vger.kernel.org # v4.1+ Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220727143219.2684192-1-mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/platforms/powernv/rng.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/powerpc/platforms/powernv/rng.c +++ b/arch/powerpc/platforms/powernv/rng.c @@ -63,6 +63,8 @@ int powernv_get_random_real_mode(unsigne struct powernv_rng *rng;
rng = raw_cpu_read(powernv_rng); + if (!rng) + return 0;
*v = rng_whiten(rng, __raw_rm_readq(rng->regs_real));
From: Huacai Chen chenhuacai@loongson.cn
commit e1a534f5d074db45ae5cbac41d8912b98e96a006 upstream.
When CONFIG_CPUMASK_OFFSTACK and CONFIG_DEBUG_PER_CPU_MAPS is selected, cpu_max_bits_warn() generates a runtime warning similar as below while we show /proc/cpuinfo. Fix this by using nr_cpu_ids (the runtime limit) instead of NR_CPUS to iterate CPUs.
[ 3.052463] ------------[ cut here ]------------ [ 3.059679] WARNING: CPU: 3 PID: 1 at include/linux/cpumask.h:108 show_cpuinfo+0x5e8/0x5f0 [ 3.070072] Modules linked in: efivarfs autofs4 [ 3.076257] CPU: 0 PID: 1 Comm: systemd Not tainted 5.19-rc5+ #1052 [ 3.084034] Hardware name: Loongson Loongson-3A4000-7A1000-1w-V0.1-CRB/Loongson-LS3A4000-7A1000-1w-EVB-V1.21, BIOS Loongson-UDK2018-V2.0.04082-beta7 04/27 [ 3.099465] Stack : 9000000100157b08 9000000000f18530 9000000000cf846c 9000000100154000 [ 3.109127] 9000000100157a50 0000000000000000 9000000100157a58 9000000000ef7430 [ 3.118774] 90000001001578e8 0000000000000040 0000000000000020 ffffffffffffffff [ 3.128412] 0000000000aaaaaa 1ab25f00eec96a37 900000010021de80 900000000101c890 [ 3.138056] 0000000000000000 0000000000000000 0000000000000000 0000000000aaaaaa [ 3.147711] ffff8000339dc220 0000000000000001 0000000006ab4000 0000000000000000 [ 3.157364] 900000000101c998 0000000000000004 9000000000ef7430 0000000000000000 [ 3.167012] 0000000000000009 000000000000006c 0000000000000000 0000000000000000 [ 3.176641] 9000000000d3de08 9000000001639390 90000000002086d8 00007ffff0080286 [ 3.186260] 00000000000000b0 0000000000000004 0000000000000000 0000000000071c1c [ 3.195868] ... [ 3.199917] Call Trace: [ 3.203941] [<98000000002086d8>] show_stack+0x38/0x14c [ 3.210666] [<9800000000cf846c>] dump_stack_lvl+0x60/0x88 [ 3.217625] [<980000000023d268>] __warn+0xd0/0x100 [ 3.223958] [<9800000000cf3c90>] warn_slowpath_fmt+0x7c/0xcc [ 3.231150] [<9800000000210220>] show_cpuinfo+0x5e8/0x5f0 [ 3.238080] [<98000000004f578c>] seq_read_iter+0x354/0x4b4 [ 3.245098] [<98000000004c2e90>] new_sync_read+0x17c/0x1c4 [ 3.252114] [<98000000004c5174>] vfs_read+0x138/0x1d0 [ 3.258694] [<98000000004c55f8>] ksys_read+0x70/0x100 [ 3.265265] [<9800000000cfde9c>] do_syscall+0x7c/0x94 [ 3.271820] [<9800000000202fe4>] handle_syscall+0xc4/0x160 [ 3.281824] ---[ end trace 8b484262b4b8c24c ]---
Cc: stable@vger.kernel.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/kernel/proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -311,7 +311,7 @@ static void *c_start(struct seq_file *m, { unsigned long i = *pos;
- return i < NR_CPUS ? (void *) (i + 1) : NULL; + return i < nr_cpu_ids ? (void *) (i + 1) : NULL; }
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
From: Suzuki K Poulose suzuki.poulose@arm.com
commit 2af89ebacf299b7fba5f3087d35e8a286ec33706 upstream.
coresight devices track their connections (output connections) and hold a reference to the fwnode. When a device goes away, we walk through the devices on the coresight bus and make sure that the references are dropped. This happens both ways: a) For all output connections from the device, drop the reference to the target device via coresight_release_platform_data()
b) Iterate over all the devices on the coresight bus and drop the reference to fwnode if *this* device is the target of the output connection, via coresight_remove_conns()->coresight_remove_match().
However, the coresight_remove_match() doesn't clear the fwnode field, after dropping the reference, this causes use-after-free and additional refcount drops on the fwnode.
e.g., if we have two devices, A and B, with a connection, A -> B. If we remove B first, B would clear the reference on B, from A via coresight_remove_match(). But when A is removed, it still has a connection with fwnode still pointing to B. Thus it tries to drops the reference in coresight_release_platform_data(), raising the bells like :
[ 91.990153] ------------[ cut here ]------------ [ 91.990163] refcount_t: addition on 0; use-after-free. [ 91.990212] WARNING: CPU: 0 PID: 461 at lib/refcount.c:25 refcount_warn_saturate+0xa0/0x144 [ 91.990260] Modules linked in: coresight_funnel coresight_replicator coresight_etm4x(-) crct10dif_ce coresight ip_tables x_tables ipv6 [last unloaded: coresight_cpu_debug] [ 91.990398] CPU: 0 PID: 461 Comm: rmmod Tainted: G W T 5.19.0-rc2+ #53 [ 91.990418] Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform, BIOS EDK II Feb 1 2019 [ 91.990434] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 91.990454] pc : refcount_warn_saturate+0xa0/0x144 [ 91.990476] lr : refcount_warn_saturate+0xa0/0x144 [ 91.990496] sp : ffff80000c843640 [ 91.990509] x29: ffff80000c843640 x28: ffff800009957c28 x27: ffff80000c8439a8 [ 91.990560] x26: ffff00097eff1990 x25: ffff8000092b6ad8 x24: ffff00097eff19a8 [ 91.990610] x23: ffff80000c8439a8 x22: 0000000000000000 x21: ffff80000c8439c2 [ 91.990659] x20: 0000000000000000 x19: ffff00097eff1a10 x18: ffff80000ab99c40 [ 91.990708] x17: 0000000000000000 x16: 0000000000000000 x15: ffff80000abf6fa0 [ 91.990756] x14: 000000000000001d x13: 0a2e656572662d72 x12: 657466612d657375 [ 91.990805] x11: 203b30206e6f206e x10: 6f69746964646120 x9 : ffff8000081aba28 [ 91.990854] x8 : 206e6f206e6f6974 x7 : 69646461203a745f x6 : 746e756f63666572 [ 91.990903] x5 : ffff00097648ec58 x4 : 0000000000000000 x3 : 0000000000000027 [ 91.990952] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff00080260ba00 [ 91.991000] Call trace: [ 91.991012] refcount_warn_saturate+0xa0/0x144 [ 91.991034] kobject_get+0xac/0xb0 [ 91.991055] of_node_get+0x2c/0x40 [ 91.991076] of_fwnode_get+0x40/0x60 [ 91.991094] fwnode_handle_get+0x3c/0x60 [ 91.991116] fwnode_get_nth_parent+0xf4/0x110 [ 91.991137] fwnode_full_name_string+0x48/0xc0 [ 91.991158] device_node_string+0x41c/0x530 [ 91.991178] pointer+0x320/0x3ec [ 91.991198] vsnprintf+0x23c/0x750 [ 91.991217] vprintk_store+0x104/0x4b0 [ 91.991238] vprintk_emit+0x8c/0x360 [ 91.991257] vprintk_default+0x44/0x50 [ 91.991276] vprintk+0xcc/0xf0 [ 91.991295] _printk+0x68/0x90 [ 91.991315] of_node_release+0x13c/0x14c [ 91.991334] kobject_put+0x98/0x114 [ 91.991354] of_node_put+0x24/0x34 [ 91.991372] of_fwnode_put+0x40/0x5c [ 91.991390] fwnode_handle_put+0x38/0x50 [ 91.991411] coresight_release_platform_data+0x74/0xb0 [coresight] [ 91.991472] coresight_unregister+0x64/0xcc [coresight] [ 91.991525] etm4_remove_dev+0x64/0x78 [coresight_etm4x] [ 91.991563] etm4_remove_amba+0x1c/0x2c [coresight_etm4x] [ 91.991598] amba_remove+0x3c/0x19c
Reproducible by: (Build all coresight components as modules):
#!/bin/sh while true do for m in tmc stm cpu_debug etm4x replicator funnel do modprobe coresight_${m} done
for m in tmc stm cpu_debug etm4x replicator funnel do rmmode coresight_${m} done done
Cc: stable@vger.kernel.org Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Mike Leach mike.leach@linaro.org Cc: Leo Yan leo.yan@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Fixes: 37ea1ffddffa ("coresight: Use fwnode handle instead of device names") Link: https://lore.kernel.org/r/20220614214024.3005275-1-suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hwtracing/coresight/coresight-core.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -1424,6 +1424,7 @@ static int coresight_remove_match(struct * platform data. */ fwnode_handle_put(conn->child_fwnode); + conn->child_fwnode = NULL; /* No need to continue */ break; }
From: Linyu Yuan quic_linyyuan@quicinc.com
commit a7dc438b5e446afcd1b3b6651da28271400722f2 upstream.
We found PPM will not send any notification after it report error status and OPM issue GET_ERROR_STATUS command to read the details about error.
According UCSI spec, PPM may clear the Error Status Data after the OPM has acknowledged the command completion.
This change add operation to acknowledge the command completion from PPM.
Fixes: bdc62f2bae8f (usb: typec: ucsi: Simplified registration and I/O API) Cc: stable@vger.kernel.org # 5.10 Signed-off-by: Jack Pham quic_jackp@quicinc.com Signed-off-by: Linyu Yuan quic_linyyuan@quicinc.com Link: https://lore.kernel.org/r/1658817949-4632-1-git-send-email-quic_linyyuan@qui... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/typec/ucsi/ucsi.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -76,6 +76,10 @@ static int ucsi_read_error(struct ucsi * if (ret) return ret;
+ ret = ucsi_acknowledge_command(ucsi); + if (ret) + return ret; + switch (error) { case UCSI_ERROR_INCOMPATIBLE_PARTNER: return -EOPNOTSUPP;
From: Weitao Wang WeitaoWang-oc@zhaoxin.com
commit 26c6c2f8a907c9e3a2f24990552a4d77235791e6 upstream.
Usb core introduce the mechanism of giveback of URB in tasklet context to reduce hardware interrupt handling time. On some test situation(such as FIO with 4KB block size), when tasklet callback function called to giveback URB, interrupt handler add URB node to the bh->head list also. If check bh->head list again after finish all URB giveback of local_list, then it may introduce a "dynamic balance" between giveback URB and add URB to bh->head list. This tasklet callback function may not exit for a long time, which will cause other tasklet function calls to be delayed. Some real-time applications(such as KB and Mouse) will see noticeable lag.
In order to prevent the tasklet function from occupying the cpu for a long time at a time, new URBS will not be added to the local_list even though the bh->head list is not empty. But also need to ensure the left URB giveback to be processed in time, so add a member high_prio for structure giveback_urb_bh to prioritize tasklet and schelule this tasklet again if bh->head list is not empty.
At the same time, we are able to prioritize tasklet through structure member high_prio. So, replace the local high_prio_bh variable with this structure member in usb_hcd_giveback_urb.
Fixes: 94dfd7edfd5c ("USB: HCD: support giveback of URB in tasklet context") Cc: stable stable@kernel.org Reviewed-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: Weitao Wang WeitaoWang-oc@zhaoxin.com Link: https://lore.kernel.org/r/20220726074918.5114-1-WeitaoWang-oc@zhaoxin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/core/hcd.c | 26 +++++++++++++++----------- include/linux/usb/hcd.h | 1 + 2 files changed, 16 insertions(+), 11 deletions(-)
--- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1691,7 +1691,6 @@ static void usb_giveback_urb_bh(struct t
spin_lock_irq(&bh->lock); bh->running = true; - restart: list_replace_init(&bh->head, &local_list); spin_unlock_irq(&bh->lock);
@@ -1705,10 +1704,17 @@ static void usb_giveback_urb_bh(struct t bh->completing_ep = NULL; }
- /* check if there are new URBs to giveback */ + /* + * giveback new URBs next time to prevent this function + * from not exiting for a long time. + */ spin_lock_irq(&bh->lock); - if (!list_empty(&bh->head)) - goto restart; + if (!list_empty(&bh->head)) { + if (bh->high_prio) + tasklet_hi_schedule(&bh->bh); + else + tasklet_schedule(&bh->bh); + } bh->running = false; spin_unlock_irq(&bh->lock); } @@ -1737,7 +1743,7 @@ static void usb_giveback_urb_bh(struct t void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) { struct giveback_urb_bh *bh; - bool running, high_prio_bh; + bool running;
/* pass status to tasklet via unlinked */ if (likely(!urb->unlinked)) @@ -1748,13 +1754,10 @@ void usb_hcd_giveback_urb(struct usb_hcd return; }
- if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)) { + if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)) bh = &hcd->high_prio_bh; - high_prio_bh = true; - } else { + else bh = &hcd->low_prio_bh; - high_prio_bh = false; - }
spin_lock(&bh->lock); list_add_tail(&urb->urb_list, &bh->head); @@ -1763,7 +1766,7 @@ void usb_hcd_giveback_urb(struct usb_hcd
if (running) ; - else if (high_prio_bh) + else if (bh->high_prio) tasklet_hi_schedule(&bh->bh); else tasklet_schedule(&bh->bh); @@ -2959,6 +2962,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
/* initialize tasklets */ init_giveback_urb_bh(&hcd->high_prio_bh); + hcd->high_prio_bh.high_prio = true; init_giveback_urb_bh(&hcd->low_prio_bh);
/* enable irqs just before we start the controller, --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -66,6 +66,7 @@
struct giveback_urb_bh { bool running; + bool high_prio; spinlock_t lock; struct list_head head; struct tasklet_struct bh;
From: Jose Alonso joalonsof@gmail.com
commit 6fd2c17fb6e02a8c0ab51df1cfec82ce96b8e83d upstream.
This reverts commit 36a15e1cb134c0395261ba1940762703f778438c.
The usage of FLAG_SEND_ZLP causes problems to other firmware/hardware versions that have no issues.
The FLAG_SEND_ZLP is not safe to use in this context. See: https://patchwork.ozlabs.org/project/netdev/patch/1270599787.8900.8.camel@Li... The original problem needs another way to solve.
Fixes: 36a15e1cb134 ("net: usb: ax88179_178a needs FLAG_SEND_ZLP") Cc: stable@vger.kernel.org Reported-by: Ronald Wahl ronald.wahl@raritan.com Link: https://bugzilla.kernel.org/show_bug.cgi?id=216327 Link: https://bugs.archlinux.org/task/75491 Signed-off-by: Jose Alonso joalonsof@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/usb/ax88179_178a.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
--- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -1801,7 +1801,7 @@ static const struct driver_info ax88179_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1814,7 +1814,7 @@ static const struct driver_info ax88178a .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1827,7 +1827,7 @@ static const struct driver_info cypress_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1840,7 +1840,7 @@ static const struct driver_info dlink_du .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1853,7 +1853,7 @@ static const struct driver_info sitecom_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1866,7 +1866,7 @@ static const struct driver_info samsung_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1879,7 +1879,7 @@ static const struct driver_info lenovo_i .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1892,7 +1892,7 @@ static const struct driver_info belkin_i .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1905,7 +1905,7 @@ static const struct driver_info toshiba_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1918,7 +1918,7 @@ static const struct driver_info mct_info .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1931,7 +1931,7 @@ static const struct driver_info at_umc20 .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1944,7 +1944,7 @@ static const struct driver_info at_umc20 .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, }; @@ -1957,7 +1957,7 @@ static const struct driver_info at_umc20 .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
From: Kunihiko Hayashi hayashi.kunihiko@socionext.com
commit 9b0dc7abb5cc43a2dbf90690c3c6011dcadc574d upstream.
An interrupt for USB device are shared with USB host. Set interrupt-names property to common "dwc_usb3" instead of "host" and "peripheral".
Cc: stable@vger.kernel.org Fixes: 45be1573ad19 ("ARM: dts: uniphier: Add USB3 controller nodes") Reported-by: Ryuta NAKANISHI nakanishi.ryuta@socionext.com Signed-off-by: Kunihiko Hayashi hayashi.kunihiko@socionext.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/boot/dts/uniphier-pxs2.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/arch/arm/boot/dts/uniphier-pxs2.dtsi +++ b/arch/arm/boot/dts/uniphier-pxs2.dtsi @@ -597,8 +597,8 @@ compatible = "socionext,uniphier-dwc3", "snps,dwc3"; status = "disabled"; reg = <0x65a00000 0xcd00>; - interrupt-names = "host", "peripheral"; - interrupts = <0 134 4>, <0 135 4>; + interrupt-names = "dwc_usb3"; + interrupts = <0 134 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb2>; clock-names = "ref", "bus_early", "suspend"; @@ -693,8 +693,8 @@ compatible = "socionext,uniphier-dwc3", "snps,dwc3"; status = "disabled"; reg = <0x65c00000 0xcd00>; - interrupt-names = "host", "peripheral"; - interrupts = <0 137 4>, <0 138 4>; + interrupt-names = "dwc_usb3"; + interrupts = <0 137 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb1>, <&pinctrl_usb3>; clock-names = "ref", "bus_early", "suspend";
From: Kunihiko Hayashi hayashi.kunihiko@socionext.com
commit fe17b91a7777df140d0f1433991da67ba658796c upstream.
An interrupt for USB device are shared with USB host. Set interrupt-names property to common "dwc_usb3" instead of "host" and "peripheral".
Cc: stable@vger.kernel.org Fixes: d7b9beb830d7 ("arm64: dts: uniphier: Add USB3 controller nodes") Reported-by: Ryuta NAKANISHI nakanishi.ryuta@socionext.com Signed-off-by: Kunihiko Hayashi hayashi.kunihiko@socionext.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi @@ -599,8 +599,8 @@ compatible = "socionext,uniphier-dwc3", "snps,dwc3"; status = "disabled"; reg = <0x65a00000 0xcd00>; - interrupt-names = "host", "peripheral"; - interrupts = <0 134 4>, <0 135 4>; + interrupt-names = "dwc_usb3"; + interrupts = <0 134 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb2>; clock-names = "ref", "bus_early", "suspend"; @@ -701,8 +701,8 @@ compatible = "socionext,uniphier-dwc3", "snps,dwc3"; status = "disabled"; reg = <0x65c00000 0xcd00>; - interrupt-names = "host", "peripheral"; - interrupts = <0 137 4>, <0 138 4>; + interrupt-names = "dwc_usb3"; + interrupts = <0 137 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb1>, <&pinctrl_usb3>; clock-names = "ref", "bus_early", "suspend";
From: Alan Stern stern@rowland.harvard.edu
commit 2191c00855b03aa59c20e698be713d952d51fc18 upstream.
The syzbot fuzzer found a race between uevent callbacks and gadget driver unregistration that can cause a use-after-free bug:
--------------------------------------------------------------- BUG: KASAN: use-after-free in usb_udc_uevent+0x11f/0x130 drivers/usb/gadget/udc/core.c:1732 Read of size 8 at addr ffff888078ce2050 by task udevd/2968
CPU: 1 PID: 2968 Comm: udevd Not tainted 5.19.0-rc4-next-20220628-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/29/2022 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:317 [inline] print_report.cold+0x2ba/0x719 mm/kasan/report.c:433 kasan_report+0xbe/0x1f0 mm/kasan/report.c:495 usb_udc_uevent+0x11f/0x130 drivers/usb/gadget/udc/core.c:1732 dev_uevent+0x290/0x770 drivers/base/core.c:2424 ---------------------------------------------------------------
The bug occurs because usb_udc_uevent() dereferences udc->driver but does so without acquiring the udc_lock mutex, which protects this field. If the gadget driver is unbound from the udc concurrently with uevent processing, the driver structure may be accessed after it has been deallocated.
To prevent the race, we make sure that the routine holds the mutex around the racing accesses.
Link: https://lore.kernel.org/all/0000000000004de90405a719c951@google.com CC: stable@vger.kernel.org # fc274c1e9973 Reported-and-tested-by: syzbot+b0de012ceb1e2a97891b@syzkaller.appspotmail.com Signed-off-by: Alan Stern stern@rowland.harvard.edu Link: https://lore.kernel.org/r/YtlrnhHyrHsSky9m@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/gadget/udc/core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
--- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1728,13 +1728,14 @@ static int usb_udc_uevent(struct device return ret; }
- if (udc->driver) { + mutex_lock(&udc_lock); + if (udc->driver) ret = add_uevent_var(env, "USB_UDC_DRIVER=%s", udc->driver->function); - if (ret) { - dev_err(dev, "failed to add uevent USB_UDC_DRIVER\n"); - return ret; - } + mutex_unlock(&udc_lock); + if (ret) { + dev_err(dev, "failed to add uevent USB_UDC_DRIVER\n"); + return ret; }
return 0;
From: Michael Grzeschik m.grzeschik@pengutronix.de
commit 23385cec5f354794dadced7f28c31da7ae3eb54c upstream.
The function __dwc3_prepare_one_trb has many parameters. Since it is only used in dwc3_prepare_one_trb there is no point in keeping the function. We merge both functions and get rid of the big list of parameters.
Fixes: 40d829fb2ec6 ("usb: dwc3: gadget: Correct ISOC DATA PIDs for short packets") Cc: stable stable@kernel.org Signed-off-by: Michael Grzeschik m.grzeschik@pengutronix.de Link: https://lore.kernel.org/r/20220704141812.1532306-2-m.grzeschik@pengutronix.d... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc3/gadget.c | 92 ++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 52 deletions(-)
--- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1182,17 +1182,49 @@ static u32 dwc3_calc_trbs_left(struct dw return trbs_left; }
-static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, - dma_addr_t dma, unsigned int length, unsigned int chain, - unsigned int node, unsigned int stream_id, - unsigned int short_not_ok, unsigned int no_interrupt, - unsigned int is_last, bool must_interrupt) +/** + * dwc3_prepare_one_trb - setup one TRB from one request + * @dep: endpoint for which this request is prepared + * @req: dwc3_request pointer + * @trb_length: buffer size of the TRB + * @chain: should this TRB be chained to the next? + * @node: only for isochronous endpoints. First TRB needs different type. + * @use_bounce_buffer: set to use bounce buffer + * @must_interrupt: set to interrupt on TRB completion + */ +static void dwc3_prepare_one_trb(struct dwc3_ep *dep, + struct dwc3_request *req, unsigned int trb_length, + unsigned int chain, unsigned int node, bool use_bounce_buffer, + bool must_interrupt) { + struct dwc3_trb *trb; + dma_addr_t dma; + unsigned int stream_id = req->request.stream_id; + unsigned int short_not_ok = req->request.short_not_ok; + unsigned int no_interrupt = req->request.no_interrupt; + unsigned int is_last = req->request.is_last; struct dwc3 *dwc = dep->dwc; struct usb_gadget *gadget = dwc->gadget; enum usb_device_speed speed = gadget->speed;
- trb->size = DWC3_TRB_SIZE_LENGTH(length); + if (use_bounce_buffer) + dma = dep->dwc->bounce_addr; + else if (req->request.num_sgs > 0) + dma = sg_dma_address(req->start_sg); + else + dma = req->request.dma; + + trb = &dep->trb_pool[dep->trb_enqueue]; + + if (!req->trb) { + dwc3_gadget_move_started_request(req); + req->trb = trb; + req->trb_dma = dwc3_trb_dma_offset(dep, trb); + } + + req->num_trbs++; + + trb->size = DWC3_TRB_SIZE_LENGTH(trb_length); trb->bpl = lower_32_bits(dma); trb->bph = upper_32_bits(dma);
@@ -1232,10 +1264,10 @@ static void __dwc3_prepare_one_trb(struc unsigned int mult = 2; unsigned int maxp = usb_endpoint_maxp(ep->desc);
- if (length <= (2 * maxp)) + if (trb_length <= (2 * maxp)) mult--;
- if (length <= maxp) + if (trb_length <= maxp) mult--;
trb->size |= DWC3_TRB_SIZE_PCM1(mult); @@ -1309,50 +1341,6 @@ static void __dwc3_prepare_one_trb(struc trace_dwc3_prepare_trb(dep, trb); }
-/** - * dwc3_prepare_one_trb - setup one TRB from one request - * @dep: endpoint for which this request is prepared - * @req: dwc3_request pointer - * @trb_length: buffer size of the TRB - * @chain: should this TRB be chained to the next? - * @node: only for isochronous endpoints. First TRB needs different type. - * @use_bounce_buffer: set to use bounce buffer - * @must_interrupt: set to interrupt on TRB completion - */ -static void dwc3_prepare_one_trb(struct dwc3_ep *dep, - struct dwc3_request *req, unsigned int trb_length, - unsigned int chain, unsigned int node, bool use_bounce_buffer, - bool must_interrupt) -{ - struct dwc3_trb *trb; - dma_addr_t dma; - unsigned int stream_id = req->request.stream_id; - unsigned int short_not_ok = req->request.short_not_ok; - unsigned int no_interrupt = req->request.no_interrupt; - unsigned int is_last = req->request.is_last; - - if (use_bounce_buffer) - dma = dep->dwc->bounce_addr; - else if (req->request.num_sgs > 0) - dma = sg_dma_address(req->start_sg); - else - dma = req->request.dma; - - trb = &dep->trb_pool[dep->trb_enqueue]; - - if (!req->trb) { - dwc3_gadget_move_started_request(req); - req->trb = trb; - req->trb_dma = dwc3_trb_dma_offset(dep, trb); - } - - req->num_trbs++; - - __dwc3_prepare_one_trb(dep, trb, dma, trb_length, chain, node, - stream_id, short_not_ok, no_interrupt, is_last, - must_interrupt); -} - static bool dwc3_needs_extra_trb(struct dwc3_ep *dep, struct dwc3_request *req) { unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc);
From: Michael Grzeschik m.grzeschik@pengutronix.de
commit 8affe37c525d800a2628c4ecfaed13b77dc5634a upstream.
For High-Speed Transfers the prepare_one_trb function is calculating the multiplier setting for the trb based on the length parameter of the trb currently prepared. This assumption is wrong. For trbs with a sg list, the length of the actual request has to be taken instead.
Fixes: 40d829fb2ec6 ("usb: dwc3: gadget: Correct ISOC DATA PIDs for short packets") Cc: stable stable@kernel.org Signed-off-by: Michael Grzeschik m.grzeschik@pengutronix.de Link: https://lore.kernel.org/r/20220704141812.1532306-3-m.grzeschik@pengutronix.d... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc3/gadget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1264,10 +1264,10 @@ static void dwc3_prepare_one_trb(struct unsigned int mult = 2; unsigned int maxp = usb_endpoint_maxp(ep->desc);
- if (trb_length <= (2 * maxp)) + if (req->request.length <= (2 * maxp)) mult--;
- if (trb_length <= maxp) + if (req->request.length <= maxp) mult--;
trb->size |= DWC3_TRB_SIZE_PCM1(mult);
From: Thadeu Lima de Souza Cascardo cascardo@canonical.com
commit 470ee20e069a6d05ae549f7d0ef2bdbcee6a81b2 upstream.
When doing lookups for sets on the same batch by using its ID, a set from a different table can be used.
Then, when the table is removed, a reference to the set may be kept after the set is freed, leading to a potential use-after-free.
When looking for sets by ID, use the table that was used for the lookup by name, and only return sets belonging to that same table.
This fixes CVE-2022-2586, also reported as ZDI-CAN-17470.
Reported-by: Team Orca of Sea Security (@seasecresponse) Fixes: 958bee14d071 ("netfilter: nf_tables: use new transaction infrastructure to handle sets") Signed-off-by: Thadeu Lima de Souza Cascardo cascardo@canonical.com Cc: stable@vger.kernel.org Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netfilter/nf_tables_api.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3842,6 +3842,7 @@ static struct nft_set *nft_set_lookup_by }
static struct nft_set *nft_set_lookup_byid(const struct net *net, + const struct nft_table *table, const struct nlattr *nla, u8 genmask) { struct nftables_pernet *nft_net = nft_pernet(net); @@ -3853,6 +3854,7 @@ static struct nft_set *nft_set_lookup_by struct nft_set *set = nft_trans_set(trans);
if (id == nft_trans_set_id(trans) && + set->table == table && nft_active_genmask(set, genmask)) return set; } @@ -3873,7 +3875,7 @@ struct nft_set *nft_set_lookup_global(co if (!nla_set_id) return set;
- set = nft_set_lookup_byid(net, nla_set_id, genmask); + set = nft_set_lookup_byid(net, table, nla_set_id, genmask); } return set; }
From: Thadeu Lima de Souza Cascardo cascardo@canonical.com
commit 95f466d22364a33d183509629d0879885b4f547e upstream.
When doing lookups for chains on the same batch by using its ID, a chain from a different table can be used. If a rule is added to a table but refers to a chain in a different table, it will be linked to the chain in table2, but would have expressions referring to objects in table1.
Then, when table1 is removed, the rule will not be removed as its linked to a chain in table2. When expressions in the rule are processed or removed, that will lead to a use-after-free.
When looking for chains by ID, use the table that was used for the lookup by name, and only return chains belonging to that same table.
Fixes: 837830a4b439 ("netfilter: nf_tables: add NFTA_RULE_CHAIN_ID attribute") Signed-off-by: Thadeu Lima de Souza Cascardo cascardo@canonical.com Cc: stable@vger.kernel.org Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netfilter/nf_tables_api.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -2472,6 +2472,7 @@ err: }
static struct nft_chain *nft_chain_lookup_byid(const struct net *net, + const struct nft_table *table, const struct nlattr *nla) { struct nftables_pernet *nft_net = nft_pernet(net); @@ -2482,6 +2483,7 @@ static struct nft_chain *nft_chain_looku struct nft_chain *chain = trans->ctx.chain;
if (trans->msg_type == NFT_MSG_NEWCHAIN && + chain->table == table && id == nft_trans_chain_id(trans)) return chain; } @@ -3417,7 +3419,7 @@ static int nf_tables_newrule(struct sk_b return -EOPNOTSUPP;
} else if (nla[NFTA_RULE_CHAIN_ID]) { - chain = nft_chain_lookup_byid(net, nla[NFTA_RULE_CHAIN_ID]); + chain = nft_chain_lookup_byid(net, table, nla[NFTA_RULE_CHAIN_ID]); if (IS_ERR(chain)) { NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN_ID]); return PTR_ERR(chain); @@ -9607,7 +9609,7 @@ static int nft_verdict_init(const struct tb[NFTA_VERDICT_CHAIN], genmask); } else if (tb[NFTA_VERDICT_CHAIN_ID]) { - chain = nft_chain_lookup_byid(ctx->net, + chain = nft_chain_lookup_byid(ctx->net, ctx->table, tb[NFTA_VERDICT_CHAIN_ID]); if (IS_ERR(chain)) return PTR_ERR(chain);
From: Thadeu Lima de Souza Cascardo cascardo@canonical.com
commit 36d5b2913219ac853908b0f1c664345e04313856 upstream.
When doing lookups for rules on the same batch by using its ID, a rule from a different chain can be used. If a rule is added to a chain but tries to be positioned next to a rule from a different chain, it will be linked to chain2, but the use counter on chain1 would be the one to be incremented.
When looking for rules by ID, use the chain that was used for the lookup by name. The chain used in the context copied to the transaction needs to match that same chain. That way, struct nft_rule does not need to get enlarged with another member.
Fixes: 1a94e38d254b ("netfilter: nf_tables: add NFTA_RULE_ID attribute") Fixes: 75dd48e2e420 ("netfilter: nf_tables: Support RULE_ID reference in new rule") Signed-off-by: Thadeu Lima de Souza Cascardo cascardo@canonical.com Cc: stable@vger.kernel.org Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netfilter/nf_tables_api.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3373,6 +3373,7 @@ static int nft_table_validate(struct net }
static struct nft_rule *nft_rule_lookup_byid(const struct net *net, + const struct nft_chain *chain, const struct nlattr *nla);
#define NFT_RULE_MAXEXPRS 128 @@ -3461,7 +3462,7 @@ static int nf_tables_newrule(struct sk_b return PTR_ERR(old_rule); } } else if (nla[NFTA_RULE_POSITION_ID]) { - old_rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_POSITION_ID]); + old_rule = nft_rule_lookup_byid(net, chain, nla[NFTA_RULE_POSITION_ID]); if (IS_ERR(old_rule)) { NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_POSITION_ID]); return PTR_ERR(old_rule); @@ -3606,6 +3607,7 @@ err_release_expr: }
static struct nft_rule *nft_rule_lookup_byid(const struct net *net, + const struct nft_chain *chain, const struct nlattr *nla) { struct nftables_pernet *nft_net = nft_pernet(net); @@ -3616,6 +3618,7 @@ static struct nft_rule *nft_rule_lookup_ struct nft_rule *rule = nft_trans_rule(trans);
if (trans->msg_type == NFT_MSG_NEWRULE && + trans->ctx.chain == chain && id == nft_trans_rule_id(trans)) return rule; } @@ -3665,7 +3668,7 @@ static int nf_tables_delrule(struct sk_b
err = nft_delrule(&ctx, rule); } else if (nla[NFTA_RULE_ID]) { - rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_ID]); + rule = nft_rule_lookup_byid(net, chain, nla[NFTA_RULE_ID]); if (IS_ERR(rule)) { NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_ID]); return PTR_ERR(rule);
From: Pablo Neira Ayuso pablo@netfilter.org
commit 341b6941608762d8235f3fd1e45e4d7114ed8c2c upstream.
Instead of parsing the data and then validate that type and length are correct, pass a description of the expected data so it can be validated upfront before parsing it to bail out earlier.
This patch adds a new .size field to specify the maximum size of the data area. The .len field is optional and it is used as an input/output field, it provides the specific length of the expected data in the input path. If then .len field is not specified, then obtained length from the netlink attribute is stored. This is required by cmp, bitwise, range and immediate, which provide no netlink attribute that describes the data length. The immediate expression uses the destination register type to infer the expected data type.
Relying on opencoded validation of the expected data might lead to subtle bugs as described in 7e6bc1f6cabc ("netfilter: nf_tables: stricter validation of element data").
Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/net/netfilter/nf_tables.h | 4 - net/netfilter/nf_tables_api.c | 78 +++++++++++++++++++------------------- net/netfilter/nft_bitwise.c | 66 ++++++++++++++++---------------- net/netfilter/nft_cmp.c | 44 +++++++++------------ net/netfilter/nft_immediate.c | 22 +++++++++- net/netfilter/nft_range.c | 27 +++++-------- 6 files changed, 126 insertions(+), 115 deletions(-)
--- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -208,11 +208,11 @@ struct nft_ctx {
struct nft_data_desc { enum nft_data_types type; + unsigned int size; unsigned int len; };
-int nft_data_init(const struct nft_ctx *ctx, - struct nft_data *data, unsigned int size, +int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, struct nft_data_desc *desc, const struct nlattr *nla); void nft_data_hold(const struct nft_data *data, enum nft_data_types type); void nft_data_release(const struct nft_data *data, enum nft_data_types type); --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -5202,19 +5202,13 @@ static int nft_setelem_parse_flags(const static int nft_setelem_parse_key(struct nft_ctx *ctx, struct nft_set *set, struct nft_data *key, struct nlattr *attr) { - struct nft_data_desc desc; - int err; - - err = nft_data_init(ctx, key, NFT_DATA_VALUE_MAXLEN, &desc, attr); - if (err < 0) - return err; - - if (desc.type != NFT_DATA_VALUE || desc.len != set->klen) { - nft_data_release(key, desc.type); - return -EINVAL; - } + struct nft_data_desc desc = { + .type = NFT_DATA_VALUE, + .size = NFT_DATA_VALUE_MAXLEN, + .len = set->klen, + };
- return 0; + return nft_data_init(ctx, key, &desc, attr); }
static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set, @@ -5223,24 +5217,17 @@ static int nft_setelem_parse_data(struct struct nlattr *attr) { u32 dtype; - int err; - - err = nft_data_init(ctx, data, NFT_DATA_VALUE_MAXLEN, desc, attr); - if (err < 0) - return err;
if (set->dtype == NFT_DATA_VERDICT) dtype = NFT_DATA_VERDICT; else dtype = NFT_DATA_VALUE;
- if (dtype != desc->type || - set->dlen != desc->len) { - nft_data_release(data, desc->type); - return -EINVAL; - } + desc->type = dtype; + desc->size = NFT_DATA_VALUE_MAXLEN; + desc->len = set->dlen;
- return 0; + return nft_data_init(ctx, data, desc, attr); }
static void *nft_setelem_catchall_get(const struct net *net, @@ -9631,7 +9618,7 @@ static int nft_verdict_init(const struct }
desc->len = sizeof(data->verdict); - desc->type = NFT_DATA_VERDICT; + return 0; }
@@ -9684,20 +9671,25 @@ nla_put_failure: }
static int nft_value_init(const struct nft_ctx *ctx, - struct nft_data *data, unsigned int size, - struct nft_data_desc *desc, const struct nlattr *nla) + struct nft_data *data, struct nft_data_desc *desc, + const struct nlattr *nla) { unsigned int len;
len = nla_len(nla); if (len == 0) return -EINVAL; - if (len > size) + if (len > desc->size) return -EOVERFLOW; + if (desc->len) { + if (len != desc->len) + return -EINVAL; + } else { + desc->len = len; + }
nla_memcpy(data->data, nla, len); - desc->type = NFT_DATA_VALUE; - desc->len = len; + return 0; }
@@ -9717,7 +9709,6 @@ static const struct nla_policy nft_data_ * * @ctx: context of the expression using the data * @data: destination struct nft_data - * @size: maximum data length * @desc: data description * @nla: netlink attribute containing data * @@ -9727,24 +9718,35 @@ static const struct nla_policy nft_data_ * The caller can indicate that it only wants to accept data of type * NFT_DATA_VALUE by passing NULL for the ctx argument. */ -int nft_data_init(const struct nft_ctx *ctx, - struct nft_data *data, unsigned int size, +int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, struct nft_data_desc *desc, const struct nlattr *nla) { struct nlattr *tb[NFTA_DATA_MAX + 1]; int err;
+ if (WARN_ON_ONCE(!desc->size)) + return -EINVAL; + err = nla_parse_nested_deprecated(tb, NFTA_DATA_MAX, nla, nft_data_policy, NULL); if (err < 0) return err;
- if (tb[NFTA_DATA_VALUE]) - return nft_value_init(ctx, data, size, desc, - tb[NFTA_DATA_VALUE]); - if (tb[NFTA_DATA_VERDICT] && ctx != NULL) - return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]); - return -EINVAL; + if (tb[NFTA_DATA_VALUE]) { + if (desc->type != NFT_DATA_VALUE) + return -EINVAL; + + err = nft_value_init(ctx, data, desc, tb[NFTA_DATA_VALUE]); + } else if (tb[NFTA_DATA_VERDICT] && ctx != NULL) { + if (desc->type != NFT_DATA_VERDICT) + return -EINVAL; + + err = nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]); + } else { + err = -EINVAL; + } + + return err; } EXPORT_SYMBOL_GPL(nft_data_init);
--- a/net/netfilter/nft_bitwise.c +++ b/net/netfilter/nft_bitwise.c @@ -93,7 +93,16 @@ static const struct nla_policy nft_bitwi static int nft_bitwise_init_bool(struct nft_bitwise *priv, const struct nlattr *const tb[]) { - struct nft_data_desc mask, xor; + struct nft_data_desc mask = { + .type = NFT_DATA_VALUE, + .size = sizeof(priv->mask), + .len = priv->len, + }; + struct nft_data_desc xor = { + .type = NFT_DATA_VALUE, + .size = sizeof(priv->xor), + .len = priv->len, + }; int err;
if (tb[NFTA_BITWISE_DATA]) @@ -103,37 +112,30 @@ static int nft_bitwise_init_bool(struct !tb[NFTA_BITWISE_XOR]) return -EINVAL;
- err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &mask, - tb[NFTA_BITWISE_MASK]); + err = nft_data_init(NULL, &priv->mask, &mask, tb[NFTA_BITWISE_MASK]); if (err < 0) return err; - if (mask.type != NFT_DATA_VALUE || mask.len != priv->len) { - err = -EINVAL; - goto err_mask_release; - }
- err = nft_data_init(NULL, &priv->xor, sizeof(priv->xor), &xor, - tb[NFTA_BITWISE_XOR]); + err = nft_data_init(NULL, &priv->xor, &xor, tb[NFTA_BITWISE_XOR]); if (err < 0) - goto err_mask_release; - if (xor.type != NFT_DATA_VALUE || xor.len != priv->len) { - err = -EINVAL; - goto err_xor_release; - } + goto err_xor_err;
return 0;
-err_xor_release: - nft_data_release(&priv->xor, xor.type); -err_mask_release: +err_xor_err: nft_data_release(&priv->mask, mask.type); + return err; }
static int nft_bitwise_init_shift(struct nft_bitwise *priv, const struct nlattr *const tb[]) { - struct nft_data_desc d; + struct nft_data_desc desc = { + .type = NFT_DATA_VALUE, + .size = sizeof(priv->data), + .len = sizeof(u32), + }; int err;
if (tb[NFTA_BITWISE_MASK] || @@ -143,13 +145,12 @@ static int nft_bitwise_init_shift(struct if (!tb[NFTA_BITWISE_DATA]) return -EINVAL;
- err = nft_data_init(NULL, &priv->data, sizeof(priv->data), &d, - tb[NFTA_BITWISE_DATA]); + err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_BITWISE_DATA]); if (err < 0) return err; - if (d.type != NFT_DATA_VALUE || d.len != sizeof(u32) || - priv->data.data[0] >= BITS_PER_TYPE(u32)) { - nft_data_release(&priv->data, d.type); + + if (priv->data.data[0] >= BITS_PER_TYPE(u32)) { + nft_data_release(&priv->data, desc.type); return -EINVAL; }
@@ -339,22 +340,21 @@ static const struct nft_expr_ops nft_bit static int nft_bitwise_extract_u32_data(const struct nlattr * const tb, u32 *out) { - struct nft_data_desc desc; struct nft_data data; - int err = 0; + struct nft_data_desc desc = { + .type = NFT_DATA_VALUE, + .size = sizeof(data), + .len = sizeof(u32), + }; + int err;
- err = nft_data_init(NULL, &data, sizeof(data), &desc, tb); + err = nft_data_init(NULL, &data, &desc, tb); if (err < 0) return err;
- if (desc.type != NFT_DATA_VALUE || desc.len != sizeof(u32)) { - err = -EINVAL; - goto err; - } *out = data.data[0]; -err: - nft_data_release(&data, desc.type); - return err; + + return 0; }
static int nft_bitwise_fast_init(const struct nft_ctx *ctx, --- a/net/netfilter/nft_cmp.c +++ b/net/netfilter/nft_cmp.c @@ -73,20 +73,16 @@ static int nft_cmp_init(const struct nft const struct nlattr * const tb[]) { struct nft_cmp_expr *priv = nft_expr_priv(expr); - struct nft_data_desc desc; + struct nft_data_desc desc = { + .type = NFT_DATA_VALUE, + .size = sizeof(priv->data), + }; int err;
- err = nft_data_init(NULL, &priv->data, sizeof(priv->data), &desc, - tb[NFTA_CMP_DATA]); + err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]); if (err < 0) return err;
- if (desc.type != NFT_DATA_VALUE) { - err = -EINVAL; - nft_data_release(&priv->data, desc.type); - return err; - } - err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len); if (err < 0) return err; @@ -202,12 +198,14 @@ static int nft_cmp_fast_init(const struc const struct nlattr * const tb[]) { struct nft_cmp_fast_expr *priv = nft_expr_priv(expr); - struct nft_data_desc desc; struct nft_data data; + struct nft_data_desc desc = { + .type = NFT_DATA_VALUE, + .size = sizeof(data), + }; int err;
- err = nft_data_init(NULL, &data, sizeof(data), &desc, - tb[NFTA_CMP_DATA]); + err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]); if (err < 0) return err;
@@ -301,11 +299,13 @@ static int nft_cmp16_fast_init(const str const struct nlattr * const tb[]) { struct nft_cmp16_fast_expr *priv = nft_expr_priv(expr); - struct nft_data_desc desc; + struct nft_data_desc desc = { + .type = NFT_DATA_VALUE, + .size = sizeof(priv->data), + }; int err;
- err = nft_data_init(NULL, &priv->data, sizeof(priv->data), &desc, - tb[NFTA_CMP_DATA]); + err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]); if (err < 0) return err;
@@ -368,8 +368,11 @@ const struct nft_expr_ops nft_cmp16_fast static const struct nft_expr_ops * nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[]) { - struct nft_data_desc desc; struct nft_data data; + struct nft_data_desc desc = { + .type = NFT_DATA_VALUE, + .size = sizeof(data), + }; enum nft_cmp_ops op; u8 sreg; int err; @@ -392,14 +395,10 @@ nft_cmp_select_ops(const struct nft_ctx return ERR_PTR(-EINVAL); }
- err = nft_data_init(NULL, &data, sizeof(data), &desc, - tb[NFTA_CMP_DATA]); + err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]); if (err < 0) return ERR_PTR(err);
- if (desc.type != NFT_DATA_VALUE) - goto err1; - sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
if (op == NFT_CMP_EQ || op == NFT_CMP_NEQ) { @@ -411,9 +410,6 @@ nft_cmp_select_ops(const struct nft_ctx return &nft_cmp16_fast_ops; } return &nft_cmp_ops; -err1: - nft_data_release(&data, desc.type); - return ERR_PTR(-EINVAL); }
struct nft_expr_type nft_cmp_type __read_mostly = { --- a/net/netfilter/nft_immediate.c +++ b/net/netfilter/nft_immediate.c @@ -29,20 +29,36 @@ static const struct nla_policy nft_immed [NFTA_IMMEDIATE_DATA] = { .type = NLA_NESTED }, };
+static enum nft_data_types nft_reg_to_type(const struct nlattr *nla) +{ + enum nft_data_types type; + u8 reg; + + reg = ntohl(nla_get_be32(nla)); + if (reg == NFT_REG_VERDICT) + type = NFT_DATA_VERDICT; + else + type = NFT_DATA_VALUE; + + return type; +} + static int nft_immediate_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { struct nft_immediate_expr *priv = nft_expr_priv(expr); - struct nft_data_desc desc; + struct nft_data_desc desc = { + .size = sizeof(priv->data), + }; int err;
if (tb[NFTA_IMMEDIATE_DREG] == NULL || tb[NFTA_IMMEDIATE_DATA] == NULL) return -EINVAL;
- err = nft_data_init(ctx, &priv->data, sizeof(priv->data), &desc, - tb[NFTA_IMMEDIATE_DATA]); + desc.type = nft_reg_to_type(tb[NFTA_IMMEDIATE_DREG]); + err = nft_data_init(ctx, &priv->data, &desc, tb[NFTA_IMMEDIATE_DATA]); if (err < 0) return err;
--- a/net/netfilter/nft_range.c +++ b/net/netfilter/nft_range.c @@ -51,7 +51,14 @@ static int nft_range_init(const struct n const struct nlattr * const tb[]) { struct nft_range_expr *priv = nft_expr_priv(expr); - struct nft_data_desc desc_from, desc_to; + struct nft_data_desc desc_from = { + .type = NFT_DATA_VALUE, + .size = sizeof(priv->data_from), + }; + struct nft_data_desc desc_to = { + .type = NFT_DATA_VALUE, + .size = sizeof(priv->data_to), + }; int err; u32 op;
@@ -61,26 +68,16 @@ static int nft_range_init(const struct n !tb[NFTA_RANGE_TO_DATA]) return -EINVAL;
- err = nft_data_init(NULL, &priv->data_from, sizeof(priv->data_from), - &desc_from, tb[NFTA_RANGE_FROM_DATA]); + err = nft_data_init(NULL, &priv->data_from, &desc_from, + tb[NFTA_RANGE_FROM_DATA]); if (err < 0) return err;
- if (desc_from.type != NFT_DATA_VALUE) { - err = -EINVAL; - goto err1; - } - - err = nft_data_init(NULL, &priv->data_to, sizeof(priv->data_to), - &desc_to, tb[NFTA_RANGE_TO_DATA]); + err = nft_data_init(NULL, &priv->data_to, &desc_to, + tb[NFTA_RANGE_TO_DATA]); if (err < 0) goto err1;
- if (desc_to.type != NFT_DATA_VALUE) { - err = -EINVAL; - goto err2; - } - if (desc_from.len != desc_to.len) { err = -EINVAL; goto err2;
From: Pablo Neira Ayuso pablo@netfilter.org
commit f323ef3a0d49e147365284bc1f02212e617b7f09 upstream.
Extend struct nft_data_desc to add a flag field that specifies nft_data_init() is being called for set element data.
Use it to disallow jump to implicit chain from set element, only jump to chain via immediate expression is allowed.
Fixes: d0e2c7de92c7 ("netfilter: nf_tables: add NFT_CHAIN_BINDING") 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 | 4 ++++ 2 files changed, 9 insertions(+)
--- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -206,10 +206,15 @@ struct nft_ctx { bool report; };
+enum nft_data_desc_flags { + NFT_DATA_DESC_SETELEM = (1 << 0), +}; + struct nft_data_desc { enum nft_data_types type; unsigned int size; unsigned int len; + unsigned int flags; };
int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -5226,6 +5226,7 @@ static int nft_setelem_parse_data(struct desc->type = dtype; desc->size = NFT_DATA_VALUE_MAXLEN; desc->len = set->dlen; + desc->flags = NFT_DATA_DESC_SETELEM;
return nft_data_init(ctx, data, desc, attr); } @@ -9611,6 +9612,9 @@ static int nft_verdict_init(const struct return PTR_ERR(chain); if (nft_is_base_chain(chain)) return -EOPNOTSUPP; + if (desc->flags & NFT_DATA_DESC_SETELEM && + chain->flags & NFT_CHAIN_BINDING) + return -EINVAL;
chain->use++; data->verdict.chain = chain;
From: Florian Westphal fw@strlen.de
commit 580077855a40741cf511766129702d97ff02f4d9 upstream.
In nf_tables_updtable, if nf_tables_table_enable returns an error, nft_trans_destroy is called to free the transaction object.
nft_trans_destroy() calls list_del(), but the transaction was never placed on a list -- the list head is all zeroes, this results in a null dereference:
BUG: KASAN: null-ptr-deref in nft_trans_destroy+0x26/0x59 Call Trace: nft_trans_destroy+0x26/0x59 nf_tables_newtable+0x4bc/0x9bc [..]
Its sane to assume that nft_trans_destroy() can be called on the transaction object returned by nft_trans_alloc(), so make sure the list head is initialised.
Fixes: 55dd6f93076b ("netfilter: nf_tables: use new transaction infrastructure to handle table") Reported-by: mingi cho mgcho.minic@gmail.com Signed-off-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 | 1 + 1 file changed, 1 insertion(+)
--- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -153,6 +153,7 @@ static struct nft_trans *nft_trans_alloc if (trans == NULL) return NULL;
+ INIT_LIST_HEAD(&trans->list); trans->msg_type = msg_type; trans->ctx = *ctx;
From: Benjamin Segall bsegall@google.com
commit a16ceb13961068f7209e34d7984f8e42d2c06159 upstream.
If a process is killed or otherwise exits while having active network connections and many threads waiting on epoll_wait, the threads will all be woken immediately, but not removed from ep->wq. Then when network traffic scans ep->wq in wake_up, every wakeup attempt will fail, and will not remove the entries from the list.
This means that the cost of the wakeup attempt is far higher than usual, does not decrease, and this also competes with the dying threads trying to actually make progress and remove themselves from the wq.
Handle this by removing visited epoll wq entries unconditionally, rather than only when the wakeup succeeds - the structure of ep_poll means that the only potential loss is the timed_out->eavail heuristic, which now can race and result in a redundant ep_send_events attempt. (But only when incoming data and a timeout actually race, not on every timeout)
Shakeel added:
: We are seeing this issue in production with real workloads and it has : caused hard lockups. Particularly network heavy workloads with a lot : of threads in epoll_wait() can easily trigger this issue if they get : killed (oom-killed in our case).
Link: https://lkml.kernel.org/r/xm26fsjotqda.fsf@google.com Signed-off-by: Ben Segall bsegall@google.com Tested-by: Shakeel Butt shakeelb@google.com Cc: Alexander Viro viro@zeniv.linux.org.uk Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Shakeel Butt shakeelb@google.com Cc: Eric Dumazet edumazet@google.com Cc: Roman Penyaev rpenyaev@suse.de Cc: Jason Baron jbaron@akamai.com Cc: Khazhismel Kumykov khazhy@google.com Cc: Heiher r@hev.cc Cc: stable@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/eventpoll.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
--- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1747,6 +1747,21 @@ static struct timespec64 *ep_timeout_to_ return to; }
+/* + * autoremove_wake_function, but remove even on failure to wake up, because we + * know that default_wake_function/ttwu will only fail if the thread is already + * woken, and in that case the ep_poll loop will remove the entry anyways, not + * try to reuse it. + */ +static int ep_autoremove_wake_function(struct wait_queue_entry *wq_entry, + unsigned int mode, int sync, void *key) +{ + int ret = default_wake_function(wq_entry, mode, sync, key); + + list_del_init(&wq_entry->entry); + return ret; +} + /** * ep_poll - Retrieves ready events, and delivers them to the caller-supplied * event buffer. @@ -1828,8 +1843,15 @@ static int ep_poll(struct eventpoll *ep, * normal wakeup path no need to call __remove_wait_queue() * explicitly, thus ep->lock is not taken, which halts the * event delivery. + * + * In fact, we now use an even more aggressive function that + * unconditionally removes, because we don't reuse the wait + * entry between loop iterations. This lets us also avoid the + * performance issue if a process is killed, causing all of its + * threads to wake up without being removed normally. */ init_wait(&wait); + wait.func = ep_autoremove_wake_function;
write_lock_irq(&ep->lock); /*
From: Wyes Karny wyes.karny@amd.com
[ Upstream commit 8bcedb4ce04750e1ccc9a6b6433387f6a9166a56 ]
When kernel is booted with idle=nomwait do not use MWAIT as the default idle state.
If the user boots the kernel with idle=nomwait, it is a clear direction to not use mwait as the default idle state. However, the current code does not take this into consideration while selecting the default idle state on x86.
Fix it by checking for the idle=nomwait boot option in prefer_mwait_c1_over_halt().
Also update the documentation around idle=nomwait appropriately.
[ dhansen: tweak commit message ]
Signed-off-by: Wyes Karny wyes.karny@amd.com Signed-off-by: Dave Hansen dave.hansen@linux.intel.com Tested-by: Zhang Rui rui.zhang@intel.com Link: https://lkml.kernel.org/r/fdc2dc2d0a1bc21c2f53d989ea2d2ee3ccbc0dbe.165453838... Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/admin-guide/pm/cpuidle.rst | 15 +++++++++------ arch/x86/kernel/process.c | 9 ++++++--- 2 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/Documentation/admin-guide/pm/cpuidle.rst b/Documentation/admin-guide/pm/cpuidle.rst index aec2cd2aaea7..19754beb5a4e 100644 --- a/Documentation/admin-guide/pm/cpuidle.rst +++ b/Documentation/admin-guide/pm/cpuidle.rst @@ -612,8 +612,8 @@ the ``menu`` governor to be used on the systems that use the ``ladder`` governor by default this way, for example.
The other kernel command line parameters controlling CPU idle time management -described below are only relevant for the *x86* architecture and some of -them affect Intel processors only. +described below are only relevant for the *x86* architecture and references +to ``intel_idle`` affect Intel processors only.
The *x86* architecture support code recognizes three kernel command line options related to CPU idle time management: ``idle=poll``, ``idle=halt``, @@ -635,10 +635,13 @@ idle, so it very well may hurt single-thread computations performance as well as energy-efficiency. Thus using it for performance reasons may not be a good idea at all.]
-The ``idle=nomwait`` option disables the ``intel_idle`` driver and causes -``acpi_idle`` to be used (as long as all of the information needed by it is -there in the system's ACPI tables), but it is not allowed to use the -``MWAIT`` instruction of the CPUs to ask the hardware to enter idle states. +The ``idle=nomwait`` option prevents the use of ``MWAIT`` instruction of +the CPU to enter idle states. When this option is used, the ``acpi_idle`` +driver will use the ``HLT`` instruction instead of ``MWAIT``. On systems +running Intel processors, this option disables the ``intel_idle`` driver +and forces the use of the ``acpi_idle`` driver instead. Note that in either +case, ``acpi_idle`` driver will function only if all the information needed +by it is in the system's ACPI tables.
In addition to the architecture-level kernel command line options affecting CPU idle time management, there are parameters affecting individual ``CPUIdle`` diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index d456ce21c255..9346c95e8879 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -821,6 +821,10 @@ static void amd_e400_idle(void) */ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c) { + /* User has disallowed the use of MWAIT. Fallback to HALT */ + if (boot_option_idle_override == IDLE_NOMWAIT) + return 0; + if (c->x86_vendor != X86_VENDOR_INTEL) return 0;
@@ -932,9 +936,8 @@ static int __init idle_setup(char *str) } else if (!strcmp(str, "nomwait")) { /* * If the boot option of "idle=nomwait" is added, - * it means that mwait will be disabled for CPU C2/C3 - * states. In such case it won't touch the variable - * of boot_option_idle_override. + * it means that mwait will be disabled for CPU C1/C2/C3 + * states. */ boot_option_idle_override = IDLE_NOMWAIT; } else
From: Mark Rutland mark.rutland@arm.com
[ Upstream commit 4510bffb4d0246cdcc1f14c7367c026b807a862d ]
On most architectures, IRQ flag tracing is disabled in NMI context, and architectures need to define and select TRACE_IRQFLAGS_NMI_SUPPORT in order to enable this.
Commit:
859d069ee1ddd878 ("lockdep: Prepare for NMI IRQ state tracking")
Permitted IRQ flag tracing in NMI context, allowing lockdep to work in NMI context where an architecture had suitable entry logic. At the time, most architectures did not have such suitable entry logic, and this broke lockdep on such architectures. Thus, this was partially disabled in commit:
ed00495333ccc80f ("locking/lockdep: Fix TRACE_IRQFLAGS vs. NMIs")
... with architectures needing to select TRACE_IRQFLAGS_NMI_SUPPORT to enable IRQ flag tracing in NMI context.
Currently TRACE_IRQFLAGS_NMI_SUPPORT is defined under arch/x86/Kconfig.debug. Move it to arch/Kconfig so architectures can select it without having to provide their own definition.
Since the regular TRACE_IRQFLAGS_SUPPORT is selected by arch/x86/Kconfig, the select of TRACE_IRQFLAGS_NMI_SUPPORT is moved there too.
There should be no functional change as a result of this patch.
Signed-off-by: Mark Rutland mark.rutland@arm.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Ingo Molnar mingo@kernel.org Cc: Peter Zijlstra (Intel) peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Will Deacon will@kernel.org Link: https://lore.kernel.org/r/20220511131733.4074499-2-mark.rutland@arm.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/Kconfig | 3 +++ arch/x86/Kconfig | 1 + arch/x86/Kconfig.debug | 3 --- 3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig index 71b9272acb28..5ea3e3838c21 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -223,6 +223,9 @@ config HAVE_FUNCTION_DESCRIPTORS config TRACE_IRQFLAGS_SUPPORT bool
+config TRACE_IRQFLAGS_NMI_SUPPORT + bool + # # An arch should select this if it provides all these things: # diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 52a7f91527fe..25e2b8b75e40 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -278,6 +278,7 @@ config X86 select SYSCTL_EXCEPTION_TRACE select THREAD_INFO_IN_TASK select TRACE_IRQFLAGS_SUPPORT + select TRACE_IRQFLAGS_NMI_SUPPORT select USER_STACKTRACE_SUPPORT select VIRT_TO_BUS select HAVE_ARCH_KCSAN if X86_64 diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 340399f69954..bdfe08f1a930 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -1,8 +1,5 @@ # SPDX-License-Identifier: GPL-2.0
-config TRACE_IRQFLAGS_NMI_SUPPORT - def_bool y - config EARLY_PRINTK_USB bool
From: Andrey Konovalov andreyknvl@google.com
[ Upstream commit 802b91118d11227b527153849ea761b280691373 ]
Disable KASAN instrumentation of arch/arm64/kernel/stacktrace.c.
This speeds up Generic KASAN by 5-20%.
As a side-effect, KASAN is now unable to detect bugs in the stack trace collection code. This is taken as an acceptable downside.
Also replace READ_ONCE_NOCHECK() with READ_ONCE() in stacktrace.c. As the file is now not instrumented, there is no need to use the NOCHECK version of READ_ONCE().
Suggested-by: Mark Rutland mark.rutland@arm.com Acked-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Andrey Konovalov andreyknvl@google.com Link: https://lore.kernel.org/r/c4c944a2a905e949760fbeb29258185087171708.165331746... Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/Makefile | 5 +++++ arch/arm64/kernel/stacktrace.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index fa7981d0d917..7075a9c6a4a6 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -14,6 +14,11 @@ CFLAGS_REMOVE_return_address.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_syscall.o = -fstack-protector -fstack-protector-strong CFLAGS_syscall.o += -fno-stack-protector
+# When KASAN is enabled, a stack trace is recorded for every alloc/free, which +# can significantly impact performance. Avoid instrumenting the stack trace +# collection code to minimize this impact. +KASAN_SANITIZE_stacktrace.o := n + # It's not safe to invoke KCOV when portions of the kernel environment aren't # available or are out-of-sync with HW state. Since `noinstr` doesn't always # inhibit KCOV instrumentation, disable it for the entire compilation unit. diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 0467cb79f080..c246e8d9f95b 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -124,8 +124,8 @@ static int notrace unwind_next(struct task_struct *tsk, * Record this frame record's values and location. The prev_fp and * prev_type are only meaningful to the next unwind_next() invocation. */ - state->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp)); - state->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8)); + state->fp = READ_ONCE(*(unsigned long *)(fp)); + state->pc = READ_ONCE(*(unsigned long *)(fp + 8)); state->prev_fp = fp; state->prev_type = info.type;
From: Andrey Konovalov andreyknvl@google.com
[ Upstream commit 446297b28a21244e4045026c4599d1b14a67e2ce ]
Use the non-atomic version of set_bit() in arch/arm64/kernel/stacktrace.c, as there is no concurrent accesses to frame->prev_type.
This speeds up stack trace collection and improves the boot time of Generic KASAN by 2-5%.
Suggested-by: Mark Rutland mark.rutland@arm.com Acked-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Andrey Konovalov andreyknvl@google.com Link: https://lore.kernel.org/r/23dfa36d1cc91e4a1059945b7834eac22fb9854d.165331746... Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/stacktrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index c246e8d9f95b..d6bef106e37e 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -117,7 +117,7 @@ static int notrace unwind_next(struct task_struct *tsk, if (fp <= state->prev_fp) return -EINVAL; } else { - set_bit(state->prev_type, state->stacks_done); + __set_bit(state->prev_type, state->stacks_done); }
/*
From: Francis Laniel flaniel@linux.microsoft.com
[ Upstream commit de6921856f99c11d3986c6702d851e1328d4f7f6 ]
Enable tracing of the execve*() system calls with the syscalls:sys_exit_execve tracepoint by removing the call to forget_syscall() when starting a new thread and preserving the value of regs->syscallno across exec.
Signed-off-by: Francis Laniel flaniel@linux.microsoft.com Link: https://lore.kernel.org/r/20220608162447.666494-2-flaniel@linux.microsoft.co... Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/include/asm/processor.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 9e58749db21d..86eb0bfe3b38 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -272,8 +272,9 @@ void tls_preserve_current_state(void);
static inline void start_thread_common(struct pt_regs *regs, unsigned long pc) { + s32 previous_syscall = regs->syscallno; memset(regs, 0, sizeof(*regs)); - forget_syscall(regs); + regs->syscallno = previous_syscall; regs->pc = pc;
if (system_uses_irq_prio_masking())
From: haibinzhang (张海斌) haibinzhang@tencent.com
[ Upstream commit af483947d472eccb79e42059276c4deed76f99a6 ]
emulation_proc_handler() changes table->data for proc_dointvec_minmax and can generate the following Oops if called concurrently with itself:
| Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 | Internal error: Oops: 96000006 [#1] SMP | Call trace: | update_insn_emulation_mode+0xc0/0x148 | emulation_proc_handler+0x64/0xb8 | proc_sys_call_handler+0x9c/0xf8 | proc_sys_write+0x18/0x20 | __vfs_write+0x20/0x48 | vfs_write+0xe4/0x1d0 | ksys_write+0x70/0xf8 | __arm64_sys_write+0x20/0x28 | el0_svc_common.constprop.0+0x7c/0x1c0 | el0_svc_handler+0x2c/0xa0 | el0_svc+0x8/0x200
To fix this issue, keep the table->data as &insn->current_mode and use container_of() to retrieve the insn pointer. Another mutex is used to protect against the current_mode update but not for retrieving insn_emulation as table->data is no longer changing.
Co-developed-by: hewenliang hewenliang4@huawei.com Signed-off-by: hewenliang hewenliang4@huawei.com Signed-off-by: Haibin Zhang haibinzhang@tencent.com Reviewed-by: Catalin Marinas catalin.marinas@arm.com Link: https://lore.kernel.org/r/20220128090324.2727688-1-hewenliang4@huawei.com Link: https://lore.kernel.org/r/9A004C03-250B-46C5-BF39-782D7551B00E@tencent.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/armv8_deprecated.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c index 6875a16b09d2..fb0e7c7b2e20 100644 --- a/arch/arm64/kernel/armv8_deprecated.c +++ b/arch/arm64/kernel/armv8_deprecated.c @@ -59,6 +59,7 @@ struct insn_emulation { static LIST_HEAD(insn_emulation); static int nr_insn_emulated __initdata; static DEFINE_RAW_SPINLOCK(insn_emulation_lock); +static DEFINE_MUTEX(insn_emulation_mutex);
static void register_emulation_hooks(struct insn_emulation_ops *ops) { @@ -207,10 +208,10 @@ static int emulation_proc_handler(struct ctl_table *table, int write, loff_t *ppos) { int ret = 0; - struct insn_emulation *insn = (struct insn_emulation *) table->data; + struct insn_emulation *insn = container_of(table->data, struct insn_emulation, current_mode); enum insn_emulation_mode prev_mode = insn->current_mode;
- table->data = &insn->current_mode; + mutex_lock(&insn_emulation_mutex); ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
if (ret || !write || prev_mode == insn->current_mode) @@ -223,7 +224,7 @@ static int emulation_proc_handler(struct ctl_table *table, int write, update_insn_emulation_mode(insn, INSN_UNDEF); } ret: - table->data = insn; + mutex_unlock(&insn_emulation_mutex); return ret; }
@@ -247,7 +248,7 @@ static void __init register_insn_emulation_sysctl(void) sysctl->maxlen = sizeof(int);
sysctl->procname = insn->ops->name; - sysctl->data = insn; + sysctl->data = &insn->current_mode; sysctl->extra1 = &insn->min; sysctl->extra2 = &insn->max; sysctl->proc_handler = emulation_proc_handler;
From: Catalin Marinas catalin.marinas@arm.com
[ Upstream commit 20794545c14692094a882d2221c251c4573e6adf ]
This reverts commit e5b8d9218951e59df986f627ec93569a0d22149b.
Pages mapped in user-space with PROT_MTE have the allocation tags either zeroed or copied/restored to some user values. In order for the kernel to access such pages via page_address(), resetting the tag in page->flags was necessary. This tag resetting was deferred to set_pte_at() -> mte_sync_page_tags() but it can race with another CPU reading the flags (via page_to_virt()):
P0 (mte_sync_page_tags): P1 (memcpy from virt_to_page): Rflags!=0xff Wflags=0xff DMB (doesn't help) Wtags=0 Rtags=0 // fault
Since now the post_alloc_hook() function resets the page->flags tag when unpoisoning is skipped for user pages (including the __GFP_ZEROTAGS case), revert the arm64 commit calling page_kasan_tag_reset().
Signed-off-by: Catalin Marinas catalin.marinas@arm.com Cc: Will Deacon will@kernel.org Cc: Vincenzo Frascino vincenzo.frascino@arm.com Cc: Andrey Konovalov andreyknvl@gmail.com Cc: Peter Collingbourne pcc@google.com Reviewed-by: Vincenzo Frascino vincenzo.frascino@arm.com Acked-by: Andrey Konovalov andreyknvl@gmail.com Link: https://lore.kernel.org/r/20220610152141.2148929-5-catalin.marinas@arm.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/hibernate.c | 5 ----- arch/arm64/kernel/mte.c | 9 --------- arch/arm64/mm/copypage.c | 9 --------- arch/arm64/mm/mteswap.c | 9 --------- 4 files changed, 32 deletions(-)
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index 2e248342476e..af5df48ba915 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -300,11 +300,6 @@ static void swsusp_mte_restore_tags(void) unsigned long pfn = xa_state.xa_index; struct page *page = pfn_to_online_page(pfn);
- /* - * It is not required to invoke page_kasan_tag_reset(page) - * at this point since the tags stored in page->flags are - * already restored. - */ mte_restore_page_tags(page_address(page), tags);
mte_free_tag_storage(tags); diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index f6b00743c399..b2b730233274 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -48,15 +48,6 @@ static void mte_sync_page_tags(struct page *page, pte_t old_pte, if (!pte_is_tagged) return;
- page_kasan_tag_reset(page); - /* - * We need smp_wmb() in between setting the flags and clearing the - * tags because if another thread reads page->flags and builds a - * tagged address out of it, there is an actual dependency to the - * memory access, but on the current thread we do not guarantee that - * the new page->flags are visible before the tags were updated. - */ - smp_wmb(); mte_clear_page_tags(page_address(page)); }
diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c index 0dea80bf6de4..24913271e898 100644 --- a/arch/arm64/mm/copypage.c +++ b/arch/arm64/mm/copypage.c @@ -23,15 +23,6 @@ void copy_highpage(struct page *to, struct page *from)
if (system_supports_mte() && test_bit(PG_mte_tagged, &from->flags)) { set_bit(PG_mte_tagged, &to->flags); - page_kasan_tag_reset(to); - /* - * We need smp_wmb() in between setting the flags and clearing the - * tags because if another thread reads page->flags and builds a - * tagged address out of it, there is an actual dependency to the - * memory access, but on the current thread we do not guarantee that - * the new page->flags are visible before the tags were updated. - */ - smp_wmb(); mte_copy_page_tags(kto, kfrom); } } diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c index a9e50e930484..4334dec93bd4 100644 --- a/arch/arm64/mm/mteswap.c +++ b/arch/arm64/mm/mteswap.c @@ -53,15 +53,6 @@ bool mte_restore_tags(swp_entry_t entry, struct page *page) if (!tags) return false;
- page_kasan_tag_reset(page); - /* - * We need smp_wmb() in between setting the flags and clearing the - * tags because if another thread reads page->flags and builds a - * tagged address out of it, there is an actual dependency to the - * memory access, but on the current thread we do not guarantee that - * the new page->flags are visible before the tags were updated. - */ - smp_wmb(); mte_restore_page_tags(page_address(page), tags);
return true;
From: James Morse james.morse@arm.com
[ Upstream commit 44b3834b2eed595af07021b1c64e6f9bc396398b ]
Cortex-A57 and Cortex-A72 have an erratum where an interrupt that occurs between a pair of AES instructions in aarch32 mode may corrupt the ELR. The task will subsequently produce the wrong AES result.
The AES instructions are part of the cryptographic extensions, which are optional. User-space software will detect the support for these instructions from the hwcaps. If the platform doesn't support these instructions a software implementation should be used.
Remove the hwcap bits on affected parts to indicate user-space should not use the AES instructions.
Acked-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: James Morse james.morse@arm.com Link: https://lore.kernel.org/r/20220714161523.279570-3-james.morse@arm.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/arm64/silicon-errata.rst | 4 ++++ arch/arm64/Kconfig | 16 ++++++++++++++++ arch/arm64/kernel/cpu_errata.c | 16 ++++++++++++++++ arch/arm64/kernel/cpufeature.c | 14 +++++++++++++- arch/arm64/tools/cpucaps | 1 + 5 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index d27db84d585e..0b4235b1f8c4 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -82,10 +82,14 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A57 | #1319537 | ARM64_ERRATUM_1319367 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A57 | #1742098 | ARM64_ERRATUM_1742098 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A72 | #853709 | N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A72 | #1319367 | ARM64_ERRATUM_1319367 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A72 | #1655431 | ARM64_ERRATUM_1742098 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A76 | #1188873,1418040| ARM64_ERRATUM_1418040 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 1652a9800ebe..3ad734de8e49 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -503,6 +503,22 @@ config ARM64_ERRATUM_834220
If unsure, say Y.
+config ARM64_ERRATUM_1742098 + bool "Cortex-A57/A72: 1742098: ELR recorded incorrectly on interrupt taken between cryptographic instructions in a sequence" + depends on COMPAT + default y + help + This option removes the AES hwcap for aarch32 user-space to + workaround erratum 1742098 on Cortex-A57 and Cortex-A72. + + Affected parts may corrupt the AES state if an interrupt is + taken between a pair of AES instructions. These instructions + are only present if the cryptography extensions are present. + All software should have a fallback implementation for CPUs + that don't implement the cryptography extensions. + + If unsure, say Y. + config ARM64_ERRATUM_845719 bool "Cortex-A53: 845719: a load might read incorrect data" depends on COMPAT diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index c05cc3b6162e..6b92989f4cc2 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -395,6 +395,14 @@ static struct midr_range trbe_write_out_of_range_cpus[] = { }; #endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
+#ifdef CONFIG_ARM64_ERRATUM_1742098 +static struct midr_range broken_aarch32_aes[] = { + MIDR_RANGE(MIDR_CORTEX_A57, 0, 1, 0xf, 0xf), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A72), + {}, +}; +#endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */ + const struct arm64_cpu_capabilities arm64_errata[] = { #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE { @@ -657,6 +665,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { /* Cortex-A510 r0p0 - r0p1 */ ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 1) }, +#endif +#ifdef CONFIG_ARM64_ERRATUM_1742098 + { + .desc = "ARM erratum 1742098", + .capability = ARM64_WORKAROUND_1742098, + CAP_MIDR_RANGE_LIST(broken_aarch32_aes), + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + }, #endif { } diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 8d88433de81d..90018643d424 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -79,6 +79,7 @@ #include <asm/cpufeature.h> #include <asm/cpu_ops.h> #include <asm/fpsimd.h> +#include <asm/hwcap.h> #include <asm/insn.h> #include <asm/kvm_host.h> #include <asm/mmu_context.h> @@ -1971,6 +1972,14 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) } #endif /* CONFIG_ARM64_MTE */
+static void elf_hwcap_fixup(void) +{ +#ifdef CONFIG_ARM64_ERRATUM_1742098 + if (cpus_have_const_cap(ARM64_WORKAROUND_1742098)) + compat_elf_hwcap2 &= ~COMPAT_HWCAP2_AES; +#endif /* ARM64_ERRATUM_1742098 */ +} + #ifdef CONFIG_KVM static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused) { @@ -3143,8 +3152,10 @@ void __init setup_cpu_features(void) setup_system_capabilities(); setup_elf_hwcaps(arm64_elf_hwcaps);
- if (system_supports_32bit_el0()) + if (system_supports_32bit_el0()) { setup_elf_hwcaps(compat_elf_hwcaps); + elf_hwcap_fixup(); + }
if (system_uses_ttbr0_pan()) pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n"); @@ -3197,6 +3208,7 @@ static int enable_mismatched_32bit_el0(unsigned int cpu) cpu_active_mask); get_cpu_device(lucky_winner)->offline_disabled = true; setup_elf_hwcaps(compat_elf_hwcaps); + elf_hwcap_fixup(); pr_info("Asymmetric 32-bit EL0 support detected on CPU %u; CPU hot-unplug disabled on CPU %u\n", cpu, lucky_winner); return 0; diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 507b20373953..8809e14cf86a 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -61,6 +61,7 @@ WORKAROUND_1418040 WORKAROUND_1463225 WORKAROUND_1508412 WORKAROUND_1542419 +WORKAROUND_1742098 WORKAROUND_1902691 WORKAROUND_2038923 WORKAROUND_2064142
From: Jan Kara jack@suse.cz
[ Upstream commit fa78f336937240d1bc598db817d638086060e7e9 ]
Add checks verifying number of inodes stored in the superblock matches the number computed from number of inodes per group. Also verify we have at least one block worth of inodes per group. This prevents crashes on corrupted filesystems.
Reported-by: syzbot+d273f7d7f58afd93be48@syzkaller.appspotmail.com Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ext2/super.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index f6a19f6d9f6d..cdffa2a041af 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -1059,9 +1059,10 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) sbi->s_frags_per_group); goto failed_mount; } - if (sbi->s_inodes_per_group > sb->s_blocksize * 8) { + if (sbi->s_inodes_per_group < sbi->s_inodes_per_block || + sbi->s_inodes_per_group > sb->s_blocksize * 8) { ext2_msg(sb, KERN_ERR, - "error: #inodes per group too big: %lu", + "error: invalid #inodes per group: %lu", sbi->s_inodes_per_group); goto failed_mount; } @@ -1071,6 +1072,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) - le32_to_cpu(es->s_first_data_block) - 1) / EXT2_BLOCKS_PER_GROUP(sb)) + 1; + if ((u64)sbi->s_groups_count * sbi->s_inodes_per_group != + le32_to_cpu(es->s_inodes_count)) { + ext2_msg(sb, KERN_ERR, "error: invalid #inodes: %u vs computed %llu", + le32_to_cpu(es->s_inodes_count), + (u64)sbi->s_groups_count * sbi->s_inodes_per_group); + goto failed_mount; + } db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) / EXT2_DESC_PER_BLOCK(sb); sbi->s_group_desc = kmalloc_array(db_count,
From: Chen Yu yu.c.chen@intel.com
[ Upstream commit 70fb5ccf2ebb09a0c8ebba775041567812d45f86 ]
[Problem Statement] select_idle_cpu() might spend too much time searching for an idle CPU, when the system is overloaded.
The following histogram is the time spent in select_idle_cpu(), when running 224 instances of netperf on a system with 112 CPUs per LLC domain:
@usecs: [0] 533 | | [1] 5495 | | [2, 4) 12008 | | [4, 8) 239252 | | [8, 16) 4041924 |@@@@@@@@@@@@@@ | [16, 32) 12357398 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | [32, 64) 14820255 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| [64, 128) 13047682 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | [128, 256) 8235013 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | [256, 512) 4507667 |@@@@@@@@@@@@@@@ | [512, 1K) 2600472 |@@@@@@@@@ | [1K, 2K) 927912 |@@@ | [2K, 4K) 218720 | | [4K, 8K) 98161 | | [8K, 16K) 37722 | | [16K, 32K) 6715 | | [32K, 64K) 477 | | [64K, 128K) 7 | |
netperf latency usecs: ======= case load Lat_99th std% TCP_RR thread-224 257.39 ( 0.21)
The time spent in select_idle_cpu() is visible to netperf and might have a negative impact.
[Symptom analysis] The patch [1] from Mel Gorman has been applied to track the efficiency of select_idle_sibling. Copy the indicators here:
SIS Search Efficiency(se_eff%): A ratio expressed as a percentage of runqueues scanned versus idle CPUs found. A 100% efficiency indicates that the target, prev or recent CPU of a task was idle at wakeup. The lower the efficiency, the more runqueues were scanned before an idle CPU was found.
SIS Domain Search Efficiency(dom_eff%): Similar, except only for the slower SIS patch.
SIS Fast Success Rate(fast_rate%): Percentage of SIS that used target, prev or recent CPUs.
SIS Success rate(success_rate%): Percentage of scans that found an idle CPU.
The test is based on Aubrey's schedtests tool, including netperf, hackbench, schbench and tbench.
Test on vanilla kernel: schedstat_parse.py -f netperf_vanilla.log case load se_eff% dom_eff% fast_rate% success_rate% TCP_RR 28 threads 99.978 18.535 99.995 100.000 TCP_RR 56 threads 99.397 5.671 99.964 100.000 TCP_RR 84 threads 21.721 6.818 73.632 100.000 TCP_RR 112 threads 12.500 5.533 59.000 100.000 TCP_RR 140 threads 8.524 4.535 49.020 100.000 TCP_RR 168 threads 6.438 3.945 40.309 99.999 TCP_RR 196 threads 5.397 3.718 32.320 99.982 TCP_RR 224 threads 4.874 3.661 25.775 99.767 UDP_RR 28 threads 99.988 17.704 99.997 100.000 UDP_RR 56 threads 99.528 5.977 99.970 100.000 UDP_RR 84 threads 24.219 6.992 76.479 100.000 UDP_RR 112 threads 13.907 5.706 62.538 100.000 UDP_RR 140 threads 9.408 4.699 52.519 100.000 UDP_RR 168 threads 7.095 4.077 44.352 100.000 UDP_RR 196 threads 5.757 3.775 35.764 99.991 UDP_RR 224 threads 5.124 3.704 28.748 99.860
schedstat_parse.py -f schbench_vanilla.log (each group has 28 tasks) case load se_eff% dom_eff% fast_rate% success_rate% normal 1 mthread 99.152 6.400 99.941 100.000 normal 2 mthreads 97.844 4.003 99.908 100.000 normal 3 mthreads 96.395 2.118 99.917 99.998 normal 4 mthreads 55.288 1.451 98.615 99.804 normal 5 mthreads 7.004 1.870 45.597 61.036 normal 6 mthreads 3.354 1.346 20.777 34.230 normal 7 mthreads 2.183 1.028 11.257 21.055 normal 8 mthreads 1.653 0.825 7.849 15.549
schedstat_parse.py -f hackbench_vanilla.log (each group has 28 tasks) case load se_eff% dom_eff% fast_rate% success_rate% process-pipe 1 group 99.991 7.692 99.999 100.000 process-pipe 2 groups 99.934 4.615 99.997 100.000 process-pipe 3 groups 99.597 3.198 99.987 100.000 process-pipe 4 groups 98.378 2.464 99.958 100.000 process-pipe 5 groups 27.474 3.653 89.811 99.800 process-pipe 6 groups 20.201 4.098 82.763 99.570 process-pipe 7 groups 16.423 4.156 77.398 99.316 process-pipe 8 groups 13.165 3.920 72.232 98.828 process-sockets 1 group 99.977 5.882 99.999 100.000 process-sockets 2 groups 99.927 5.505 99.996 100.000 process-sockets 3 groups 99.397 3.250 99.980 100.000 process-sockets 4 groups 79.680 4.258 98.864 99.998 process-sockets 5 groups 7.673 2.503 63.659 92.115 process-sockets 6 groups 4.642 1.584 58.946 88.048 process-sockets 7 groups 3.493 1.379 49.816 81.164 process-sockets 8 groups 3.015 1.407 40.845 75.500 threads-pipe 1 group 99.997 0.000 100.000 100.000 threads-pipe 2 groups 99.894 2.932 99.997 100.000 threads-pipe 3 groups 99.611 4.117 99.983 100.000 threads-pipe 4 groups 97.703 2.624 99.937 100.000 threads-pipe 5 groups 22.919 3.623 87.150 99.764 threads-pipe 6 groups 18.016 4.038 80.491 99.557 threads-pipe 7 groups 14.663 3.991 75.239 99.247 threads-pipe 8 groups 12.242 3.808 70.651 98.644 threads-sockets 1 group 99.990 6.667 99.999 100.000 threads-sockets 2 groups 99.940 5.114 99.997 100.000 threads-sockets 3 groups 99.469 4.115 99.977 100.000 threads-sockets 4 groups 87.528 4.038 99.400 100.000 threads-sockets 5 groups 6.942 2.398 59.244 88.337 threads-sockets 6 groups 4.359 1.954 49.448 87.860 threads-sockets 7 groups 2.845 1.345 41.198 77.102 threads-sockets 8 groups 2.871 1.404 38.512 74.312
schedstat_parse.py -f tbench_vanilla.log case load se_eff% dom_eff% fast_rate% success_rate% loopback 28 threads 99.976 18.369 99.995 100.000 loopback 56 threads 99.222 7.799 99.934 100.000 loopback 84 threads 19.723 6.819 70.215 100.000 loopback 112 threads 11.283 5.371 55.371 99.999 loopback 140 threads 0.000 0.000 0.000 0.000 loopback 168 threads 0.000 0.000 0.000 0.000 loopback 196 threads 0.000 0.000 0.000 0.000 loopback 224 threads 0.000 0.000 0.000 0.000
According to the test above, if the system becomes busy, the SIS Search Efficiency(se_eff%) drops significantly. Although some benchmarks would finally find an idle CPU(success_rate% = 100%), it is doubtful whether it is worth it to search the whole LLC domain.
[Proposal] It would be ideal to have a crystal ball to answer this question: How many CPUs must a wakeup path walk down, before it can find an idle CPU? Many potential metrics could be used to predict the number. One candidate is the sum of util_avg in this LLC domain. The benefit of choosing util_avg is that it is a metric of accumulated historic activity, which seems to be smoother than instantaneous metrics (such as rq->nr_running). Besides, choosing the sum of util_avg would help predict the load of the LLC domain more precisely, because SIS_PROP uses one CPU's idle time to estimate the total LLC domain idle time.
In summary, the lower the util_avg is, the more select_idle_cpu() should scan for idle CPU, and vice versa. When the sum of util_avg in this LLC domain hits 85% or above, the scan stops. The reason to choose 85% as the threshold is that this is the imbalance_pct(117) when a LLC sched group is overloaded.
Introduce the quadratic function:
y = SCHED_CAPACITY_SCALE - p * x^2 and y'= y / SCHED_CAPACITY_SCALE
x is the ratio of sum_util compared to the CPU capacity: x = sum_util / (llc_weight * SCHED_CAPACITY_SCALE) y' is the ratio of CPUs to be scanned in the LLC domain, and the number of CPUs to scan is calculated by:
nr_scan = llc_weight * y'
Choosing quadratic function is because: [1] Compared to the linear function, it scans more aggressively when the sum_util is low. [2] Compared to the exponential function, it is easier to calculate. [3] It seems that there is no accurate mapping between the sum of util_avg and the number of CPUs to be scanned. Use heuristic scan for now.
For a platform with 112 CPUs per LLC, the number of CPUs to scan is: sum_util% 0 5 15 25 35 45 55 65 75 85 86 ... scan_nr 112 111 108 102 93 81 65 47 25 1 0 ...
For a platform with 16 CPUs per LLC, the number of CPUs to scan is: sum_util% 0 5 15 25 35 45 55 65 75 85 86 ... scan_nr 16 15 15 14 13 11 9 6 3 0 0 ...
Furthermore, to minimize the overhead of calculating the metrics in select_idle_cpu(), borrow the statistics from periodic load balance. As mentioned by Abel, on a platform with 112 CPUs per LLC, the sum_util calculated by periodic load balance after 112 ms would decay to about 0.5 * 0.5 * 0.5 * 0.7 = 8.75%, thus bringing a delay in reflecting the latest utilization. But it is a trade-off. Checking the util_avg in newidle load balance would be more frequent, but it brings overhead - multiple CPUs write/read the per-LLC shared variable and introduces cache contention. Tim also mentioned that, it is allowed to be non-optimal in terms of scheduling for the short-term variations, but if there is a long-term trend in the load behavior, the scheduler can adjust for that.
When SIS_UTIL is enabled, the select_idle_cpu() uses the nr_scan calculated by SIS_UTIL instead of the one from SIS_PROP. As Peter and Mel suggested, SIS_UTIL should be enabled by default.
This patch is based on the util_avg, which is very sensitive to the CPU frequency invariance. There is an issue that, when the max frequency has been clamp, the util_avg would decay insanely fast when the CPU is idle. Commit addca285120b ("cpufreq: intel_pstate: Handle no_turbo in frequency invariance") could be used to mitigate this symptom, by adjusting the arch_max_freq_ratio when turbo is disabled. But this issue is still not thoroughly fixed, because the current code is unaware of the user-specified max CPU frequency.
[Test result]
netperf and tbench were launched with 25% 50% 75% 100% 125% 150% 175% 200% of CPU number respectively. Hackbench and schbench were launched by 1, 2 ,4, 8 groups. Each test lasts for 100 seconds and repeats 3 times.
The following is the benchmark result comparison between baseline:vanilla v5.19-rc1 and compare:patched kernel. Positive compare% indicates better performance.
Each netperf test is a: netperf -4 -H 127.0.1 -t TCP/UDP_RR -c -C -l 100 netperf.throughput ======= case load baseline(std%) compare%( std%) TCP_RR 28 threads 1.00 ( 0.34) -0.16 ( 0.40) TCP_RR 56 threads 1.00 ( 0.19) -0.02 ( 0.20) TCP_RR 84 threads 1.00 ( 0.39) -0.47 ( 0.40) TCP_RR 112 threads 1.00 ( 0.21) -0.66 ( 0.22) TCP_RR 140 threads 1.00 ( 0.19) -0.69 ( 0.19) TCP_RR 168 threads 1.00 ( 0.18) -0.48 ( 0.18) TCP_RR 196 threads 1.00 ( 0.16) +194.70 ( 16.43) TCP_RR 224 threads 1.00 ( 0.16) +197.30 ( 7.85) UDP_RR 28 threads 1.00 ( 0.37) +0.35 ( 0.33) UDP_RR 56 threads 1.00 ( 11.18) -0.32 ( 0.21) UDP_RR 84 threads 1.00 ( 1.46) -0.98 ( 0.32) UDP_RR 112 threads 1.00 ( 28.85) -2.48 ( 19.61) UDP_RR 140 threads 1.00 ( 0.70) -0.71 ( 14.04) UDP_RR 168 threads 1.00 ( 14.33) -0.26 ( 11.16) UDP_RR 196 threads 1.00 ( 12.92) +186.92 ( 20.93) UDP_RR 224 threads 1.00 ( 11.74) +196.79 ( 18.62)
Take the 224 threads as an example, the SIS search metrics changes are illustrated below:
vanilla patched 4544492 +237.5% 15338634 sched_debug.cpu.sis_domain_search.avg 38539 +39686.8% 15333634 sched_debug.cpu.sis_failed.avg 128300000 -87.9% 15551326 sched_debug.cpu.sis_scanned.avg 5842896 +162.7% 15347978 sched_debug.cpu.sis_search.avg
There is -87.9% less CPU scans after patched, which indicates lower overhead. Besides, with this patch applied, there is -13% less rq lock contention in perf-profile.calltrace.cycles-pp._raw_spin_lock.raw_spin_rq_lock_nested .try_to_wake_up.default_wake_function.woken_wake_function. This might help explain the performance improvement - Because this patch allows the waking task to remain on the previous CPU, rather than grabbing other CPUs' lock.
Each hackbench test is a: hackbench -g $job --process/threads --pipe/sockets -l 1000000 -s 100 hackbench.throughput ========= case load baseline(std%) compare%( std%) process-pipe 1 group 1.00 ( 1.29) +0.57 ( 0.47) process-pipe 2 groups 1.00 ( 0.27) +0.77 ( 0.81) process-pipe 4 groups 1.00 ( 0.26) +1.17 ( 0.02) process-pipe 8 groups 1.00 ( 0.15) -4.79 ( 0.02) process-sockets 1 group 1.00 ( 0.63) -0.92 ( 0.13) process-sockets 2 groups 1.00 ( 0.03) -0.83 ( 0.14) process-sockets 4 groups 1.00 ( 0.40) +5.20 ( 0.26) process-sockets 8 groups 1.00 ( 0.04) +3.52 ( 0.03) threads-pipe 1 group 1.00 ( 1.28) +0.07 ( 0.14) threads-pipe 2 groups 1.00 ( 0.22) -0.49 ( 0.74) threads-pipe 4 groups 1.00 ( 0.05) +1.88 ( 0.13) threads-pipe 8 groups 1.00 ( 0.09) -4.90 ( 0.06) threads-sockets 1 group 1.00 ( 0.25) -0.70 ( 0.53) threads-sockets 2 groups 1.00 ( 0.10) -0.63 ( 0.26) threads-sockets 4 groups 1.00 ( 0.19) +11.92 ( 0.24) threads-sockets 8 groups 1.00 ( 0.08) +4.31 ( 0.11)
Each tbench test is a: tbench -t 100 $job 127.0.0.1 tbench.throughput ====== case load baseline(std%) compare%( std%) loopback 28 threads 1.00 ( 0.06) -0.14 ( 0.09) loopback 56 threads 1.00 ( 0.03) -0.04 ( 0.17) loopback 84 threads 1.00 ( 0.05) +0.36 ( 0.13) loopback 112 threads 1.00 ( 0.03) +0.51 ( 0.03) loopback 140 threads 1.00 ( 0.02) -1.67 ( 0.19) loopback 168 threads 1.00 ( 0.38) +1.27 ( 0.27) loopback 196 threads 1.00 ( 0.11) +1.34 ( 0.17) loopback 224 threads 1.00 ( 0.11) +1.67 ( 0.22)
Each schbench test is a: schbench -m $job -t 28 -r 100 -s 30000 -c 30000 schbench.latency_90%_us ======== case load baseline(std%) compare%( std%) normal 1 mthread 1.00 ( 31.22) -7.36 ( 20.25)* normal 2 mthreads 1.00 ( 2.45) -0.48 ( 1.79) normal 4 mthreads 1.00 ( 1.69) +0.45 ( 0.64) normal 8 mthreads 1.00 ( 5.47) +9.81 ( 14.28)
*Consider the Standard Deviation, this -7.36% regression might not be valid.
Also, a OLTP workload with a commercial RDBMS has been tested, and there is no significant change.
There were concerns that unbalanced tasks among CPUs would cause problems. For example, suppose the LLC domain is composed of 8 CPUs, and 7 tasks are bound to CPU0~CPU6, while CPU7 is idle:
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 util_avg 1024 1024 1024 1024 1024 1024 1024 0
Since the util_avg ratio is 87.5%( = 7/8 ), which is higher than 85%, select_idle_cpu() will not scan, thus CPU7 is undetected during scan. But according to Mel, it is unlikely the CPU7 will be idle all the time because CPU7 could pull some tasks via CPU_NEWLY_IDLE.
lkp(kernel test robot) has reported a regression on stress-ng.sock on a very busy system. According to the sched_debug statistics, it might be caused by SIS_UTIL terminates the scan and chooses a previous CPU earlier, and this might introduce more context switch, especially involuntary preemption, which impacts a busy stress-ng. This regression has shown that, not all benchmarks in every scenario benefit from idle CPU scan limit, and it needs further investigation.
Besides, there is slight regression in hackbench's 16 groups case when the LLC domain has 16 CPUs. Prateek mentioned that we should scan aggressively in an LLC domain with 16 CPUs. Because the cost to search for an idle one among 16 CPUs is negligible. The current patch aims to propose a generic solution and only considers the util_avg. Something like the below could be applied on top of the current patch to fulfill the requirement:
if (llc_weight <= 16) nr_scan = nr_scan * 32 / llc_weight;
For LLC domain with 16 CPUs, the nr_scan will be expanded to 2 times large. The smaller the CPU number this LLC domain has, the larger nr_scan will be expanded. This needs further investigation.
There is also ongoing work[2] from Abel to filter out the busy CPUs during wakeup, to further speed up the idle CPU scan. And it could be a following-up optimization on top of this change.
Suggested-by: Tim Chen tim.c.chen@intel.com Suggested-by: Peter Zijlstra peterz@infradead.org Signed-off-by: Chen Yu yu.c.chen@intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Tested-by: Yicong Yang yangyicong@hisilicon.com Tested-by: Mohini Narkhede mohini.narkhede@intel.com Tested-by: K Prateek Nayak kprateek.nayak@amd.com Link: https://lore.kernel.org/r/20220612163428.849378-1-yu.c.chen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/sched/topology.h | 1 + kernel/sched/fair.c | 87 ++++++++++++++++++++++++++++++++++ kernel/sched/features.h | 3 +- 3 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h index 56cffe42abbc..816df6cc444e 100644 --- a/include/linux/sched/topology.h +++ b/include/linux/sched/topology.h @@ -81,6 +81,7 @@ struct sched_domain_shared { atomic_t ref; atomic_t nr_busy_cpus; int has_idle_cores; + int nr_idle_scan; };
struct sched_domain { diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 77b2048a9326..3fb857a35b16 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6336,6 +6336,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool { struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask); int i, cpu, idle_cpu = -1, nr = INT_MAX; + struct sched_domain_shared *sd_share; struct rq *this_rq = this_rq(); int this = smp_processor_id(); struct sched_domain *this_sd; @@ -6375,6 +6376,17 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool time = cpu_clock(this); }
+ if (sched_feat(SIS_UTIL)) { + sd_share = rcu_dereference(per_cpu(sd_llc_shared, target)); + if (sd_share) { + /* because !--nr is the condition to stop scan */ + nr = READ_ONCE(sd_share->nr_idle_scan) + 1; + /* overloaded LLC is unlikely to have idle cpu/core */ + if (nr == 1) + return -1; + } + } + for_each_cpu_wrap(cpu, cpus, target + 1) { if (has_idle_core) { i = select_idle_core(p, cpu, cpus, &idle_cpu); @@ -9222,6 +9234,77 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu) return idlest; }
+static void update_idle_cpu_scan(struct lb_env *env, + unsigned long sum_util) +{ + struct sched_domain_shared *sd_share; + int llc_weight, pct; + u64 x, y, tmp; + /* + * Update the number of CPUs to scan in LLC domain, which could + * be used as a hint in select_idle_cpu(). The update of sd_share + * could be expensive because it is within a shared cache line. + * So the write of this hint only occurs during periodic load + * balancing, rather than CPU_NEWLY_IDLE, because the latter + * can fire way more frequently than the former. + */ + if (!sched_feat(SIS_UTIL) || env->idle == CPU_NEWLY_IDLE) + return; + + llc_weight = per_cpu(sd_llc_size, env->dst_cpu); + if (env->sd->span_weight != llc_weight) + return; + + sd_share = rcu_dereference(per_cpu(sd_llc_shared, env->dst_cpu)); + if (!sd_share) + return; + + /* + * The number of CPUs to search drops as sum_util increases, when + * sum_util hits 85% or above, the scan stops. + * The reason to choose 85% as the threshold is because this is the + * imbalance_pct(117) when a LLC sched group is overloaded. + * + * let y = SCHED_CAPACITY_SCALE - p * x^2 [1] + * and y'= y / SCHED_CAPACITY_SCALE + * + * x is the ratio of sum_util compared to the CPU capacity: + * x = sum_util / (llc_weight * SCHED_CAPACITY_SCALE) + * y' is the ratio of CPUs to be scanned in the LLC domain, + * and the number of CPUs to scan is calculated by: + * + * nr_scan = llc_weight * y' [2] + * + * When x hits the threshold of overloaded, AKA, when + * x = 100 / pct, y drops to 0. According to [1], + * p should be SCHED_CAPACITY_SCALE * pct^2 / 10000 + * + * Scale x by SCHED_CAPACITY_SCALE: + * x' = sum_util / llc_weight; [3] + * + * and finally [1] becomes: + * y = SCHED_CAPACITY_SCALE - + * x'^2 * pct^2 / (10000 * SCHED_CAPACITY_SCALE) [4] + * + */ + /* equation [3] */ + x = sum_util; + do_div(x, llc_weight); + + /* equation [4] */ + pct = env->sd->imbalance_pct; + tmp = x * x * pct * pct; + do_div(tmp, 10000 * SCHED_CAPACITY_SCALE); + tmp = min_t(long, tmp, SCHED_CAPACITY_SCALE); + y = SCHED_CAPACITY_SCALE - tmp; + + /* equation [2] */ + y *= llc_weight; + do_div(y, SCHED_CAPACITY_SCALE); + if ((int)y != sd_share->nr_idle_scan) + WRITE_ONCE(sd_share->nr_idle_scan, (int)y); +} + /** * update_sd_lb_stats - Update sched_domain's statistics for load balancing. * @env: The load balancing environment. @@ -9234,6 +9317,7 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd struct sched_group *sg = env->sd->groups; struct sg_lb_stats *local = &sds->local_stat; struct sg_lb_stats tmp_sgs; + unsigned long sum_util = 0; int sg_status = 0;
do { @@ -9266,6 +9350,7 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd sds->total_load += sgs->group_load; sds->total_capacity += sgs->group_capacity;
+ sum_util += sgs->group_util; sg = sg->next; } while (sg != env->sd->groups);
@@ -9291,6 +9376,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd WRITE_ONCE(rd->overutilized, SG_OVERUTILIZED); trace_sched_overutilized_tp(rd, SG_OVERUTILIZED); } + + update_idle_cpu_scan(env, sum_util); }
#define NUMA_IMBALANCE_MIN 2 diff --git a/kernel/sched/features.h b/kernel/sched/features.h index 1cf435bbcd9c..ee7f23c76bd3 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h @@ -60,7 +60,8 @@ SCHED_FEAT(TTWU_QUEUE, true) /* * When doing wakeups, attempt to limit superfluous scans of the LLC domain. */ -SCHED_FEAT(SIS_PROP, true) +SCHED_FEAT(SIS_PROP, false) +SCHED_FEAT(SIS_UTIL, true)
/* * Issue a WARN when we do multiple update_rq_clock() calls
From: Antonio Borneo antonio.borneo@foss.st.com
[ Upstream commit 95001b756467ecc9f5973eb5e74e97699d9bbdf1 ]
Function irq_chip::irq_request_resources() is reported as optional in the declaration of struct irq_chip. If the parent irq_chip does not implement it, we should ignore it and return.
Don't return error if the functions is missing.
Signed-off-by: Antonio Borneo antonio.borneo@foss.st.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220512160544.13561-1-antonio.borneo@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/irq/chip.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 886789dcee43..c19040530789 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -1516,7 +1516,8 @@ int irq_chip_request_resources_parent(struct irq_data *data) if (data->chip->irq_request_resources) return data->chip->irq_request_resources(data);
- return -ENOSYS; + /* no error on missing optional irq_chip::irq_request_resources */ + return 0; } EXPORT_SYMBOL_GPL(irq_chip_request_resources_parent);
From: Samuel Holland samuel@sholland.org
[ Upstream commit 8190cc572981f2f13b6ffc26c7cfa7899e5d3ccc ]
The MIPS GIC irqchip driver may be selected in a uniprocessor configuration, but it unconditionally registers an IPI domain.
Limit the part of the driver dealing with IPIs to only be compiled when GENERIC_IRQ_IPI is enabled, which corresponds to an SMP configuration.
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Samuel Holland samuel@sholland.org Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220701200056.46555-2-samuel@sholland.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/Kconfig | 3 +- drivers/irqchip/irq-mips-gic.c | 80 +++++++++++++++++++++++----------- 2 files changed, 56 insertions(+), 27 deletions(-)
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index bbb11cb8b0f7..12664ac6ac2d 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -322,7 +322,8 @@ config KEYSTONE_IRQ
config MIPS_GIC bool - select GENERIC_IRQ_IPI + select GENERIC_IRQ_IPI if SMP + select IRQ_DOMAIN_HIERARCHY select MIPS_CM
config INGENIC_IRQ diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index ff89b36267dd..8a9efb6ae587 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -52,13 +52,15 @@ static DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
static DEFINE_SPINLOCK(gic_lock); static struct irq_domain *gic_irq_domain; -static struct irq_domain *gic_ipi_domain; static int gic_shared_intrs; static unsigned int gic_cpu_pin; static unsigned int timer_cpu_pin; static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller; + +#ifdef CONFIG_GENERIC_IRQ_IPI static DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS); static DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS); +#endif /* CONFIG_GENERIC_IRQ_IPI */
static struct gic_all_vpes_chip_data { u32 map; @@ -472,9 +474,11 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, u32 map;
if (hwirq >= GIC_SHARED_HWIRQ_BASE) { +#ifdef CONFIG_GENERIC_IRQ_IPI /* verify that shared irqs don't conflict with an IPI irq */ if (test_bit(GIC_HWIRQ_TO_SHARED(hwirq), ipi_resrv)) return -EBUSY; +#endif /* CONFIG_GENERIC_IRQ_IPI */
err = irq_domain_set_hwirq_and_chip(d, virq, hwirq, &gic_level_irq_controller, @@ -567,6 +571,8 @@ static const struct irq_domain_ops gic_irq_domain_ops = { .map = gic_irq_domain_map, };
+#ifdef CONFIG_GENERIC_IRQ_IPI + static int gic_ipi_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, @@ -670,6 +676,48 @@ static const struct irq_domain_ops gic_ipi_domain_ops = { .match = gic_ipi_domain_match, };
+static int gic_register_ipi_domain(struct device_node *node) +{ + struct irq_domain *gic_ipi_domain; + unsigned int v[2], num_ipis; + + gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain, + IRQ_DOMAIN_FLAG_IPI_PER_CPU, + GIC_NUM_LOCAL_INTRS + gic_shared_intrs, + node, &gic_ipi_domain_ops, NULL); + if (!gic_ipi_domain) { + pr_err("Failed to add IPI domain"); + return -ENXIO; + } + + irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI); + + if (node && + !of_property_read_u32_array(node, "mti,reserved-ipi-vectors", v, 2)) { + bitmap_set(ipi_resrv, v[0], v[1]); + } else { + /* + * Reserve 2 interrupts per possible CPU/VP for use as IPIs, + * meeting the requirements of arch/mips SMP. + */ + num_ipis = 2 * num_possible_cpus(); + bitmap_set(ipi_resrv, gic_shared_intrs - num_ipis, num_ipis); + } + + bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS); + + return 0; +} + +#else /* !CONFIG_GENERIC_IRQ_IPI */ + +static inline int gic_register_ipi_domain(struct device_node *node) +{ + return 0; +} + +#endif /* !CONFIG_GENERIC_IRQ_IPI */ + static int gic_cpu_startup(unsigned int cpu) { /* Enable or disable EIC */ @@ -688,11 +736,12 @@ static int gic_cpu_startup(unsigned int cpu) static int __init gic_of_init(struct device_node *node, struct device_node *parent) { - unsigned int cpu_vec, i, gicconfig, v[2], num_ipis; + unsigned int cpu_vec, i, gicconfig; unsigned long reserved; phys_addr_t gic_base; struct resource res; size_t gic_len; + int ret;
/* Find the first available CPU vector. */ i = 0; @@ -780,30 +829,9 @@ static int __init gic_of_init(struct device_node *node, return -ENXIO; }
- gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain, - IRQ_DOMAIN_FLAG_IPI_PER_CPU, - GIC_NUM_LOCAL_INTRS + gic_shared_intrs, - node, &gic_ipi_domain_ops, NULL); - if (!gic_ipi_domain) { - pr_err("Failed to add IPI domain"); - return -ENXIO; - } - - irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI); - - if (node && - !of_property_read_u32_array(node, "mti,reserved-ipi-vectors", v, 2)) { - bitmap_set(ipi_resrv, v[0], v[1]); - } else { - /* - * Reserve 2 interrupts per possible CPU/VP for use as IPIs, - * meeting the requirements of arch/mips SMP. - */ - num_ipis = 2 * num_possible_cpus(); - bitmap_set(ipi_resrv, gic_shared_intrs - num_ipis, num_ipis); - } - - bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS); + ret = gic_register_ipi_domain(node); + if (ret) + return ret;
board_bind_eic_interrupt = &gic_bind_eic_interrupt;
From: Samuel Holland samuel@sholland.org
[ Upstream commit 0f5209fee90b4544c58b4278d944425292789967 ]
The generic IPI code depends on the IRQ affinity mask being allocated and initialized. This will not be the case if SMP is disabled. Fix up the remaining driver that selected GENERIC_IRQ_IPI in a non-SMP config.
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Samuel Holland samuel@sholland.org Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220701200056.46555-3-samuel@sholland.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/Kconfig | 2 +- kernel/irq/Kconfig | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 12664ac6ac2d..6b287dc025a9 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -177,7 +177,7 @@ config MADERA_IRQ config IRQ_MIPS_CPU bool select GENERIC_IRQ_CHIP - select GENERIC_IRQ_IPI if SYS_SUPPORTS_MULTITHREADING + select GENERIC_IRQ_IPI if SMP && SYS_SUPPORTS_MULTITHREADING select IRQ_DOMAIN select GENERIC_IRQ_EFFECTIVE_AFF_MASK
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index 10929eda9825..fc760d064a65 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -82,6 +82,7 @@ config IRQ_FASTEOI_HIERARCHY_HANDLERS # Generic IRQ IPI support config GENERIC_IRQ_IPI bool + depends on SMP select IRQ_DOMAIN_HIERARCHY
# Generic MSI interrupt support
From: Vincent Guittot vincent.guittot@linaro.org
[ Upstream commit c82a69629c53eda5233f13fc11c3c01585ef48a2 ]
The capacity of the CPU available for CFS tasks can be reduced because of other activities running on the latter. In such case, it's worth trying to move CFS tasks on a CPU with more available capacity.
The rework of the load balance has filtered the case when the CPU is classified to be fully busy but its capacity is reduced.
Check if CPU's capacity is reduced while gathering load balance statistic and classify it group_misfit_task instead of group_fully_busy so we can try to move the load on another CPU.
Reported-by: David Chen david.chen@nutanix.com Reported-by: Zhang Qiao zhangqiao22@huawei.com Signed-off-by: Vincent Guittot vincent.guittot@linaro.org Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Tested-by: David Chen david.chen@nutanix.com Tested-by: Zhang Qiao zhangqiao22@huawei.com Link: https://lkml.kernel.org/r/20220708154401.21411-1-vincent.guittot@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/fair.c | 54 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 12 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 3fb857a35b16..9d6058b0a3d4 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7597,8 +7597,8 @@ enum group_type { */ group_fully_busy, /* - * SD_ASYM_CPUCAPACITY only: One task doesn't fit with CPU's capacity - * and must be migrated to a more powerful CPU. + * One task doesn't fit with CPU's capacity and must be migrated to a + * more powerful CPU. */ group_misfit_task, /* @@ -8681,6 +8681,19 @@ sched_asym(struct lb_env *env, struct sd_lb_stats *sds, struct sg_lb_stats *sgs return sched_asym_prefer(env->dst_cpu, group->asym_prefer_cpu); }
+static inline bool +sched_reduced_capacity(struct rq *rq, struct sched_domain *sd) +{ + /* + * When there is more than 1 task, the group_overloaded case already + * takes care of cpu with reduced capacity + */ + if (rq->cfs.h_nr_running != 1) + return false; + + return check_cpu_capacity(rq, sd); +} + /** * update_sg_lb_stats - Update sched_group's statistics for load balancing. * @env: The load balancing environment. @@ -8703,8 +8716,9 @@ static inline void update_sg_lb_stats(struct lb_env *env,
for_each_cpu_and(i, sched_group_span(group), env->cpus) { struct rq *rq = cpu_rq(i); + unsigned long load = cpu_load(rq);
- sgs->group_load += cpu_load(rq); + sgs->group_load += load; sgs->group_util += cpu_util_cfs(i); sgs->group_runnable += cpu_runnable(rq); sgs->sum_h_nr_running += rq->cfs.h_nr_running; @@ -8734,11 +8748,17 @@ static inline void update_sg_lb_stats(struct lb_env *env, if (local_group) continue;
- /* Check for a misfit task on the cpu */ - if (env->sd->flags & SD_ASYM_CPUCAPACITY && - sgs->group_misfit_task_load < rq->misfit_task_load) { - sgs->group_misfit_task_load = rq->misfit_task_load; - *sg_status |= SG_OVERLOAD; + if (env->sd->flags & SD_ASYM_CPUCAPACITY) { + /* Check for a misfit task on the cpu */ + if (sgs->group_misfit_task_load < rq->misfit_task_load) { + sgs->group_misfit_task_load = rq->misfit_task_load; + *sg_status |= SG_OVERLOAD; + } + } else if ((env->idle != CPU_NOT_IDLE) && + sched_reduced_capacity(rq, env->sd)) { + /* Check for a task running on a CPU with reduced capacity */ + if (sgs->group_misfit_task_load < load) + sgs->group_misfit_task_load = load; } }
@@ -8791,7 +8811,8 @@ static bool update_sd_pick_busiest(struct lb_env *env, * CPUs in the group should either be possible to resolve * internally or be covered by avg_load imbalance (eventually). */ - if (sgs->group_type == group_misfit_task && + if ((env->sd->flags & SD_ASYM_CPUCAPACITY) && + (sgs->group_type == group_misfit_task) && (!capacity_greater(capacity_of(env->dst_cpu), sg->sgc->max_capacity) || sds->local_stat.group_type != group_has_spare)) return false; @@ -9412,9 +9433,18 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s busiest = &sds->busiest_stat;
if (busiest->group_type == group_misfit_task) { - /* Set imbalance to allow misfit tasks to be balanced. */ - env->migration_type = migrate_misfit; - env->imbalance = 1; + if (env->sd->flags & SD_ASYM_CPUCAPACITY) { + /* Set imbalance to allow misfit tasks to be balanced. */ + env->migration_type = migrate_misfit; + env->imbalance = 1; + } else { + /* + * Set load imbalance to allow moving task from cpu + * with reduced capacity. + */ + env->migration_type = migrate_load; + env->imbalance = busiest->group_misfit_task_load; + } return; }
From: John Keeping john@metanate.com
[ Upstream commit 401e4963bf45c800e3e9ea0d3a0289d738005fd4 ]
With CONFIG_PREEMPT_RT, it is possible to hit a deadlock between two normal priority tasks (SCHED_OTHER, nice level zero):
INFO: task kworker/u8:0:8 blocked for more than 491 seconds. Not tainted 5.15.49-rt46 #1 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:kworker/u8:0 state:D stack: 0 pid: 8 ppid: 2 flags:0x00000000 Workqueue: writeback wb_workfn (flush-7:0) [<c08a3a10>] (__schedule) from [<c08a3d84>] (schedule+0xdc/0x134) [<c08a3d84>] (schedule) from [<c08a65a0>] (rt_mutex_slowlock_block.constprop.0+0xb8/0x174) [<c08a65a0>] (rt_mutex_slowlock_block.constprop.0) from [<c08a6708>] +(rt_mutex_slowlock.constprop.0+0xac/0x174) [<c08a6708>] (rt_mutex_slowlock.constprop.0) from [<c0374d60>] (fat_write_inode+0x34/0x54) [<c0374d60>] (fat_write_inode) from [<c0297304>] (__writeback_single_inode+0x354/0x3ec) [<c0297304>] (__writeback_single_inode) from [<c0297998>] (writeback_sb_inodes+0x250/0x45c) [<c0297998>] (writeback_sb_inodes) from [<c0297c20>] (__writeback_inodes_wb+0x7c/0xb8) [<c0297c20>] (__writeback_inodes_wb) from [<c0297f24>] (wb_writeback+0x2c8/0x2e4) [<c0297f24>] (wb_writeback) from [<c0298c40>] (wb_workfn+0x1a4/0x3e4) [<c0298c40>] (wb_workfn) from [<c0138ab8>] (process_one_work+0x1fc/0x32c) [<c0138ab8>] (process_one_work) from [<c0139120>] (worker_thread+0x22c/0x2d8) [<c0139120>] (worker_thread) from [<c013e6e0>] (kthread+0x16c/0x178) [<c013e6e0>] (kthread) from [<c01000fc>] (ret_from_fork+0x14/0x38) Exception stack(0xc10e3fb0 to 0xc10e3ff8) 3fa0: 00000000 00000000 00000000 00000000 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
INFO: task tar:2083 blocked for more than 491 seconds. Not tainted 5.15.49-rt46 #1 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:tar state:D stack: 0 pid: 2083 ppid: 2082 flags:0x00000000 [<c08a3a10>] (__schedule) from [<c08a3d84>] (schedule+0xdc/0x134) [<c08a3d84>] (schedule) from [<c08a41b0>] (io_schedule+0x14/0x24) [<c08a41b0>] (io_schedule) from [<c08a455c>] (bit_wait_io+0xc/0x30) [<c08a455c>] (bit_wait_io) from [<c08a441c>] (__wait_on_bit_lock+0x54/0xa8) [<c08a441c>] (__wait_on_bit_lock) from [<c08a44f4>] (out_of_line_wait_on_bit_lock+0x84/0xb0) [<c08a44f4>] (out_of_line_wait_on_bit_lock) from [<c0371fb0>] (fat_mirror_bhs+0xa0/0x144) [<c0371fb0>] (fat_mirror_bhs) from [<c0372a68>] (fat_alloc_clusters+0x138/0x2a4) [<c0372a68>] (fat_alloc_clusters) from [<c0370b14>] (fat_alloc_new_dir+0x34/0x250) [<c0370b14>] (fat_alloc_new_dir) from [<c03787c0>] (vfat_mkdir+0x58/0x148) [<c03787c0>] (vfat_mkdir) from [<c0277b60>] (vfs_mkdir+0x68/0x98) [<c0277b60>] (vfs_mkdir) from [<c027b484>] (do_mkdirat+0xb0/0xec) [<c027b484>] (do_mkdirat) from [<c0100060>] (ret_fast_syscall+0x0/0x1c) Exception stack(0xc2e1bfa8 to 0xc2e1bff0) bfa0: 01ee42f0 01ee4208 01ee42f0 000041ed 00000000 00004000 bfc0: 01ee42f0 01ee4208 00000000 00000027 01ee4302 00000004 000dcb00 01ee4190 bfe0: 000dc368 bed11924 0006d4b0 b6ebddfc
Here the kworker is waiting on msdos_sb_info::s_lock which is held by tar which is in turn waiting for a buffer which is locked waiting to be flushed, but this operation is plugged in the kworker.
The lock is a normal struct mutex, so tsk_is_pi_blocked() will always return false on !RT and thus the behaviour changes for RT.
It seems that the intent here is to skip blk_flush_plug() in the case where a non-preemptible lock (such as a spinlock) has been converted to a rtmutex on RT, which is the case covered by the SM_RTLOCK_WAIT schedule flag. But sched_submit_work() is only called from schedule() which is never called in this scenario, so the check can simply be deleted.
Looking at the history of the -rt patchset, in fact this change was present from v5.9.1-rt20 until being dropped in v5.13-rt1 as it was part of a larger patch [1] most of which was replaced by commit b4bfa3fcfe3b ("sched/core: Rework the __schedule() preempt argument").
As described in [1]:
The schedule process must distinguish between blocking on a regular sleeping lock (rwsem and mutex) and a RT-only sleeping lock (spinlock and rwlock): - rwsem and mutex must flush block requests (blk_schedule_flush_plug()) even if blocked on a lock. This can not deadlock because this also happens for non-RT. There should be a warning if the scheduling point is within a RCU read section.
- spinlock and rwlock must not flush block requests. This will deadlock if the callback attempts to acquire a lock which is already acquired. Similarly to being preempted, there should be no warning if the scheduling point is within a RCU read section.
and with the tsk_is_pi_blocked() in the scheduler path, we hit the first issue.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git/tree/p...
Signed-off-by: John Keeping john@metanate.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Steven Rostedt (Google) rostedt@goodmis.org Link: https://lkml.kernel.org/r/20220708162702.1758865-1-john@metanate.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/sched/rt.h | 8 -------- kernel/sched/core.c | 8 ++++++-- 2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/include/linux/sched/rt.h b/include/linux/sched/rt.h index e5af028c08b4..994c25640e15 100644 --- a/include/linux/sched/rt.h +++ b/include/linux/sched/rt.h @@ -39,20 +39,12 @@ static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *p) } extern void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task); extern void rt_mutex_adjust_pi(struct task_struct *p); -static inline bool tsk_is_pi_blocked(struct task_struct *tsk) -{ - return tsk->pi_blocked_on != NULL; -} #else static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *task) { return NULL; } # define rt_mutex_adjust_pi(p) do { } while (0) -static inline bool tsk_is_pi_blocked(struct task_struct *tsk) -{ - return false; -} #endif
extern void normalize_rt_tasks(void); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index da0bf6fe9ecd..410b04decb90 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6500,8 +6500,12 @@ static inline void sched_submit_work(struct task_struct *tsk) io_wq_worker_sleeping(tsk); }
- if (tsk_is_pi_blocked(tsk)) - return; + /* + * spinlock and rwlock must not flush block requests. This will + * deadlock if the callback attempts to acquire a lock which is + * already acquired. + */ + SCHED_WARN_ON(current->__state & TASK_RTLOCK_WAIT);
/* * If we are going to sleep and we have plugged IO queued,
From: William Dean williamsukatube@163.com
[ Upstream commit 71349cc85e5930dce78ed87084dee098eba24b59 ]
The function ioremap() in gic_of_init() can fail, so its return value should be checked.
Reported-by: Hacash Robot hacashRobot@santino.com Signed-off-by: William Dean williamsukatube@163.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220723100128.2964304-1-williamsukatube@163.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-mips-gic.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 8a9efb6ae587..1ba0f1555c80 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -783,6 +783,10 @@ static int __init gic_of_init(struct device_node *node, }
mips_gic_base = ioremap(gic_base, gic_len); + if (!mips_gic_base) { + pr_err("Failed to ioremap gic_base\n"); + return -ENOMEM; + }
gicconfig = read_gic_config(); gic_shared_intrs = FIELD_GET(GIC_CONFIG_NUMINTERRUPTS, gicconfig);
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit 5655699cf5cff9f4c4ee703792156bdd05d1addf ]
All 3 properties are required by sram.yaml. Fixes the dtbs_check warning: sram@900000: '#address-cells' is a required property sram@900000: '#size-cells' is a required property sram@900000: 'ranges' is a required property
Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx6ul.dtsi | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index afeec01f6522..1d435a46fc5c 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -149,6 +149,9 @@ soc { ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x20000>; + ranges = <0 0x00900000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; };
intc: interrupt-controller@a01000 {
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit edb67843983bbdf61b4c8c3c50618003d38bb4ae ]
operating-points is a uint32-matrix as per opp-v1.yaml. Change it accordingly. While at it, change fsl,soc-operating-points as well, although there is no bindings file (yet). But they should have the same format. Fixes the dt_binding_check warning: cpu@0: operating-points:0: [696000, 1275000, 528000, 1175000, 396000, 1025000, 198000, 950000] is too long cpu@0: operating-points:0: Additional items are not allowed (528000, 1175000, 396000, 1025000, 198000, 950000 were unexpected)
Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx6ul.dtsi | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index 1d435a46fc5c..2fcbd9d91521 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -64,20 +64,18 @@ cpu0: cpu@0 { clock-frequency = <696000000>; clock-latency = <61036>; /* two CLK32 periods */ #cooling-cells = <2>; - operating-points = < + operating-points = /* kHz uV */ - 696000 1275000 - 528000 1175000 - 396000 1025000 - 198000 950000 - >; - fsl,soc-operating-points = < + <696000 1275000>, + <528000 1175000>, + <396000 1025000>, + <198000 950000>; + fsl,soc-operating-points = /* KHz uV */ - 696000 1275000 - 528000 1175000 - 396000 1175000 - 198000 1175000 - >; + <696000 1275000>, + <528000 1175000>, + <396000 1175000>, + <198000 1175000>; clocks = <&clks IMX6UL_CLK_ARM>, <&clks IMX6UL_CLK_PLL2_BUS>, <&clks IMX6UL_CLK_PLL2_PFD2>,
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit 7d15e0c9a515494af2e3199741cdac7002928a0e ]
According to binding, the compatible shall only contain imx6ul and imx21 compatibles. Fixes the dt_binding_check warning: keypad@20b8000: compatible: 'oneOf' conditional failed, one must be fixed: ['fsl,imx6ul-kpp', 'fsl,imx6q-kpp', 'fsl,imx21-kpp'] is too long Additional items are not allowed ('fsl,imx6q-kpp', 'fsl,imx21-kpp' were unexpected) Additional items are not allowed ('fsl,imx21-kpp' was unexpected) 'fsl,imx21-kpp' was expected
Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx6ul.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index 2fcbd9d91521..df8b4ad62418 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -544,7 +544,7 @@ fec2: ethernet@20b4000 { };
kpp: keypad@20b8000 { - compatible = "fsl,imx6ul-kpp", "fsl,imx6q-kpp", "fsl,imx21-kpp"; + compatible = "fsl,imx6ul-kpp", "fsl,imx21-kpp"; reg = <0x020b8000 0x4000>; interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6UL_CLK_KPP>;
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit e0aca931a2c7c29c88ebf37f9c3cd045e083483d ]
"fsl,imx6ul-csi" was never listed as compatible to "fsl,imx7-csi", neither in yaml bindings, nor previous txt binding. Remove the imx7 part. Fixes the dt schema check warning: csi@21c4000: compatible: 'oneOf' conditional failed, one must be fixed: ['fsl,imx6ul-csi', 'fsl,imx7-csi'] is too long Additional items are not allowed ('fsl,imx7-csi' was unexpected) 'fsl,imx8mm-csi' was expected
Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx6ul.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index df8b4ad62418..367657a9a99f 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -999,7 +999,7 @@ cpu_speed_grade: speed-grade@10 { };
csi: csi@21c4000 { - compatible = "fsl,imx6ul-csi", "fsl,imx7-csi"; + compatible = "fsl,imx6ul-csi"; reg = <0x021c4000 0x4000>; interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6UL_CLK_CSI>;
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit 1a884d17ca324531634cce82e9f64c0302bdf7de ]
In yaml binding "fsl,imx6ul-lcdif" is listed as compatible to imx6sx-lcdif, but not imx28-lcdif. Change the list accordingly. Fixes the dt_binding_check warning: lcdif@21c8000: compatible: 'oneOf' conditional failed, one must be fixed: ['fsl,imx6ul-lcdif', 'fsl,imx28-lcdif'] is too long Additional items are not allowed ('fsl,imx28-lcdif' was unexpected) 'fsl,imx6ul-lcdif' is not one of ['fsl,imx23-lcdif', 'fsl,imx28-lcdif', 'fsl,imx6sx-lcdif'] 'fsl,imx6sx-lcdif' was expected
Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx6ul.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index 367657a9a99f..bc6548058d8c 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -1008,7 +1008,7 @@ csi: csi@21c4000 { };
lcdif: lcdif@21c8000 { - compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif"; + compatible = "fsl,imx6ul-lcdif", "fsl,imx6sx-lcdif"; reg = <0x021c8000 0x4000>; interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,
From: Alexander Stein alexander.stein@ew.tq-group.com
[ Upstream commit 0c6cf86e1ab433b2d421880fdd9c6e954f404948 ]
imx6ul is not compatible to imx6sx, both have different erratas. Fixes the dt_binding_check warning: spi@21e0000: compatible: 'oneOf' conditional failed, one must be fixed: ['fsl,imx6ul-qspi', 'fsl,imx6sx-qspi'] is too long Additional items are not allowed ('fsl,imx6sx-qspi' was unexpected) 'fsl,imx6ul-qspi' is not one of ['fsl,ls1043a-qspi'] 'fsl,imx6ul-qspi' is not one of ['fsl,imx8mq-qspi'] 'fsl,ls1021a-qspi' was expected 'fsl,imx7d-qspi' was expected
Signed-off-by: Alexander Stein alexander.stein@ew.tq-group.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx6ul.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index bc6548058d8c..eca8bf89ab88 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -1029,7 +1029,7 @@ pxp: pxp@21cc000 { qspi: spi@21e0000 { #address-cells = <1>; #size-cells = <0>; - compatible = "fsl,imx6ul-qspi", "fsl,imx6sx-qspi"; + compatible = "fsl,imx6ul-qspi"; reg = <0x021e0000 0x4000>, <0x60000000 0x10000000>; reg-names = "QuadSPI", "QuadSPI-memory"; interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
From: Christian Lamparter chunkeey@gmail.com
[ Upstream commit 935327a73553001f8d81375c76985d05f604507f ]
Meraki MR26 is an EOL wireless access point featuring a PoE ethernet port and two dual-band 3x3 MIMO 802.11n radios and 1x1 dual-band WIFI dedicated to scanning.
Thank you Amir for the unit and PSU.
Hardware info: SOC : Broadcom BCM53015A1KFEBG (dual-core Cortex-A9 CPU at 800 MHz) RAM : SK Hynix Inc. H5TQ1G63EFR, 1 GBit DDR3 SDRAM = 128 MiB NAND : Spansion S34ML01G100TF100, 1 GBit SLC NAND Flash = 128 MiB ETH : 1 GBit Ethernet Port - PoE (TPS23754 PoE Interface) WIFI0 : Broadcom BCM43431KMLG, BCM43431 802.11 abgn (3x3:3) WIFI1 : Broadcom BCM43431KMLG, BCM43431 802.11 abgn (3x3:3) WIFI2 : Broadcom BCM43428 "Air Marshal" 802.11 abgn (1x1:1) BUTTON: One reset key behind a small hole next to the Ethernet Port LEDS : One amber (fault), one white (indicator) LED, separate RGB-LED MISC : Atmel AT24C64 8KiB EEPROM i2c : Ti INA219 26V, 12-bit, i2c output current/voltage/power monitor
SERIAL: WARNING: The serial port needs a TTL/RS-232 3V3 level converter! The Serial setting is 115200-8-N-1. The board has a populated right angle 1x4 0.1" pinheader. The pinout is: VCC (next to J3, has the pin 1 indicator), RX, TX, GND.
Odd stuff:
- uboot does not support lzma compression, but gzip'd uImage/DTB work. - uboot claims to support FIT, but fails to pass the DTB to the kernel. Appending the dtb after the kernel image works. - RGB-controller is supported through an external userspace program. - The ubi partition contains a "board-config" volume. It stores the MAC Address (0x66 in binary) and Serial No. (0x7c alpha-numerical). - SoC's temperature sensor always reports that it is on fire. This causes the system to immediately shutdown! Looking at reported "418 degree Celsius" suggests that this sensor is not working.
WIFI: b43 is able to initialize all three WIFIs @ 802.11bg. | b43-phy0: Broadcom 43431 WLAN found (core revision 29) | bcma-pci-bridge 0000:01:00.0: bus1: Switched to core: 0x812 | b43-phy0: Found PHY: Analog 9, Type 7 (HT), Revision 1 | b43-phy0: Found Radio: Manuf 0x17F, ID 0x2059, Revision 0, Version 1 | b43-phy0 warning: 5 GHz band is unsupported on this PHY | b43-phy1: Broadcom 43431 WLAN found (core revision 29) | bcma-pci-bridge 0001:01:00.0: bus2: Switched to core: 0x812 | b43-phy1: Found PHY: Analog 9, Type 7 (HT), Revision 1 | b43-phy1: Found Radio: Manuf 0x17F, ID 0x2059, Revision 0, Version 1 | b43-phy1 warning: 5 GHz band is unsupported on this PHY | b43-phy2: Broadcom 43228 WLAN found (core revision 30) | bcma-pci-bridge 0002:01:00.0: bus3: Switched to core: 0x812 | b43-phy2: Found PHY: Analog 9, Type 4 (N), Revision 16 | b43-phy2: Found Radio: Manuf 0x17F, ID 0x2057, Revision 9, Version 1 | Broadcom 43xx driver loaded [ Features: NL ]
Signed-off-by: Christian Lamparter chunkeey@gmail.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 166 +++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 arch/arm/boot/dts/bcm53015-meraki-mr26.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 5112f493f494..27eec8e670ec 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -135,6 +135,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \ bcm47094-luxul-xwr-3150-v1.dtb \ bcm47094-netgear-r8500.dtb \ bcm47094-phicomm-k3.dtb \ + bcm53015-meraki-mr26.dtb \ bcm53016-meraki-mr32.dtb \ bcm94708.dtb \ bcm94709.dtb \ diff --git a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts new file mode 100644 index 000000000000..14f58033efeb --- /dev/null +++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Broadcom BCM470X / BCM5301X ARM platform code. + * DTS for Meraki MR26 / Codename: Venom + * + * Copyright (C) 2022 Christian Lamparter chunkeey@gmail.com + */ + +/dts-v1/; + +#include "bcm4708.dtsi" +#include "bcm5301x-nand-cs0-bch8.dtsi" +#include <dt-bindings/leds/common.h> + +/ { + compatible = "meraki,mr26", "brcm,bcm53015", "brcm,bcm4708"; + model = "Meraki MR26"; + + memory@0 { + reg = <0x00000000 0x08000000>; + device_type = "memory"; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + function = LED_FUNCTION_FAULT; + color = <LED_COLOR_ID_AMBER>; + gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>; + panic-indicator; + }; + led-1 { + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_WHITE>; + gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>; + }; + }; + + keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + key-restart { + label = "Reset"; + linux,code = <KEY_RESTART>; + gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&uart0 { + clock-frequency = <50000000>; + /delete-property/ clocks; +}; + +&uart1 { + status = "disabled"; +}; + +&gmac0 { + status = "okay"; +}; + +&gmac1 { + status = "disabled"; +}; +&gmac2 { + status = "disabled"; +}; +&gmac3 { + status = "disabled"; +}; + +&nandcs { + nand-ecc-algo = "hw"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <0x1>; + #size-cells = <0x1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x200000>; + read-only; + }; + + partition@200000 { + label = "u-boot-env"; + reg = <0x200000 0x200000>; + /* empty */ + }; + + partition@400000 { + label = "u-boot-backup"; + reg = <0x400000 0x200000>; + /* empty */ + }; + + partition@600000 { + label = "u-boot-env-backup"; + reg = <0x600000 0x200000>; + /* empty */ + }; + + partition@800000 { + label = "ubi"; + reg = <0x800000 0x7780000>; + }; + }; +}; + +&srab { + status = "okay"; + + ports { + port@0 { + reg = <0>; + label = "poe"; + }; + + port@5 { + reg = <5>; + label = "cpu"; + ethernet = <&gmac0>; + + fixed-link { + speed = <1000>; + duplex-full; + }; + }; + }; +}; + +&i2c0 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_i2c>; + + clock-frequency = <100000>; + + ina219@40 { + compatible = "ti,ina219"; /* PoE power */ + reg = <0x40>; + shunt-resistor = <60000>; /* = 60 mOhms */ + }; + + eeprom@56 { + compatible = "atmel,24c64"; + reg = <0x56>; + pagesize = <32>; + read-only; + #address-cells = <1>; + #size-cells = <1>; + + /* it's empty */ + }; +}; + +&thermal { + status = "disabled"; + /* does not work, reads 418 degree Celsius */ +};
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit 013fda41c03e6bcb3dc416669187b609e9e5fdbc ]
This was fixed wrong so fix it again. Now verified by using iio-sensor-proxy monitor-sensor test program.
Link: https://lore.kernel.org/r/20220609083516.329281-1-linus.walleij@linaro.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/ste-ux500-samsung-janice.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts index e6d4fd0eb5f4..ed5c79c3d04b 100644 --- a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts +++ b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts @@ -633,8 +633,8 @@ i2c-gate { accelerometer@8 { compatible = "bosch,bma222"; reg = <0x08>; - mount-matrix = "0", "1", "0", - "-1", "0", "0", + mount-matrix = "0", "-1", "0", + "1", "0", "0", "0", "0", "1"; vddio-supply = <&ab8500_ldo_aux2_reg>; // 1.8V vdd-supply = <&ab8500_ldo_aux1_reg>; // 3V
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit 0b2152e428ab91533a02888ff24e52e788dc4637 ]
This was fixed wrong so fix it again. Now verified by using iio-sensor-proxy monitor-sensor test program.
Link: https://lore.kernel.org/r/20220611204249.472250-1-linus.walleij@linaro.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/ste-ux500-samsung-codina.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts index b6746ac167bc..5f41256d7f4b 100644 --- a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts +++ b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts @@ -598,8 +598,8 @@ lisd3dh@19 { reg = <0x19>; vdd-supply = <&ab8500_ldo_aux1_reg>; // 3V vddio-supply = <&ab8500_ldo_aux2_reg>; // 1.8V - mount-matrix = "0", "-1", "0", - "1", "0", "0", + mount-matrix = "0", "1", "0", + "-1", "0", "0", "0", "0", "1"; }; };
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit e24c75f02a81d6ddac0072cbd7a03e799c19d558 ]
This was fixed wrong so fix it. Now verified by using iio-sensor-proxy monitor-sensor test program.
Link: https://lore.kernel.org/r/20220611205138.491513-1-linus.walleij@linaro.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/ste-ux500-samsung-gavini.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts index 53062d50e455..806da3fc33cd 100644 --- a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts +++ b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts @@ -527,8 +527,8 @@ i2c-gate { accelerometer@18 { compatible = "bosch,bma222e"; reg = <0x18>; - mount-matrix = "0", "1", "0", - "-1", "0", "0", + mount-matrix = "0", "-1", "0", + "1", "0", "0", "0", "0", "1"; vddio-supply = <&ab8500_ldo_aux2_reg>; // 1.8V vdd-supply = <&ab8500_ldo_aux1_reg>; // 3V
From: David Heidelberg david@ixit.cz
[ Upstream commit 458ebdbb8e5d596a462d8125cec74142ff5dfa97 ]
There's no reason the timer needs > 32-bits of address or size. Since we using 32-bit size, we need to define ranges properly.
Fixes warnings as: ``` arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dt.yaml: timer@17c90000: #size-cells:0:0: 1 was expected From schema: Documentation/devicetree/bindings/timer/arm,arch_timer_mmio.yaml ```
Signed-off-by: David Heidelberg david@ixit.cz Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220626105800.35586-1-david@ixit.cz Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/ipq6018.dtsi | 22 +++++++++++----------- arch/arm64/boot/dts/qcom/sc7180.dtsi | 22 +++++++++++----------- arch/arm64/boot/dts/qcom/sc7280.dtsi | 22 +++++++++++----------- arch/arm64/boot/dts/qcom/sdm845.dtsi | 22 +++++++++++----------- arch/arm64/boot/dts/qcom/sm6350.dtsi | 22 +++++++++++----------- arch/arm64/boot/dts/qcom/sm8150.dtsi | 22 +++++++++++----------- arch/arm64/boot/dts/qcom/sm8250.dtsi | 22 +++++++++++----------- arch/arm64/boot/dts/qcom/sm8350.dtsi | 22 +++++++++++----------- arch/arm64/boot/dts/qcom/sm8450.dtsi | 22 +++++++++++----------- 9 files changed, 99 insertions(+), 99 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi index c89499e366d3..748575ed1490 100644 --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi @@ -525,9 +525,9 @@ timer { };
timer@b120000 { - #address-cells = <2>; - #size-cells = <2>; - ranges; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0x10000000>; compatible = "arm,armv7-timer-mem"; reg = <0x0 0x0b120000 0x0 0x1000>;
@@ -535,49 +535,49 @@ frame@b120000 { frame-number = <0>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x0b121000 0x0 0x1000>, - <0x0 0x0b122000 0x0 0x1000>; + reg = <0x0b121000 0x1000>, + <0x0b122000 0x1000>; };
frame@b123000 { frame-number = <1>; interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0xb123000 0x0 0x1000>; + reg = <0x0b123000 0x1000>; status = "disabled"; };
frame@b124000 { frame-number = <2>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x0b124000 0x0 0x1000>; + reg = <0x0b124000 0x1000>; status = "disabled"; };
frame@b125000 { frame-number = <3>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x0b125000 0x0 0x1000>; + reg = <0x0b125000 0x1000>; status = "disabled"; };
frame@b126000 { frame-number = <4>; interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x0b126000 0x0 0x1000>; + reg = <0x0b126000 0x1000>; status = "disabled"; };
frame@b127000 { frame-number = <5>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x0b127000 0x0 0x1000>; + reg = <0x0b127000 0x1000>; status = "disabled"; };
frame@b128000 { frame-number = <6>; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x0b128000 0x0 0x1000>; + reg = <0x0b128000 0x1000>; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 5dcaac23a138..2006f416e3e2 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -3384,9 +3384,9 @@ watchdog@17c10000 { };
timer@17c20000{ - #address-cells = <2>; - #size-cells = <2>; - ranges; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0x20000000>; compatible = "arm,armv7-timer-mem"; reg = <0 0x17c20000 0 0x1000>;
@@ -3394,49 +3394,49 @@ frame@17c21000 { frame-number = <0>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c21000 0 0x1000>, - <0 0x17c22000 0 0x1000>; + reg = <0x17c21000 0x1000>, + <0x17c22000 0x1000>; };
frame@17c23000 { frame-number = <1>; interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c23000 0 0x1000>; + reg = <0x17c23000 0x1000>; status = "disabled"; };
frame@17c25000 { frame-number = <2>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c25000 0 0x1000>; + reg = <0x17c25000 0x1000>; status = "disabled"; };
frame@17c27000 { frame-number = <3>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c27000 0 0x1000>; + reg = <0x17c27000 0x1000>; status = "disabled"; };
frame@17c29000 { frame-number = <4>; interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c29000 0 0x1000>; + reg = <0x17c29000 0x1000>; status = "disabled"; };
frame@17c2b000 { frame-number = <5>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c2b000 0 0x1000>; + reg = <0x17c2b000 0x1000>; status = "disabled"; };
frame@17c2d000 { frame-number = <6>; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c2d000 0 0x1000>; + reg = <0x17c2d000 0x1000>; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index e66fc67de206..a7b128186b65 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -4771,9 +4771,9 @@ watchdog@17c10000 { };
timer@17c20000 { - #address-cells = <2>; - #size-cells = <2>; - ranges; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0x20000000>; compatible = "arm,armv7-timer-mem"; reg = <0 0x17c20000 0 0x1000>;
@@ -4781,49 +4781,49 @@ frame@17c21000 { frame-number = <0>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c21000 0 0x1000>, - <0 0x17c22000 0 0x1000>; + reg = <0x17c21000 0x1000>, + <0x17c22000 0x1000>; };
frame@17c23000 { frame-number = <1>; interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c23000 0 0x1000>; + reg = <0x17c23000 0x1000>; status = "disabled"; };
frame@17c25000 { frame-number = <2>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c25000 0 0x1000>; + reg = <0x17c25000 0x1000>; status = "disabled"; };
frame@17c27000 { frame-number = <3>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c27000 0 0x1000>; + reg = <0x17c27000 0x1000>; status = "disabled"; };
frame@17c29000 { frame-number = <4>; interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c29000 0 0x1000>; + reg = <0x17c29000 0x1000>; status = "disabled"; };
frame@17c2b000 { frame-number = <5>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c2b000 0 0x1000>; + reg = <0x17c2b000 0x1000>; status = "disabled"; };
frame@17c2d000 { frame-number = <6>; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17c2d000 0 0x1000>; + reg = <0x17c2d000 0x1000>; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 038538c8c614..7783005c8028 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -4948,9 +4948,9 @@ slimbam: dma-controller@17184000 { };
timer@17c90000 { - #address-cells = <2>; - #size-cells = <2>; - ranges; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0x20000000>; compatible = "arm,armv7-timer-mem"; reg = <0 0x17c90000 0 0x1000>;
@@ -4958,49 +4958,49 @@ frame@17ca0000 { frame-number = <0>; interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17ca0000 0 0x1000>, - <0 0x17cb0000 0 0x1000>; + reg = <0x17ca0000 0x1000>, + <0x17cb0000 0x1000>; };
frame@17cc0000 { frame-number = <1>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17cc0000 0 0x1000>; + reg = <0x17cc0000 0x1000>; status = "disabled"; };
frame@17cd0000 { frame-number = <2>; interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17cd0000 0 0x1000>; + reg = <0x17cd0000 0x1000>; status = "disabled"; };
frame@17ce0000 { frame-number = <3>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17ce0000 0 0x1000>; + reg = <0x17ce0000 0x1000>; status = "disabled"; };
frame@17cf0000 { frame-number = <4>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17cf0000 0 0x1000>; + reg = <0x17cf0000 0x1000>; status = "disabled"; };
frame@17d00000 { frame-number = <5>; interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17d00000 0 0x1000>; + reg = <0x17d00000 0x1000>; status = "disabled"; };
frame@17d10000 { frame-number = <6>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - reg = <0 0x17d10000 0 0x1000>; + reg = <0x17d10000 0x1000>; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi index d4f8f33f3f0c..b44734cd8d6f 100644 --- a/arch/arm64/boot/dts/qcom/sm6350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi @@ -1304,57 +1304,57 @@ timer@17c20000 { compatible = "arm,armv7-timer-mem"; reg = <0x0 0x17c20000 0x0 0x1000>; clock-frequency = <19200000>; - #address-cells = <2>; - #size-cells = <2>; - ranges; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0x20000000>;
frame@17c21000 { frame-number = <0>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c21000 0x0 0x1000>, - <0x0 0x17c22000 0x0 0x1000>; + reg = <0x17c21000 0x1000>, + <0x17c22000 0x1000>; };
frame@17c23000 { frame-number = <1>; interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c23000 0x0 0x1000>; + reg = <0x17c23000 0x1000>; status = "disabled"; };
frame@17c25000 { frame-number = <2>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c25000 0x0 0x1000>; + reg = <0x17c25000 0x1000>; status = "disabled"; };
frame@17c27000 { frame-number = <3>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c27000 0x0 0x1000>; + reg = <0x17c27000 0x1000>; status = "disabled"; };
frame@17c29000 { frame-number = <4>; interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c29000 0x0 0x1000>; + reg = <0x17c29000 0x1000>; status = "disabled"; };
frame@17c2b000 { frame-number = <5>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c2b000 0x0 0x1000>; + reg = <0x17c2b000 0x1000>; status = "disabled"; };
frame@17c2d000 { frame-number = <6>; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c2d000 0x0 0x1000>; + reg = <0x17c2d000 0x1000>; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi index 8ea44c4b56b4..592be9945cb8 100644 --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -3944,9 +3944,9 @@ watchdog@17c10000 { };
timer@17c20000 { - #address-cells = <2>; - #size-cells = <2>; - ranges; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0x20000000>; compatible = "arm,armv7-timer-mem"; reg = <0x0 0x17c20000 0x0 0x1000>; clock-frequency = <19200000>; @@ -3955,49 +3955,49 @@ frame@17c21000{ frame-number = <0>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c21000 0x0 0x1000>, - <0x0 0x17c22000 0x0 0x1000>; + reg = <0x17c21000 0x1000>, + <0x17c22000 0x1000>; };
frame@17c23000 { frame-number = <1>; interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c23000 0x0 0x1000>; + reg = <0x17c23000 0x1000>; status = "disabled"; };
frame@17c25000 { frame-number = <2>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c25000 0x0 0x1000>; + reg = <0x17c25000 0x1000>; status = "disabled"; };
frame@17c27000 { frame-number = <3>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c26000 0x0 0x1000>; + reg = <0x17c26000 0x1000>; status = "disabled"; };
frame@17c29000 { frame-number = <4>; interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c29000 0x0 0x1000>; + reg = <0x17c29000 0x1000>; status = "disabled"; };
frame@17c2b000 { frame-number = <5>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c2b000 0x0 0x1000>; + reg = <0x17c2b000 0x1000>; status = "disabled"; };
frame@17c2d000 { frame-number = <6>; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c2d000 0x0 0x1000>; + reg = <0x17c2d000 0x1000>; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index cf0c97bd5ad3..5dae1b8469a2 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -4867,9 +4867,9 @@ watchdog@17c10000 { };
timer@17c20000 { - #address-cells = <2>; - #size-cells = <2>; - ranges; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0x20000000>; compatible = "arm,armv7-timer-mem"; reg = <0x0 0x17c20000 0x0 0x1000>; clock-frequency = <19200000>; @@ -4878,49 +4878,49 @@ frame@17c21000 { frame-number = <0>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c21000 0x0 0x1000>, - <0x0 0x17c22000 0x0 0x1000>; + reg = <0x17c21000 0x1000>, + <0x17c22000 0x1000>; };
frame@17c23000 { frame-number = <1>; interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c23000 0x0 0x1000>; + reg = <0x17c23000 0x1000>; status = "disabled"; };
frame@17c25000 { frame-number = <2>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c25000 0x0 0x1000>; + reg = <0x17c25000 0x1000>; status = "disabled"; };
frame@17c27000 { frame-number = <3>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c27000 0x0 0x1000>; + reg = <0x17c27000 0x1000>; status = "disabled"; };
frame@17c29000 { frame-number = <4>; interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c29000 0x0 0x1000>; + reg = <0x17c29000 0x1000>; status = "disabled"; };
frame@17c2b000 { frame-number = <5>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c2b000 0x0 0x1000>; + reg = <0x17c2b000 0x1000>; status = "disabled"; };
frame@17c2d000 { frame-number = <6>; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c2d000 0x0 0x1000>; + reg = <0x17c2d000 0x1000>; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index 743cba9b683c..2b80d8f89d18 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -1933,9 +1933,9 @@ intc: interrupt-controller@17a00000 {
timer@17c20000 { compatible = "arm,armv7-timer-mem"; - #address-cells = <2>; - #size-cells = <2>; - ranges; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0x20000000>; reg = <0x0 0x17c20000 0x0 0x1000>; clock-frequency = <19200000>;
@@ -1943,49 +1943,49 @@ frame@17c21000 { frame-number = <0>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c21000 0x0 0x1000>, - <0x0 0x17c22000 0x0 0x1000>; + reg = <0x17c21000 0x1000>, + <0x17c22000 0x1000>; };
frame@17c23000 { frame-number = <1>; interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c23000 0x0 0x1000>; + reg = <0x17c23000 0x1000>; status = "disabled"; };
frame@17c25000 { frame-number = <2>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c25000 0x0 0x1000>; + reg = <0x17c25000 0x1000>; status = "disabled"; };
frame@17c27000 { frame-number = <3>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c27000 0x0 0x1000>; + reg = <0x17c27000 0x1000>; status = "disabled"; };
frame@17c29000 { frame-number = <4>; interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c29000 0x0 0x1000>; + reg = <0x17c29000 0x1000>; status = "disabled"; };
frame@17c2b000 { frame-number = <5>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c2b000 0x0 0x1000>; + reg = <0x17c2b000 0x1000>; status = "disabled"; };
frame@17c2d000 { frame-number = <6>; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17c2d000 0x0 0x1000>; + reg = <0x17c2d000 0x1000>; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi index b87756bf1ce4..c958f5d4adc2 100644 --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -2867,9 +2867,9 @@ gic_its: msi-controller@17140000 {
timer@17420000 { compatible = "arm,armv7-timer-mem"; - #address-cells = <2>; - #size-cells = <2>; - ranges; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0x20000000>; reg = <0x0 0x17420000 0x0 0x1000>; clock-frequency = <19200000>;
@@ -2877,49 +2877,49 @@ frame@17421000 { frame-number = <0>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17421000 0x0 0x1000>, - <0x0 0x17422000 0x0 0x1000>; + reg = <0x17421000 0x1000>, + <0x17422000 0x1000>; };
frame@17423000 { frame-number = <1>; interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17423000 0x0 0x1000>; + reg = <0x17423000 0x1000>; status = "disabled"; };
frame@17425000 { frame-number = <2>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17425000 0x0 0x1000>; + reg = <0x17425000 0x1000>; status = "disabled"; };
frame@17427000 { frame-number = <3>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17427000 0x0 0x1000>; + reg = <0x17427000 0x1000>; status = "disabled"; };
frame@17429000 { frame-number = <4>; interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x17429000 0x0 0x1000>; + reg = <0x17429000 0x1000>; status = "disabled"; };
frame@1742b000 { frame-number = <5>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x1742b000 0x0 0x1000>; + reg = <0x1742b000 0x1000>; status = "disabled"; };
frame@1742d000 { frame-number = <6>; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x0 0x1742d000 0x0 0x1000>; + reg = <0x1742d000 0x1000>; status = "disabled"; }; };
From: Guo Mengqi guomengqi3@huawei.com
[ Upstream commit 917e43de2a56d9b82576f1cc94748261f1988458 ]
Add missing clk_disable_unprepare() in synquacer_spi_resume().
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Guo Mengqi guomengqi3@huawei.com Link: https://lore.kernel.org/r/20220624005614.49434-1-guomengqi3@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-synquacer.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/spi/spi-synquacer.c b/drivers/spi/spi-synquacer.c index ea706d9629cb..47cbe73137c2 100644 --- a/drivers/spi/spi-synquacer.c +++ b/drivers/spi/spi-synquacer.c @@ -783,6 +783,7 @@ static int __maybe_unused synquacer_spi_resume(struct device *dev)
ret = synquacer_spi_enable(master); if (ret) { + clk_disable_unprepare(sspi->clk); dev_err(dev, "failed to enable spi (%d)\n", ret); return ret; }
From: Liang He windhl@126.com
[ Upstream commit 50b87a32a79bca6e275918a711fb8cc55e16d739 ]
In omapdss_init_fbdev(), of_find_node_by_name() will return a node pointer with refcount incremented. We should use of_node_put() when it is not used anymore.
Signed-off-by: Liang He windhl@126.com Message-Id: 20220617145803.4050918-1-windhl@126.com Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap2/display.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 21413a9b7b6c..eb09a25e3b45 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -211,6 +211,7 @@ static int __init omapdss_init_fbdev(void) node = of_find_node_by_name(NULL, "omap4_padconf_global"); if (node) omap4_dsi_mux_syscon = syscon_node_to_regmap(node); + of_node_put(node);
return 0; }
From: Liang He windhl@126.com
[ Upstream commit 5cdbab96bab314c6f2f5e4e8b8a019181328bf5f ]
In pdata_quirks_init_clocks(), the loop contains of_find_node_by_name() but without corresponding of_node_put().
Signed-off-by: Liang He windhl@126.com Message-Id: 20220618020603.4055792-1-windhl@126.com Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap2/pdata-quirks.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 13f1b89f74b8..5b99d602c87b 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -540,6 +540,8 @@ pdata_quirks_init_clocks(const struct of_device_id *omap_dt_match_table)
of_platform_populate(np, omap_dt_match_table, omap_auxdata_lookup, NULL); + + of_node_put(np); } }
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 0dd6db359e5f206cbf1dd1fd40dd211588cd2725 ]
Somehow the "ThinkPad X1 Carbon 6th" entry ended up twice in the struct dmi_system_id acpi_ec_no_wakeup[] array. Remove one of the entries.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/ec.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a1b871a418f8..f6a022892ee0 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -2207,13 +2207,6 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = { DMI_MATCH(DMI_PRODUCT_FAMILY, "Thinkpad X1 Carbon 6th"), }, }, - { - .ident = "ThinkPad X1 Carbon 6th", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Carbon 6th"), - }, - }, { .ident = "ThinkPad X1 Yoga 3rd", .matches = {
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit f7090e0ef360d674f08a22fab90e4e209fb1f658 ]
It seems that these quirks are no longer necessary since commit 69b957c26b32 ("ACPI: EC: Fix possible issues related to EC initialization order"), which has fixed this in a generic manner.
There are 3 commits adding DMI entries with this quirk (adding multiple DMI entries per commit). 2/3 commits are from before the generic fix.
Which leaves commit 6306f0431914 ("ACPI: EC: Make more Asus laptops use ECDT _GPE"), which was committed way after the generic fix. But this was just due to slow upstreaming of it. This commit stems from Endless from 15 Aug 2017 (committed upstream 20 May 2021): https://github.com/endlessm/linux/pull/288
The current code should work fine without this:
1. The EC_FLAGS_IGNORE_DSDT_GPE flag is only checked in ec_parse_device(), like this:
if (boot_ec && boot_ec_is_ecdt && EC_FLAGS_IGNORE_DSDT_GPE) { ec->gpe = boot_ec->gpe; } else { /* parse GPE */ }
2. ec_parse_device() is only called from acpi_ec_add() and acpi_ec_dsdt_probe()
3. acpi_ec_dsdt_probe() starts with:
if (boot_ec) return;
so it only calls ec_parse_device() when boot_ec == NULL, meaning that the quirk never triggers for this call. So only the call in acpi_ec_add() matters.
4. acpi_ec_add() does the following after the ec_parse_device() call:
if (boot_ec && ec->command_addr == boot_ec->command_addr && ec->data_addr == boot_ec->data_addr && !EC_FLAGS_TRUST_DSDT_GPE) { /* * Trust PNP0C09 namespace location rather than * ECDT ID. But trust ECDT GPE rather than _GPE * because of ASUS quirks, so do not change * boot_ec->gpe to ec->gpe. */ boot_ec->handle = ec->handle; acpi_handle_debug(ec->handle, "duplicated.\n"); acpi_ec_free(ec); ec = boot_ec; }
The quirk only matters if boot_ec != NULL and EC_FLAGS_TRUST_DSDT_GPE is never set at the same time as EC_FLAGS_IGNORE_DSDT_GPE.
That means that if the addresses match we always enter this if block and then only the ec->handle part of the data stored in ec by ec_parse_device() is used and the rest is thrown away, after which ec is made to point to boot_ec, at which point ec->gpe == boot_ec->gpe, so the same result as with the quirk set, independent of the value of the quirk.
Also note the comment in this block which indicates that the gpe result from ec_parse_device() is deliberately not taken to deal with buggy Asus laptops and all DMI quirks setting EC_FLAGS_IGNORE_DSDT_GPE are for Asus laptops.
Based on the above I believe that unless on some quirked laptops the ECDT and DSDT EC addresses do not match we can drop the quirk.
I've checked dmesg output to ensure the ECDT and DSDT EC addresses match for quirked models using https://linux-hardware.org hw-probe reports.
I've been able to confirm that the addresses match for the following models this way: GL702VMK, X505BA, X505BP, X550VXK, X580VD. Whereas for the following models I could find any dmesg output: FX502VD, FX502VE, X542BA, X542BP.
Note the models without dmesg all were submitted in patches with a batch of models and other models from the same batch checkout ok.
This, combined with that all the code adding the quirks was written before the generic fix makes me believe that it is safe to remove this quirk now.
Signed-off-by: Hans de Goede hdegoede@redhat.com Reviewed-by: Daniel Drake drake@endlessos.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/ec.c | 75 ++++++----------------------------------------- 1 file changed, 9 insertions(+), 66 deletions(-)
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f6a022892ee0..488c9ec0da0b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -180,7 +180,6 @@ static struct workqueue_struct *ec_wq; static struct workqueue_struct *ec_query_wq;
static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */ -static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */ static int EC_FLAGS_TRUST_DSDT_GPE; /* Needs DSDT GPE as correction setting */ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
@@ -1407,24 +1406,16 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) if (ec->data_addr == 0 || ec->command_addr == 0) return AE_OK;
- if (boot_ec && boot_ec_is_ecdt && EC_FLAGS_IGNORE_DSDT_GPE) { - /* - * Always inherit the GPE number setting from the ECDT - * EC. - */ - ec->gpe = boot_ec->gpe; - } else { - /* Get GPE bit assignment (EC events). */ - /* TODO: Add support for _GPE returning a package */ - status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); - if (ACPI_SUCCESS(status)) - ec->gpe = tmp; + /* Get GPE bit assignment (EC events). */ + /* TODO: Add support for _GPE returning a package */ + status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); + if (ACPI_SUCCESS(status)) + ec->gpe = tmp; + /* + * Errors are non-fatal, allowing for ACPI Reduced Hardware + * platforms which use GpioInt instead of GPE. + */
- /* - * Errors are non-fatal, allowing for ACPI Reduced Hardware - * platforms which use GpioInt instead of GPE. - */ - } /* Use the global lock for all EC transactions? */ tmp = 0; acpi_evaluate_integer(handle, "_GLK", NULL, &tmp); @@ -1862,60 +1853,12 @@ static int ec_honor_dsdt_gpe(const struct dmi_system_id *id) return 0; }
-/* - * Some DSDTs contain wrong GPE setting. - * Asus FX502VD/VE, GL702VMK, X550VXK, X580VD - * https://bugzilla.kernel.org/show_bug.cgi?id=195651 - */ -static int ec_honor_ecdt_gpe(const struct dmi_system_id *id) -{ - pr_debug("Detected system needing ignore DSDT GPE setting.\n"); - EC_FLAGS_IGNORE_DSDT_GPE = 1; - return 0; -} - static const struct dmi_system_id ec_dmi_table[] __initconst = { { ec_correct_ecdt, "MSI MS-171F", { DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star"), DMI_MATCH(DMI_PRODUCT_NAME, "MS-171F"),}, NULL}, { - ec_honor_ecdt_gpe, "ASUS FX502VD", { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "FX502VD"),}, NULL}, - { - ec_honor_ecdt_gpe, "ASUS FX502VE", { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "FX502VE"),}, NULL}, - { - ec_honor_ecdt_gpe, "ASUS GL702VMK", { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "GL702VMK"),}, NULL}, - { - ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BA", { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "X505BA"),}, NULL}, - { - ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BP", { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "X505BP"),}, NULL}, - { - ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BA", { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "X542BA"),}, NULL}, - { - ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BP", { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "X542BP"),}, NULL}, - { - ec_honor_ecdt_gpe, "ASUS X550VXK", { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "X550VXK"),}, NULL}, - { - ec_honor_ecdt_gpe, "ASUS X580VD", { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL}, - { /* https://bugzilla.kernel.org/show_bug.cgi?id=209989 */ ec_honor_dsdt_gpe, "HP Pavilion Gaming Laptop 15-cx0xxx", { DMI_MATCH(DMI_SYS_VENDOR, "HP"),
From: Manyi Li limanyi@uniontech.com
[ Upstream commit 4b7ef7b05afcde44142225c184bf43a0cd9e2178 ]
[821d6f0359b0614792ab8e2fb93b503e25a65079] is to make machines produced from 2012 to now not saving NVS region to accelerate S3.
But, Lenovo G40-45, a platform released in 2015, still needs NVS memory saving during S3. A quirk is introduced for this platform.
Signed-off-by: Manyi Li limanyi@uniontech.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/sleep.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 04ea1569df78..974746e6e59d 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -360,6 +360,14 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), }, }, + { + .callback = init_nvs_save_s3, + .ident = "Lenovo G40-45", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "80E1"), + }, + }, /* * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using * the Low Power S0 Idle firmware interface (see
From: huhai huhai@kylinos.cn
[ Upstream commit b4f1f61ed5928b1128e60e38d0dffa16966f06dc ]
register_device_clock() misses a check for platform_device_register_simple(). Add a check to fix it.
Signed-off-by: huhai huhai@kylinos.cn Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/acpi_lpss.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index fbe0756259c5..c4d4d21391d7 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -422,6 +422,9 @@ static int register_device_clock(struct acpi_device *adev, if (!lpss_clk_dev) lpt_register_clock_device();
+ if (IS_ERR(lpss_clk_dev)) + return PTR_ERR(lpss_clk_dev); + clk_data = platform_get_drvdata(lpss_clk_dev); if (!clk_data) return -ENODEV;
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
[ Upstream commit ae500b351ab0006d933d804a2b7507fe1e98cecc ]
The trigger type should be LEVEL_HIGH. So fix it!
Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220530080842.37024-2-manivannan.sadhasivam@linar... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-sdx55.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom-sdx55.dtsi index 1c2b208a5670..ef1da28f567c 100644 --- a/arch/arm/boot/dts/qcom-sdx55.dtsi +++ b/arch/arm/boot/dts/qcom-sdx55.dtsi @@ -206,7 +206,7 @@ gcc: clock-controller@100000 { blsp1_uart3: serial@831000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; reg = <0x00831000 0x200>; - interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_LOW>; + interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; clocks = <&gcc 30>, <&gcc 9>; clock-names = "core", "iface";
From: Gwendal Grignou gwendal@chromium.org
[ Upstream commit 9c54f1711fc2516faf1f8d31217462184157b429 ]
To ease matching configuration of sysfs attributes for particular sensor, match label reported by iio 'label' attribute with the location label generated by ChromeOS config tool.
Signed-off-by: Gwendal Grignou gwendal@chromium.org Reviewed-by: Douglas Anderson dianders@chromium.org Reviewed-by: Stephen Boyd swboyd@chromium.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220623223119.1858863-1-gwendal@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi index 9cb1bc8ed6b5..8b96fad5fdd4 100644 --- a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi @@ -388,7 +388,7 @@ ap_sar_sensor0: proximity@28 {
vdd-supply = <&pp1800_prox>;
- label = "proximity-wifi-lte0"; + label = "proximity-wifi_cellular-0"; status = "disabled"; };
@@ -404,7 +404,7 @@ ap_sar_sensor1: proximity@2c {
vdd-supply = <&pp1800_prox>;
- label = "proximity-wifi-lte1"; + label = "proximity-wifi_cellular-1"; status = "disabled"; }; };
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 6ba93ba9f63fbc44c3a6af7fe6f2536d009cfd5a ]
The AOSS QMP bindings expect all compatibles to be followed by fallback "qcom,aoss-qmp" because all of these are actually compatible with each other. This fixes dtbs_check warnings like:
sm8250-hdk.dtb: power-controller@c300000: compatible: ['qcom,sm8250-aoss-qmp'] is too short
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220504131923.214367-6-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 2 +- arch/arm64/boot/dts/qcom/sc7280.dtsi | 2 +- arch/arm64/boot/dts/qcom/sm8150.dtsi | 2 +- arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +- arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 2006f416e3e2..8769ad30f1c7 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -3215,7 +3215,7 @@ aoss_reset: reset-controller@c2a0000 { };
aoss_qmp: power-controller@c300000 { - compatible = "qcom,sc7180-aoss-qmp"; + compatible = "qcom,sc7180-aoss-qmp", "qcom,aoss-qmp"; reg = <0 0x0c300000 0 0x400>; interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>; mboxes = <&apss_shared 0>; diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index a7b128186b65..d22405658f13 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -3843,7 +3843,7 @@ aoss_reset: reset-controller@c2a0000 { };
aoss_qmp: power-controller@c300000 { - compatible = "qcom,sc7280-aoss-qmp"; + compatible = "qcom,sc7280-aoss-qmp", "qcom,aoss-qmp"; reg = <0 0x0c300000 0 0x400>; interrupts-extended = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi index 592be9945cb8..8abaa28cebbc 100644 --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -3718,7 +3718,7 @@ pdc: interrupt-controller@b220000 { };
aoss_qmp: power-controller@c300000 { - compatible = "qcom,sm8150-aoss-qmp"; + compatible = "qcom,sm8150-aoss-qmp", "qcom,aoss-qmp"; reg = <0x0 0x0c300000 0x0 0x400>; interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>; mboxes = <&apss_shared 0>; diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index 5dae1b8469a2..d0760e6ec942 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -3734,7 +3734,7 @@ tsens1: thermal-sensor@c265000 { };
aoss_qmp: power-controller@c300000 { - compatible = "qcom,sm8250-aoss-qmp"; + compatible = "qcom,sm8250-aoss-qmp", "qcom,aoss-qmp"; reg = <0 0x0c300000 0 0x400>; interrupts-extended = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index 2b80d8f89d18..3293f76478df 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -1718,7 +1718,7 @@ tsens1: thermal-sensor@c265000 { };
aoss_qmp: power-controller@c300000 { - compatible = "qcom,sm8350-aoss-qmp"; + compatible = "qcom,sm8350-aoss-qmp", "qcom,aoss-qmp"; reg = <0 0x0c300000 0 0x400>; interrupts-extended = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP IRQ_TYPE_EDGE_RISING>;
From: Robert Marko robimarko@gmail.com
[ Upstream commit b39961659ffc3c3a9e3d0d43b0476547b5f35d49 ]
Per schema it should be nand-controller@79b0000 instead of nand@79b0000. Fix it to match nand-controller.yaml requirements.
Signed-off-by: Robert Marko robimarko@gmail.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220621120642.518575-1-robimarko@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 4c38b15c6fd4..697f46e17903 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -534,7 +534,7 @@ qpic_bam: dma-controller@7984000 { status = "disabled"; };
- qpic_nand: nand@79b0000 { + qpic_nand: nand-controller@79b0000 { compatible = "qcom,ipq8074-nand"; reg = <0x079b0000 0x10000>; #address-cells = <1>;
From: Samuel Holland samuel@sholland.org
[ Upstream commit b8eb2df19fbf97aa1e950cf491232c2e3bef8357 ]
"status" does not match any pattern in the gpio-leds binding. Rename the node to the preferred pattern. This fixes a `make dtbs_check` error.
Signed-off-by: Samuel Holland samuel@sholland.org Reviewed-by: Jernej Skrabec jernej.skrabec@gmail.com Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Link: https://lore.kernel.org/r/20220702132816.46456-1-samuel@sholland.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts index c519d9fa6967..3d2c68d58f49 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts @@ -40,7 +40,7 @@ hdmi_con_in: endpoint { leds { compatible = "gpio-leds";
- status { + led-0 { label = "orangepi:green:status"; gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */ };
From: Liang He windhl@126.com
[ Upstream commit 75a185fb92e58ccd3670258d8d3b826bd2fa6d29 ]
In rcar_gen2_regulator_quirk(), for_each_matching_node_and_match() will automatically increase and decrease the refcount. However, we should call of_node_get() for the new reference created in 'quirk->np'. Besides, we also should call of_node_put() before the 'quirk' being freed.
Signed-off-by: Liang He windhl@126.com Link: https://lore.kernel.org/r/20220701121804.234223-1-windhl@126.com Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c index abea41f7782e..117e7b07995b 100644 --- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c +++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c @@ -125,6 +125,7 @@ static int regulator_quirk_notify(struct notifier_block *nb,
list_for_each_entry_safe(pos, tmp, &quirk_list, list) { list_del(&pos->list); + of_node_put(pos->np); kfree(pos); }
@@ -174,11 +175,12 @@ static int __init rcar_gen2_regulator_quirk(void) memcpy(&quirk->i2c_msg, id->data, sizeof(quirk->i2c_msg));
quirk->id = id; - quirk->np = np; + quirk->np = of_node_get(np); quirk->i2c_msg.addr = addr;
ret = of_irq_parse_one(np, 0, argsa); if (ret) { /* Skip invalid entry and continue */ + of_node_put(np); kfree(quirk); continue; } @@ -225,6 +227,7 @@ static int __init rcar_gen2_regulator_quirk(void) err_mem: list_for_each_entry_safe(pos, tmp, &quirk_list, list) { list_del(&pos->list); + of_node_put(pos->np); kfree(pos); }
From: Lv Ruyi lv.ruyi@zte.com.cn
[ Upstream commit afcdb8e55c91c6ff0700ab272fd0f74e899ab884 ]
If an error occurs, debugfs_create_file() will return ERR_PTR(-ERROR), so use IS_ERR() to check it.
Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Lv Ruyi lv.ruyi@zte.com.cn Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/tegra/bpmp-debugfs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/tegra/bpmp-debugfs.c b/drivers/firmware/tegra/bpmp-debugfs.c index fd89899aeeed..0c440afd5224 100644 --- a/drivers/firmware/tegra/bpmp-debugfs.c +++ b/drivers/firmware/tegra/bpmp-debugfs.c @@ -474,7 +474,7 @@ static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp, mode |= attrs & DEBUGFS_S_IWUSR ? 0200 : 0; dentry = debugfs_create_file(name, mode, parent, bpmp, &bpmp_debug_fops); - if (!dentry) { + if (IS_ERR(dentry)) { err = -ENOMEM; goto out; } @@ -725,7 +725,7 @@ static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf,
if (t & DEBUGFS_S_ISDIR) { dentry = debugfs_create_dir(name, parent); - if (!dentry) + if (IS_ERR(dentry)) return -ENOMEM; err = bpmp_populate_dir(bpmp, seqbuf, dentry, depth+1); if (err < 0) @@ -738,7 +738,7 @@ static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf, dentry = debugfs_create_file(name, mode, parent, bpmp, &debugfs_fops); - if (!dentry) + if (IS_ERR(dentry)) return -ENOMEM; } } @@ -788,11 +788,11 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp) return 0;
root = debugfs_create_dir("bpmp", NULL); - if (!root) + if (IS_ERR(root)) return -ENOMEM;
bpmp->debugfs_mirror = debugfs_create_dir("debug", root); - if (!bpmp->debugfs_mirror) { + if (IS_ERR(bpmp->debugfs_mirror)) { err = -ENOMEM; goto out; }
From: Armin Wolf W_Armin@gmx.de
[ Upstream commit 385e5f57053ff293282fea84c1c27186d53f66e1 ]
A user reported that the program dell-bios-fan-control worked on his Dell XPS 13 7390 to switch off automatic fan control. Since it uses the same mechanism as the dell_smm_hwmon module, add this model to the fan control whitelist.
Compile-tested only.
Signed-off-by: Armin Wolf W_Armin@gmx.de Acked-by: Pali Rohár pali@kernel.org Link: https://lore.kernel.org/r/20220612041806.11367-1-W_Armin@gmx.de Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/dell-smm-hwmon.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c index 071aa6f4e109..16c10ac84a91 100644 --- a/drivers/hwmon/dell-smm-hwmon.c +++ b/drivers/hwmon/dell-smm-hwmon.c @@ -1365,6 +1365,14 @@ static const struct dmi_system_id i8k_whitelist_fan_control[] __initconst = { }, .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3], }, + { + .ident = "Dell XPS 13 7390", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 13 7390"), + }, + .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3], + }, { } };
From: Lukasz Luba lukasz.luba@arm.com
[ Upstream commit ae6ccaa650380d243cf43d31c864c5ced2fd4612 ]
The milli-Watts precision causes rounding errors while calculating efficiency cost for each OPP. This is especially visible in the 'simple' Energy Model (EM), where the power for each OPP is provided from OPP framework. This can cause some OPPs to be marked inefficient, while using micro-Watts precision that might not happen.
Update all EM users which access 'power' field and assume the value is in milli-Watts.
Solve also an issue with potential overflow in calculation of energy estimation on 32bit machine. It's needed now since the power value (thus the 'cost' as well) are higher.
Example calculation which shows the rounding error and impact:
power = 'dyn-power-coeff' * volt_mV * volt_mV * freq_MHz
power_a_uW = (100 * 600mW * 600mW * 500MHz) / 10^6 = 18000 power_a_mW = (100 * 600mW * 600mW * 500MHz) / 10^9 = 18
power_b_uW = (100 * 605mW * 605mW * 600MHz) / 10^6 = 21961 power_b_mW = (100 * 605mW * 605mW * 600MHz) / 10^9 = 21
max_freq = 2000MHz
cost_a_mW = 18 * 2000MHz/500MHz = 72 cost_a_uW = 18000 * 2000MHz/500MHz = 72000
cost_b_mW = 21 * 2000MHz/600MHz = 70 // <- artificially better cost_b_uW = 21961 * 2000MHz/600MHz = 73203
The 'cost_b_mW' (which is based on old milli-Watts) is misleadingly better that the 'cost_b_uW' (this patch uses micro-Watts) and such would have impact on the 'inefficient OPPs' information in the Cpufreq framework. This patch set removes the rounding issue.
Signed-off-by: Lukasz Luba lukasz.luba@arm.com Acked-by: Daniel Lezcano daniel.lezcano@linaro.org Acked-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/mediatek-cpufreq-hw.c | 7 ++-- drivers/cpufreq/scmi-cpufreq.c | 6 +++ drivers/opp/of.c | 15 ++++---- drivers/powercap/dtpm_cpu.c | 5 +-- drivers/thermal/cpufreq_cooling.c | 13 ++++++- drivers/thermal/devfreq_cooling.c | 19 ++++++++-- include/linux/energy_model.h | 54 +++++++++++++++++++-------- kernel/power/energy_model.c | 24 ++++++++---- 8 files changed, 100 insertions(+), 43 deletions(-)
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c index 813cccbfe934..f0e0a35c7f21 100644 --- a/drivers/cpufreq/mediatek-cpufreq-hw.c +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c @@ -51,7 +51,7 @@ static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = { };
static int __maybe_unused -mtk_cpufreq_get_cpu_power(struct device *cpu_dev, unsigned long *mW, +mtk_cpufreq_get_cpu_power(struct device *cpu_dev, unsigned long *uW, unsigned long *KHz) { struct mtk_cpufreq_data *data; @@ -71,8 +71,9 @@ mtk_cpufreq_get_cpu_power(struct device *cpu_dev, unsigned long *mW, i--;
*KHz = data->table[i].frequency; - *mW = readl_relaxed(data->reg_bases[REG_EM_POWER_TBL] + - i * LUT_ROW_SIZE) / 1000; + /* Provide micro-Watts value to the Energy Model */ + *uW = readl_relaxed(data->reg_bases[REG_EM_POWER_TBL] + + i * LUT_ROW_SIZE);
return 0; } diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c index 6d2a4cf46db7..bfd35583d653 100644 --- a/drivers/cpufreq/scmi-cpufreq.c +++ b/drivers/cpufreq/scmi-cpufreq.c @@ -19,6 +19,7 @@ #include <linux/slab.h> #include <linux/scmi_protocol.h> #include <linux/types.h> +#include <linux/units.h>
struct scmi_data { int domain_id; @@ -99,6 +100,7 @@ static int __maybe_unused scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power, unsigned long *KHz) { + bool power_scale_mw = perf_ops->power_scale_mw_get(ph); unsigned long Hz; int ret, domain;
@@ -112,6 +114,10 @@ scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power, if (ret) return ret;
+ /* Provide bigger resolution power to the Energy Model */ + if (power_scale_mw) + *power *= MICROWATT_PER_MILLIWATT; + /* The EM framework specifies the frequency in KHz. */ *KHz = Hz / 1000;
diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 30394929d700..eb89c9a75985 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -1443,12 +1443,12 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node); * It provides the power used by @dev at @kHz if it is the frequency of an * existing OPP, or at the frequency of the first OPP above @kHz otherwise * (see dev_pm_opp_find_freq_ceil()). This function updates @kHz to the ceiled - * frequency and @mW to the associated power. + * frequency and @uW to the associated power. * * Returns 0 on success or a proper -EINVAL value in case of error. */ static int __maybe_unused -_get_dt_power(struct device *dev, unsigned long *mW, unsigned long *kHz) +_get_dt_power(struct device *dev, unsigned long *uW, unsigned long *kHz) { struct dev_pm_opp *opp; unsigned long opp_freq, opp_power; @@ -1465,7 +1465,7 @@ _get_dt_power(struct device *dev, unsigned long *mW, unsigned long *kHz) return -EINVAL;
*kHz = opp_freq / 1000; - *mW = opp_power / 1000; + *uW = opp_power;
return 0; } @@ -1475,14 +1475,14 @@ _get_dt_power(struct device *dev, unsigned long *mW, unsigned long *kHz) * This computes the power estimated by @dev at @kHz if it is the frequency * of an existing OPP, or at the frequency of the first OPP above @kHz otherwise * (see dev_pm_opp_find_freq_ceil()). This function updates @kHz to the ceiled - * frequency and @mW to the associated power. The power is estimated as + * frequency and @uW to the associated power. The power is estimated as * P = C * V^2 * f with C being the device's capacitance and V and f * respectively the voltage and frequency of the OPP. * * Returns -EINVAL if the power calculation failed because of missing * parameters, 0 otherwise. */ -static int __maybe_unused _get_power(struct device *dev, unsigned long *mW, +static int __maybe_unused _get_power(struct device *dev, unsigned long *uW, unsigned long *kHz) { struct dev_pm_opp *opp; @@ -1512,9 +1512,10 @@ static int __maybe_unused _get_power(struct device *dev, unsigned long *mW, return -EINVAL;
tmp = (u64)cap * mV * mV * (Hz / 1000000); - do_div(tmp, 1000000000); + /* Provide power in micro-Watts */ + do_div(tmp, 1000000);
- *mW = (unsigned long)tmp; + *uW = (unsigned long)tmp; *kHz = Hz / 1000;
return 0; diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c index f5eced0842b3..61c5ff80bd30 100644 --- a/drivers/powercap/dtpm_cpu.c +++ b/drivers/powercap/dtpm_cpu.c @@ -53,7 +53,7 @@ static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit)
for (i = 0; i < pd->nr_perf_states; i++) {
- power = pd->table[i].power * MICROWATT_PER_MILLIWATT * nr_cpus; + power = pd->table[i].power * nr_cpus;
if (power > power_limit) break; @@ -63,8 +63,7 @@ static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit)
freq_qos_update_request(&dtpm_cpu->qos_req, freq);
- power_limit = pd->table[i - 1].power * - MICROWATT_PER_MILLIWATT * nr_cpus; + power_limit = pd->table[i - 1].power * nr_cpus;
return power_limit; } diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index b8151d95a806..dc19e7c80751 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -21,6 +21,7 @@ #include <linux/pm_qos.h> #include <linux/slab.h> #include <linux/thermal.h> +#include <linux/units.h>
#include <trace/events/thermal.h>
@@ -101,6 +102,7 @@ static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_cdev, static u32 cpu_freq_to_power(struct cpufreq_cooling_device *cpufreq_cdev, u32 freq) { + unsigned long power_mw; int i;
for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) { @@ -108,16 +110,23 @@ static u32 cpu_freq_to_power(struct cpufreq_cooling_device *cpufreq_cdev, break; }
- return cpufreq_cdev->em->table[i + 1].power; + power_mw = cpufreq_cdev->em->table[i + 1].power; + power_mw /= MICROWATT_PER_MILLIWATT; + + return power_mw; }
static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev, u32 power) { + unsigned long em_power_mw; int i;
for (i = cpufreq_cdev->max_level; i > 0; i--) { - if (power >= cpufreq_cdev->em->table[i].power) + /* Convert EM power to milli-Watts to make safe comparison */ + em_power_mw = cpufreq_cdev->em->table[i].power; + em_power_mw /= MICROWATT_PER_MILLIWATT; + if (power >= em_power_mw) break; }
diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index 8c76f9655e57..8d1260f65061 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -200,7 +200,11 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd res = dfc->power_ops->get_real_power(df, power, freq, voltage); if (!res) { state = dfc->capped_state; + + /* Convert EM power into milli-Watts first */ dfc->res_util = dfc->em_pd->table[state].power; + dfc->res_util /= MICROWATT_PER_MILLIWATT; + dfc->res_util *= SCALE_ERROR_MITIGATION;
if (*power > 1) @@ -218,8 +222,10 @@ static int devfreq_cooling_get_requested_power(struct thermal_cooling_device *cd
_normalize_load(&status);
- /* Scale power for utilization */ + /* Convert EM power into milli-Watts first */ *power = dfc->em_pd->table[perf_idx].power; + *power /= MICROWATT_PER_MILLIWATT; + /* Scale power for utilization */ *power *= status.busy_time; *power >>= 10; } @@ -244,6 +250,7 @@ static int devfreq_cooling_state2power(struct thermal_cooling_device *cdev,
perf_idx = dfc->max_state - state; *power = dfc->em_pd->table[perf_idx].power; + *power /= MICROWATT_PER_MILLIWATT;
return 0; } @@ -254,7 +261,7 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev, struct devfreq_cooling_device *dfc = cdev->devdata; struct devfreq *df = dfc->devfreq; struct devfreq_dev_status status; - unsigned long freq; + unsigned long freq, em_power_mw; s32 est_power; int i;
@@ -279,9 +286,13 @@ static int devfreq_cooling_power2state(struct thermal_cooling_device *cdev, * Find the first cooling state that is within the power * budget. The EM power table is sorted ascending. */ - for (i = dfc->max_state; i > 0; i--) - if (est_power >= dfc->em_pd->table[i].power) + for (i = dfc->max_state; i > 0; i--) { + /* Convert EM power to milli-Watts to make safe comparison */ + em_power_mw = dfc->em_pd->table[i].power; + em_power_mw /= MICROWATT_PER_MILLIWATT; + if (est_power >= em_power_mw) break; + }
*state = dfc->max_state - i; dfc->capped_state = *state; diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index 8419bffb4398..b9caa01dfac4 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -62,7 +62,7 @@ struct em_perf_domain { /* * em_perf_domain flags: * - * EM_PERF_DOMAIN_MILLIWATTS: The power values are in milli-Watts or some + * EM_PERF_DOMAIN_MICROWATTS: The power values are in micro-Watts or some * other scale. * * EM_PERF_DOMAIN_SKIP_INEFFICIENCIES: Skip inefficient states when estimating @@ -71,7 +71,7 @@ struct em_perf_domain { * EM_PERF_DOMAIN_ARTIFICIAL: The power values are artificial and might be * created by platform missing real power information */ -#define EM_PERF_DOMAIN_MILLIWATTS BIT(0) +#define EM_PERF_DOMAIN_MICROWATTS BIT(0) #define EM_PERF_DOMAIN_SKIP_INEFFICIENCIES BIT(1) #define EM_PERF_DOMAIN_ARTIFICIAL BIT(2)
@@ -79,22 +79,44 @@ struct em_perf_domain { #define em_is_artificial(em) ((em)->flags & EM_PERF_DOMAIN_ARTIFICIAL)
#ifdef CONFIG_ENERGY_MODEL -#define EM_MAX_POWER 0xFFFF +/* + * The max power value in micro-Watts. The limit of 64 Watts is set as + * a safety net to not overflow multiplications on 32bit platforms. The + * 32bit value limit for total Perf Domain power implies a limit of + * maximum CPUs in such domain to 64. + */ +#define EM_MAX_POWER (64000000) /* 64 Watts */ + +/* + * To avoid possible energy estimation overflow on 32bit machines add + * limits to number of CPUs in the Perf. Domain. + * We are safe on 64bit machine, thus some big number. + */ +#ifdef CONFIG_64BIT +#define EM_MAX_NUM_CPUS 4096 +#else +#define EM_MAX_NUM_CPUS 16 +#endif
/* - * Increase resolution of energy estimation calculations for 64-bit - * architectures. The extra resolution improves decision made by EAS for the - * task placement when two Performance Domains might provide similar energy - * estimation values (w/o better resolution the values could be equal). + * To avoid an overflow on 32bit machines while calculating the energy + * use a different order in the operation. First divide by the 'cpu_scale' + * which would reduce big value stored in the 'cost' field, then multiply by + * the 'sum_util'. This would allow to handle existing platforms, which have + * e.g. power ~1.3 Watt at max freq, so the 'cost' value > 1mln micro-Watts. + * In such scenario, where there are 4 CPUs in the Perf. Domain the 'sum_util' + * could be 4096, then multiplication: 'cost' * 'sum_util' would overflow. + * This reordering of operations has some limitations, we lose small + * precision in the estimation (comparing to 64bit platform w/o reordering). * - * We increase resolution only if we have enough bits to allow this increased - * resolution (i.e. 64-bit). The costs for increasing resolution when 32-bit - * are pretty high and the returns do not justify the increased costs. + * We are safe on 64bit machine. */ #ifdef CONFIG_64BIT -#define em_scale_power(p) ((p) * 1000) +#define em_estimate_energy(cost, sum_util, scale_cpu) \ + (((cost) * (sum_util)) / (scale_cpu)) #else -#define em_scale_power(p) (p) +#define em_estimate_energy(cost, sum_util, scale_cpu) \ + (((cost) / (scale_cpu)) * (sum_util)) #endif
struct em_data_callback { @@ -112,7 +134,7 @@ struct em_data_callback { * and frequency. * * In case of CPUs, the power is the one of a single CPU in the domain, - * expressed in milli-Watts or an abstract scale. It is expected to + * expressed in micro-Watts or an abstract scale. It is expected to * fit in the [0, EM_MAX_POWER] range. * * Return 0 on success. @@ -148,7 +170,7 @@ struct em_perf_domain *em_cpu_get(int cpu); struct em_perf_domain *em_pd_get(struct device *dev); int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, struct em_data_callback *cb, cpumask_t *span, - bool milliwatts); + bool microwatts); void em_dev_unregister_perf_domain(struct device *dev);
/** @@ -273,7 +295,7 @@ static inline unsigned long em_cpu_energy(struct em_perf_domain *pd, * pd_nrg = ------------------------ (4) * scale_cpu */ - return ps->cost * sum_util / scale_cpu; + return em_estimate_energy(ps->cost, sum_util, scale_cpu); }
/** @@ -297,7 +319,7 @@ struct em_data_callback {}; static inline int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, struct em_data_callback *cb, cpumask_t *span, - bool milliwatts) + bool microwatts) { return -EINVAL; } diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 6c373f2960e7..f82111837b8d 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -145,7 +145,7 @@ static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
/* * The power returned by active_state() is expected to be - * positive and to fit into 16 bits. + * positive and be in range. */ if (!power || power > EM_MAX_POWER) { dev_err(dev, "EM: invalid power: %lu\n", @@ -170,7 +170,7 @@ static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd, goto free_ps_table; } } else { - power_res = em_scale_power(table[i].power); + power_res = table[i].power; cost = div64_u64(fmax * power_res, table[i].frequency); }
@@ -201,9 +201,17 @@ static int em_create_pd(struct device *dev, int nr_states, { struct em_perf_domain *pd; struct device *cpu_dev; - int cpu, ret; + int cpu, ret, num_cpus;
if (_is_cpu_device(dev)) { + num_cpus = cpumask_weight(cpus); + + /* Prevent max possible energy calculation to not overflow */ + if (num_cpus > EM_MAX_NUM_CPUS) { + dev_err(dev, "EM: too many CPUs, overflow possible\n"); + return -EINVAL; + } + pd = kzalloc(sizeof(*pd) + cpumask_size(), GFP_KERNEL); if (!pd) return -ENOMEM; @@ -314,13 +322,13 @@ EXPORT_SYMBOL_GPL(em_cpu_get); * @cpus : Pointer to cpumask_t, which in case of a CPU device is * obligatory. It can be taken from i.e. 'policy->cpus'. For other * type of devices this should be set to NULL. - * @milliwatts : Flag indicating that the power values are in milliWatts or + * @microwatts : Flag indicating that the power values are in micro-Watts or * in some other scale. It must be set properly. * * Create Energy Model tables for a performance domain using the callbacks * defined in cb. * - * The @milliwatts is important to set with correct value. Some kernel + * The @microwatts is important to set with correct value. Some kernel * sub-systems might rely on this flag and check if all devices in the EM are * using the same scale. * @@ -331,7 +339,7 @@ EXPORT_SYMBOL_GPL(em_cpu_get); */ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, struct em_data_callback *cb, cpumask_t *cpus, - bool milliwatts) + bool microwatts) { unsigned long cap, prev_cap = 0; unsigned long flags = 0; @@ -381,8 +389,8 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, } }
- if (milliwatts) - flags |= EM_PERF_DOMAIN_MILLIWATTS; + if (microwatts) + flags |= EM_PERF_DOMAIN_MICROWATTS; else if (cb->get_cost) flags |= EM_PERF_DOMAIN_ARTIFICIAL;
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 03c440a26cba6cfa540d65924e9db86fcea362b2 ]
The Dell Inspiron N4010 does not have ACPI backlight control, so acpi_video_get_backlight_type()'s heuristics return vendor as the type to use.
But the vendor interface is broken, where as the native (intel_backlight) works well, add a quirk to use native.
Link: https://lore.kernel.org/regressions/CALF=6jEe5G8+r1Wo0vvz4GjNQQhdkLT5p8uCHn6... Reported-and-tested-by: Ben Greening bgreening@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/video_detect.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 6615f59ab7fd..5d7f38016a24 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -347,6 +347,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"), }, }, + { + .callback = video_detect_force_native, + /* Dell Inspiron N4010 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron N4010"), + }, + }, { .callback = video_detect_force_native, /* Dell Vostro V131 */
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 7d4edccc9bbfe1dcdff641343f7b0c6763fbe774 ]
Taking a lock at the beginning of .remove() doesn't prevent new readers. With the existing approach it can happen, that a read occurs just when the lock was taken blocking the reader until the lock is released at the end of the remove callback which then accessed *data that is already freed then.
To actually fix this problem the hwmon core needs some adaption. Until this is implemented take the optimistic approach of assuming that all readers are gone after hwmon_device_unregister() and sysfs_remove_group() as most other drivers do. (And once the core implements that, taking the lock would deadlock.)
So drop the lock, move the reset to after device unregistration to keep the device in a workable state until it's deregistered. Also add a error message in case the reset fails and return 0 anyhow. (Returning an error code, doesn't stop the platform device unregistration and only results in a little helpful error message before the devm cleanup handlers are called.)
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Link: https://lore.kernel.org/r/20220725194344.150098-1-u.kleine-koenig@pengutroni... Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/sht15.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 7f4a63959730..ae4d14257a11 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -1020,25 +1020,20 @@ static int sht15_probe(struct platform_device *pdev) static int sht15_remove(struct platform_device *pdev) { struct sht15_data *data = platform_get_drvdata(pdev); + int ret;
- /* - * Make sure any reads from the device are done and - * prevent new ones beginning - */ - mutex_lock(&data->read_lock); - if (sht15_soft_reset(data)) { - mutex_unlock(&data->read_lock); - return -EFAULT; - } hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group); + + ret = sht15_soft_reset(data); + if (ret) + dev_err(&pdev->dev, "Failed to reset device (%pe)\n", ERR_PTR(ret)); + if (!IS_ERR(data->reg)) { regulator_unregister_notifier(data->reg, &data->nb); regulator_disable(data->reg); }
- mutex_unlock(&data->read_lock); - return 0; }
Hello,
On Mon, Aug 15, 2022 at 07:52:27PM +0200, Greg Kroah-Hartman wrote:
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 7d4edccc9bbfe1dcdff641343f7b0c6763fbe774 ]
Taking a lock at the beginning of .remove() doesn't prevent new readers. With the existing approach it can happen, that a read occurs just when the lock was taken blocking the reader until the lock is released at the end of the remove callback which then accessed *data that is already freed then.
To actually fix this problem the hwmon core needs some adaption. Until this is implemented take the optimistic approach of assuming that all readers are gone after hwmon_device_unregister() and sysfs_remove_group() as most other drivers do. (And once the core implements that, taking the lock would deadlock.)
So drop the lock, move the reset to after device unregistration to keep the device in a workable state until it's deregistered. Also add a error message in case the reset fails and return 0 anyhow. (Returning an error code, doesn't stop the platform device unregistration and only results in a little helpful error message before the devm cleanup handlers are called.)
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Link: https://lore.kernel.org/r/20220725194344.150098-1-u.kleine-koenig@pengutroni... Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org
Does this mean my concerns I expressed in the mail with Message-Id: 20220814155638.idxnihylofsxqlql@pengutronix.de were not taken into consideration?
Best regards Uwe
On Mon, Aug 15, 2022 at 11:49:11PM +0200, Uwe Kleine-König wrote:
Hello,
On Mon, Aug 15, 2022 at 07:52:27PM +0200, Greg Kroah-Hartman wrote:
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 7d4edccc9bbfe1dcdff641343f7b0c6763fbe774 ]
Taking a lock at the beginning of .remove() doesn't prevent new readers. With the existing approach it can happen, that a read occurs just when the lock was taken blocking the reader until the lock is released at the end of the remove callback which then accessed *data that is already freed then.
To actually fix this problem the hwmon core needs some adaption. Until this is implemented take the optimistic approach of assuming that all readers are gone after hwmon_device_unregister() and sysfs_remove_group() as most other drivers do. (And once the core implements that, taking the lock would deadlock.)
So drop the lock, move the reset to after device unregistration to keep the device in a workable state until it's deregistered. Also add a error message in case the reset fails and return 0 anyhow. (Returning an error code, doesn't stop the platform device unregistration and only results in a little helpful error message before the devm cleanup handlers are called.)
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Link: https://lore.kernel.org/r/20220725194344.150098-1-u.kleine-koenig@pengutroni... Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org
Does this mean my concerns I expressed in the mail with Message-Id: 20220814155638.idxnihylofsxqlql@pengutronix.de were not taken into consideration?
I can't find that message-id on lore.kernel.org, do you have a link?
thanks,
greg k-h
Hello Greg,
On Tue, Aug 16, 2022 at 12:40:50PM +0200, Greg Kroah-Hartman wrote:
On Mon, Aug 15, 2022 at 11:49:11PM +0200, Uwe Kleine-König wrote:
On Mon, Aug 15, 2022 at 07:52:27PM +0200, Greg Kroah-Hartman wrote:
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 7d4edccc9bbfe1dcdff641343f7b0c6763fbe774 ]
Taking a lock at the beginning of .remove() doesn't prevent new readers. With the existing approach it can happen, that a read occurs just when the lock was taken blocking the reader until the lock is released at the end of the remove callback which then accessed *data that is already freed then.
To actually fix this problem the hwmon core needs some adaption. Until this is implemented take the optimistic approach of assuming that all readers are gone after hwmon_device_unregister() and sysfs_remove_group() as most other drivers do. (And once the core implements that, taking the lock would deadlock.)
So drop the lock, move the reset to after device unregistration to keep the device in a workable state until it's deregistered. Also add a error message in case the reset fails and return 0 anyhow. (Returning an error code, doesn't stop the platform device unregistration and only results in a little helpful error message before the devm cleanup handlers are called.)
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Link: https://lore.kernel.org/r/20220725194344.150098-1-u.kleine-koenig@pengutroni... Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org
Does this mean my concerns I expressed in the mail with Message-Id: 20220814155638.idxnihylofsxqlql@pengutronix.de were not taken into consideration?
I can't find that message-id on lore.kernel.org, do you have a link?
Oh, I missed your request earlier. No I don't have a link, the mail was sent to Sasha Levin, Jean Delvare, Guenter Roeck and stable-commits as I just replied to the "note to let you know that I've just added the patch titled [...] to the 5.19-stable tree".
I wrote:
I'd say adding this patch to stable isn't right. The problem existed since v3.0 (commit cc15c7ebb424e45ba2c5ceecbe52d025219ee970) and was never reported to be hit in practise. And given that the problem doesn't go away completely but (AFAICT) just opens the possibility for a hwmon core fix, I'd say it's not worth a backport.
Best regards Uwe
On Fri, Aug 19, 2022 at 09:35:01PM +0200, Uwe Kleine-König wrote:
Hello Greg,
On Tue, Aug 16, 2022 at 12:40:50PM +0200, Greg Kroah-Hartman wrote:
On Mon, Aug 15, 2022 at 11:49:11PM +0200, Uwe Kleine-König wrote:
On Mon, Aug 15, 2022 at 07:52:27PM +0200, Greg Kroah-Hartman wrote:
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 7d4edccc9bbfe1dcdff641343f7b0c6763fbe774 ]
Taking a lock at the beginning of .remove() doesn't prevent new readers. With the existing approach it can happen, that a read occurs just when the lock was taken blocking the reader until the lock is released at the end of the remove callback which then accessed *data that is already freed then.
To actually fix this problem the hwmon core needs some adaption. Until this is implemented take the optimistic approach of assuming that all readers are gone after hwmon_device_unregister() and sysfs_remove_group() as most other drivers do. (And once the core implements that, taking the lock would deadlock.)
So drop the lock, move the reset to after device unregistration to keep the device in a workable state until it's deregistered. Also add a error message in case the reset fails and return 0 anyhow. (Returning an error code, doesn't stop the platform device unregistration and only results in a little helpful error message before the devm cleanup handlers are called.)
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Link: https://lore.kernel.org/r/20220725194344.150098-1-u.kleine-koenig@pengutroni... Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org
Does this mean my concerns I expressed in the mail with Message-Id: 20220814155638.idxnihylofsxqlql@pengutronix.de were not taken into consideration?
I can't find that message-id on lore.kernel.org, do you have a link?
Oh, I missed your request earlier. No I don't have a link, the mail was sent to Sasha Levin, Jean Delvare, Guenter Roeck and stable-commits as I just replied to the "note to let you know that I've just added the patch titled [...] to the 5.19-stable tree".
Ok, I've dropped it now from all pending queues (5.10 and older), I can also revert it from the newer ones if you want me to.
thanks,
greg k-h
On Sat, Aug 20, 2022 at 08:14:42PM +0200, Greg Kroah-Hartman wrote:
On Fri, Aug 19, 2022 at 09:35:01PM +0200, Uwe Kleine-König wrote:
Hello Greg,
On Tue, Aug 16, 2022 at 12:40:50PM +0200, Greg Kroah-Hartman wrote:
On Mon, Aug 15, 2022 at 11:49:11PM +0200, Uwe Kleine-König wrote:
On Mon, Aug 15, 2022 at 07:52:27PM +0200, Greg Kroah-Hartman wrote:
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 7d4edccc9bbfe1dcdff641343f7b0c6763fbe774 ]
Taking a lock at the beginning of .remove() doesn't prevent new readers. With the existing approach it can happen, that a read occurs just when the lock was taken blocking the reader until the lock is released at the end of the remove callback which then accessed *data that is already freed then.
To actually fix this problem the hwmon core needs some adaption. Until this is implemented take the optimistic approach of assuming that all readers are gone after hwmon_device_unregister() and sysfs_remove_group() as most other drivers do. (And once the core implements that, taking the lock would deadlock.)
So drop the lock, move the reset to after device unregistration to keep the device in a workable state until it's deregistered. Also add a error message in case the reset fails and return 0 anyhow. (Returning an error code, doesn't stop the platform device unregistration and only results in a little helpful error message before the devm cleanup handlers are called.)
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Link: https://lore.kernel.org/r/20220725194344.150098-1-u.kleine-koenig@pengutroni... Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org
Does this mean my concerns I expressed in the mail with Message-Id: 20220814155638.idxnihylofsxqlql@pengutronix.de were not taken into consideration?
I can't find that message-id on lore.kernel.org, do you have a link?
Oh, I missed your request earlier. No I don't have a link, the mail was sent to Sasha Levin, Jean Delvare, Guenter Roeck and stable-commits as I just replied to the "note to let you know that I've just added the patch titled [...] to the 5.19-stable tree".
Ok, I've dropped it now from all pending queues (5.10 and older), I can also revert it from the newer ones if you want me to.
Actually I don't care much. It touches a path that is not usually hit, because platform devices are not removed very often. So I expect even if the problem with this driver is a different one now, we won't get any regressions here.
Best regards Uwe
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
[ Upstream commit 8386c414e27caba8501119948e9551e52b527f59 ]
syzbot is reporting hung task at misc_open() [1], for there is a race window of AB-BA deadlock which involves probe_count variable. Currently wait_for_device_probe() from snapshot_open() from misc_open() can sleep forever with misc_mtx held if probe_count cannot become 0.
When a device is probed by hub_event() work function, probe_count is incremented before the probe function starts, and probe_count is decremented after the probe function completed.
There are three cases that can prevent probe_count from dropping to 0.
(a) A device being probed stopped responding (i.e. broken/malicious hardware).
(b) A process emulating a USB device using /dev/raw-gadget interface stopped responding for some reason.
(c) New device probe requests keeps coming in before existing device probe requests complete.
The phenomenon syzbot is reporting is (b). A process which is holding system_transition_mutex and misc_mtx is waiting for probe_count to become 0 inside wait_for_device_probe(), but the probe function which is called from hub_event() work function is waiting for the processes which are blocked at mutex_lock(&misc_mtx) to respond via /dev/raw-gadget interface.
This patch mitigates (b) by deferring wait_for_device_probe() from snapshot_open() to snapshot_write() and snapshot_ioctl(). Please note that the possibility of (b) remains as long as any thread which is emulating a USB device via /dev/raw-gadget interface can be blocked by uninterruptible blocking operations (e.g. mutex_lock()).
Please also note that (a) and (c) are not addressed. Regarding (c), we should change the code to wait for only one device which contains the image for resuming from hibernation. I don't know how to address (a), for use of timeout for wait_for_device_probe() might result in loss of user data in the image. Maybe we should require the userland to wait for the image device before opening /dev/snapshot interface.
Link: https://syzkaller.appspot.com/bug?extid=358c9ab4c93da7b7238c [1] Reported-by: syzbot syzbot+358c9ab4c93da7b7238c@syzkaller.appspotmail.com Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Tested-by: syzbot syzbot+358c9ab4c93da7b7238c@syzkaller.appspotmail.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/power/user.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/kernel/power/user.c b/kernel/power/user.c index ad241b4ff64c..d43c2aa583b2 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -26,6 +26,7 @@
#include "power.h"
+static bool need_wait;
static struct snapshot_data { struct snapshot_handle handle; @@ -78,7 +79,7 @@ static int snapshot_open(struct inode *inode, struct file *filp) * Resuming. We may need to wait for the image device to * appear. */ - wait_for_device_probe(); + need_wait = true;
data->swap = -1; data->mode = O_WRONLY; @@ -168,6 +169,11 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, ssize_t res; loff_t pg_offp = *offp & ~PAGE_MASK;
+ if (need_wait) { + wait_for_device_probe(); + need_wait = false; + } + lock_system_sleep();
data = filp->private_data; @@ -244,6 +250,11 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, loff_t size; sector_t offset;
+ if (need_wait) { + wait_for_device_probe(); + need_wait = false; + } + if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR)
From: Xiu Jianfeng xiujianfeng@huawei.com
[ Upstream commit 73de1befcc53a7c68b0c5e76b9b5ac41c517760f ]
In this function, it directly returns the result of __security_read_policy without freeing the allocated memory in *data, cause memory leak issue, so free the memory if __security_read_policy failed.
Signed-off-by: Xiu Jianfeng xiujianfeng@huawei.com [PM: subject line tweak] Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/selinux/ss/services.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 69b2734311a6..fe5fcf571c56 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -4048,6 +4048,7 @@ int security_read_policy(struct selinux_state *state, int security_read_state_kernel(struct selinux_state *state, void **data, size_t *len) { + int err; struct selinux_policy *policy;
policy = rcu_dereference_protected( @@ -4060,5 +4061,11 @@ int security_read_state_kernel(struct selinux_state *state, if (!*data) return -ENOMEM;
- return __security_read_policy(policy, *data, len); + err = __security_read_policy(policy, *data, len); + if (err) { + vfree(*data); + *data = NULL; + *len = 0; + } + return err; }
From: Xiu Jianfeng xiujianfeng@huawei.com
[ Upstream commit 15ec76fb29be31df2bccb30fc09875274cba2776 ]
Just like next_entry(), boundary check is necessary to prevent memory out-of-bound access.
Signed-off-by: Xiu Jianfeng xiujianfeng@huawei.com Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/selinux/ss/policydb.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index c24d4e1063ea..ffc4e7bad205 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -370,6 +370,8 @@ static inline int put_entry(const void *buf, size_t bytes, int num, struct polic { size_t len = bytes * num;
+ if (len > fp->len) + return -EINVAL; memcpy(fp->data, buf, len); fp->data += len; fp->len -= len;
From: Dylan Yudaken dylany@fb.com
[ Upstream commit 9b26e811e934eebda59362c9a03d082852552574 ]
Make the trace format consistent with io_uring_complete for cflags
Signed-off-by: Dylan Yudaken dylany@fb.com Link: https://lore.kernel.org/r/20220630091231.1456789-12-dylany@fb.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- include/trace/events/io_uring.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/trace/events/io_uring.h b/include/trace/events/io_uring.h index aa2f951b07cd..6a12eef3ffb7 100644 --- a/include/trace/events/io_uring.h +++ b/include/trace/events/io_uring.h @@ -622,7 +622,7 @@ TRACE_EVENT(io_uring_cqe_overflow, __entry->ocqe = ocqe; ),
- TP_printk("ring %p, user_data 0x%llx, res %d, flags %x, " + TP_printk("ring %p, user_data 0x%llx, res %d, cflags 0x%x, " "overflow_cqe %p", __entry->ctx, __entry->user_data, __entry->res, __entry->cflags, __entry->ocqe)
From: Kees Cook keescook@chromium.org
[ Upstream commit aaf50b1969d7933a51ea421b11432a7fb90974e3 ]
GCC 12 continues to get smarter about array accesses. The KASAN tests are expecting to explicitly test out-of-bounds conditions at run-time, so hide the variable from GCC, to avoid warnings like:
../lib/test_kasan.c: In function 'ksize_uaf': ../lib/test_kasan.c:790:61: warning: array subscript 120 is outside array bounds of 'void[120]' [-Warray-bounds] 790 | KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[size]); | ~~~~~~~~~~~~~~~~~~~~~~^~~~~~ ../lib/test_kasan.c:97:9: note: in definition of macro 'KUNIT_EXPECT_KASAN_FAIL' 97 | expression; \ | ^~~~~~~~~~
Cc: Andrey Ryabinin ryabinin.a.a@gmail.com Cc: Alexander Potapenko glider@google.com Cc: Andrey Konovalov andreyknvl@gmail.com Cc: Dmitry Vyukov dvyukov@google.com Cc: Vincenzo Frascino vincenzo.frascino@arm.com Cc: kasan-dev@googlegroups.com Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20220608214024.1068451-1-keescook@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/test_kasan.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/lib/test_kasan.c b/lib/test_kasan.c index c233b1a4e984..58c1b01ccfe2 100644 --- a/lib/test_kasan.c +++ b/lib/test_kasan.c @@ -131,6 +131,7 @@ static void kmalloc_oob_right(struct kunit *test) ptr = kmalloc(size, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+ OPTIMIZER_HIDE_VAR(ptr); /* * An unaligned access past the requested kmalloc size. * Only generic KASAN can precisely detect these. @@ -159,6 +160,7 @@ static void kmalloc_oob_left(struct kunit *test) ptr = kmalloc(size, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+ OPTIMIZER_HIDE_VAR(ptr); KUNIT_EXPECT_KASAN_FAIL(test, *ptr = *(ptr - 1)); kfree(ptr); } @@ -171,6 +173,7 @@ static void kmalloc_node_oob_right(struct kunit *test) ptr = kmalloc_node(size, GFP_KERNEL, 0); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+ OPTIMIZER_HIDE_VAR(ptr); KUNIT_EXPECT_KASAN_FAIL(test, ptr[0] = ptr[size]); kfree(ptr); } @@ -191,6 +194,7 @@ static void kmalloc_pagealloc_oob_right(struct kunit *test) ptr = kmalloc(size, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+ OPTIMIZER_HIDE_VAR(ptr); KUNIT_EXPECT_KASAN_FAIL(test, ptr[size + OOB_TAG_OFF] = 0);
kfree(ptr); @@ -271,6 +275,7 @@ static void kmalloc_large_oob_right(struct kunit *test) ptr = kmalloc(size, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+ OPTIMIZER_HIDE_VAR(ptr); KUNIT_EXPECT_KASAN_FAIL(test, ptr[size] = 0); kfree(ptr); } @@ -410,6 +415,8 @@ static void kmalloc_oob_16(struct kunit *test) ptr2 = kmalloc(sizeof(*ptr2), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2);
+ OPTIMIZER_HIDE_VAR(ptr1); + OPTIMIZER_HIDE_VAR(ptr2); KUNIT_EXPECT_KASAN_FAIL(test, *ptr1 = *ptr2); kfree(ptr1); kfree(ptr2); @@ -756,6 +763,8 @@ static void ksize_unpoisons_memory(struct kunit *test) KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); real_size = ksize(ptr);
+ OPTIMIZER_HIDE_VAR(ptr); + /* This access shouldn't trigger a KASAN report. */ ptr[size] = 'x';
@@ -778,6 +787,7 @@ static void ksize_uaf(struct kunit *test) KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); kfree(ptr);
+ OPTIMIZER_HIDE_VAR(ptr); KUNIT_EXPECT_KASAN_FAIL(test, ksize(ptr)); KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[0]); KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[size]);
From: Juri Lelli juri.lelli@redhat.com
[ Upstream commit cceeeb6a6d02e7b9a74ddd27a3225013b34174aa ]
Changes to hrtimer mode (potentially made by __hrtimer_init_sleeper on PREEMPT_RT) are not visible to hrtimer_start_range_ns, thus not accounted for by hrtimer_start_expires call paths. In particular, __wait_event_hrtimeout suffers from this problem as we have, for example:
fs/aio.c::read_events wait_event_interruptible_hrtimeout __wait_event_hrtimeout hrtimer_init_sleeper_on_stack <- this might "mode |= HRTIMER_MODE_HARD" on RT if task runs at RT/DL priority hrtimer_start_range_ns WARN_ON_ONCE(!(mode & HRTIMER_MODE_HARD) ^ !timer->is_hard) fires since the latter doesn't see the change of mode done by init_sleeper
Fix it by making __wait_event_hrtimeout call hrtimer_sleeper_start_expires, which is aware of the special RT/DL case, instead of hrtimer_start_range_ns.
Reported-by: Bruno Goncalves bgoncalv@redhat.com Signed-off-by: Juri Lelli juri.lelli@redhat.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Daniel Bristot de Oliveira bristot@kernel.org Reviewed-by: Valentin Schneider vschneid@redhat.com Link: https://lore.kernel.org/r/20220627095051.42470-1-juri.lelli@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/wait.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/include/linux/wait.h b/include/linux/wait.h index 851e07da2583..58cfbf81447c 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -544,10 +544,11 @@ do { \ \ hrtimer_init_sleeper_on_stack(&__t, CLOCK_MONOTONIC, \ HRTIMER_MODE_REL); \ - if ((timeout) != KTIME_MAX) \ - hrtimer_start_range_ns(&__t.timer, timeout, \ - current->timer_slack_ns, \ - HRTIMER_MODE_REL); \ + if ((timeout) != KTIME_MAX) { \ + hrtimer_set_expires_range_ns(&__t.timer, timeout, \ + current->timer_slack_ns); \ + hrtimer_sleeper_start_expires(&__t, HRTIMER_MODE_REL); \ + } \ \ __ret = ___wait_event(wq_head, condition, state, 0, 0, \ if (!__t.task) { \
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit a2106f38077e78afcb4bf98fdda3e162118cfb3d ]
of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: 5e68c0fc8df8 ("soc: amlogic: Add Meson6/Meson8/Meson8b/Meson8m2 SoC Information driver") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://lore.kernel.org/r/20220524065729.33689-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/amlogic/meson-mx-socinfo.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/soc/amlogic/meson-mx-socinfo.c b/drivers/soc/amlogic/meson-mx-socinfo.c index 78f0f1aeca57..92125dd65f33 100644 --- a/drivers/soc/amlogic/meson-mx-socinfo.c +++ b/drivers/soc/amlogic/meson-mx-socinfo.c @@ -126,6 +126,7 @@ static int __init meson_mx_socinfo_init(void) np = of_find_matching_node(NULL, meson_mx_socinfo_analog_top_ids); if (np) { analog_top_regmap = syscon_node_to_regmap(np); + of_node_put(np); if (IS_ERR(analog_top_regmap)) return PTR_ERR(analog_top_regmap);
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 7512af9f78dedea7e04225f665dad6750df7d095 ]
Currently there are two nodes named "regulator_camera". This causes the former to be overwritten by the latter.
Fix this by renaming them to unique names, using the preferred hyphen instead of an underscore.
While at it, update the name of the audio regulator (which was added in the same commit) to use a hyphen.
Fixes: a1d8a344f1ca0709 ("arm64: dts: renesas: Introduce r8a774a1-beacon-rzg2m-kit") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/a9ac82bdf108162487289d091c53a9b3de393f13.165226391... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi index 142e7ffbd2bd..63e7a39e100e 100644 --- a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi +++ b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi @@ -146,7 +146,7 @@ rgb_panel: endpoint { }; };
- reg_audio: regulator_audio { + reg_audio: regulator-audio { compatible = "regulator-fixed"; regulator-name = "audio-1.8V"; regulator-min-microvolt = <1800000>; @@ -174,7 +174,7 @@ reg_lcd_reset: regulator-lcd-reset { vin-supply = <®_lcd>; };
- reg_cam0: regulator_camera { + reg_cam0: regulator-cam0 { compatible = "regulator-fixed"; regulator-name = "reg_cam0"; regulator-min-microvolt = <1800000>; @@ -183,7 +183,7 @@ reg_cam0: regulator_camera { enable-active-high; };
- reg_cam1: regulator_camera { + reg_cam1: regulator-cam1 { compatible = "regulator-fixed"; regulator-name = "reg_cam1"; regulator-min-microvolt = <1800000>;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 8e3ca32f46994e74b7f43c57731150b2aedb2630 ]
The spi_alloc_master() call is not undone in all error handling paths. Moreover, there is no .remove function to release the allocated memory.
In order to fix both this issues, switch to devm_spi_alloc_master().
This allows further simplification of the probe.
Fixes: ba2fc167e944 ("spi: altera: Add DFL bus driver for Altera API Controller") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/0607bb59f4073f86abe5c585d35245aef0b045c6.165380590... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-altera-dfl.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/spi/spi-altera-dfl.c b/drivers/spi/spi-altera-dfl.c index ca40923258af..596e181ae136 100644 --- a/drivers/spi/spi-altera-dfl.c +++ b/drivers/spi/spi-altera-dfl.c @@ -128,9 +128,9 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev) struct spi_master *master; struct altera_spi *hw; void __iomem *base; - int err = -ENODEV; + int err;
- master = spi_alloc_master(dev, sizeof(struct altera_spi)); + master = devm_spi_alloc_master(dev, sizeof(struct altera_spi)); if (!master) return -ENOMEM;
@@ -159,10 +159,9 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev) altera_spi_init_master(master);
err = devm_spi_register_master(dev, master); - if (err) { - dev_err(dev, "%s failed to register spi master %d\n", __func__, err); - goto exit; - } + if (err) + return dev_err_probe(dev, err, "%s failed to register spi master\n", + __func__);
if (dfl_dev->revision == FME_FEATURE_REV_MAX10_SPI_N5010) strscpy(board_info.modalias, "m10-n5010", SPI_NAME_SIZE); @@ -179,9 +178,6 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev) }
return 0; -exit: - spi_master_put(master); - return err; }
static const struct dfl_device_id dfl_spi_altera_ids[] = {
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit cb23389a2458c2e4bfd6c86a513cbbe1c4d35e76 ]
of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: b8eb35fd594a ("ARM: bcm281xx: Add L2 cache enable code") Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-bcm/bcm_kona_smc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c index 43829e49ad93..347bfb7f03e2 100644 --- a/arch/arm/mach-bcm/bcm_kona_smc.c +++ b/arch/arm/mach-bcm/bcm_kona_smc.c @@ -52,6 +52,7 @@ int __init bcm_kona_smc_init(void) return -ENODEV;
prop_val = of_get_address(node, 0, &prop_size, NULL); + of_node_put(node); if (!prop_val) return -EINVAL;
From: Guilherme G. Piccoli gpiccoli@igalia.com
[ Upstream commit 409dfdcaffb266acfc1f33529a26b1443c9332d4 ]
Commit 6727ad9e206c ("nmi_backtrace: generate one-line reports for idle cpus") introduced a new text section called cpuidle; with that, we have a mechanism to add idling functions in such section and skip them from nmi_backtrace output, since they're useless and potentially flooding for such report.
Happens that inlining might cause some real idle functions to end-up outside of such section; this is currently the case of ACPI processor_idle driver; the functions acpi_idle_enter_* do inline acpi_idle_do_entry(), hence they stay out of the cpuidle section. Fix that by marking such functions to also live in the cpuidle section.
Fixes: 6727ad9e206c ("nmi_backtrace: generate one-line reports for idle cpus") Signed-off-by: Guilherme G. Piccoli gpiccoli@igalia.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/processor_idle.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 6a5572a1a80c..13200969ccf3 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -607,7 +607,7 @@ static DEFINE_RAW_SPINLOCK(c3_lock); * @cx: Target state context * @index: index of target state */ -static int acpi_idle_enter_bm(struct cpuidle_driver *drv, +static int __cpuidle acpi_idle_enter_bm(struct cpuidle_driver *drv, struct acpi_processor *pr, struct acpi_processor_cx *cx, int index) @@ -664,7 +664,7 @@ static int acpi_idle_enter_bm(struct cpuidle_driver *drv, return index; }
-static int acpi_idle_enter(struct cpuidle_device *dev, +static int __cpuidle acpi_idle_enter(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); @@ -693,7 +693,7 @@ static int acpi_idle_enter(struct cpuidle_device *dev, return index; }
-static int acpi_idle_enter_s2idle(struct cpuidle_device *dev, +static int __cpuidle acpi_idle_enter_s2idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
From: Marcel Ziswiler marcel.ziswiler@toradex.com
[ Upstream commit ba28db60d34271e8a3cf4d7158d71607e8b1e57f ]
Each cpu-core is supposed to list its supply separately, add supply for cpu1.
Fixes: 2d7401f8632f ("ARM: dts: imx7d: Add cpu1 supply") Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx7d-colibri-emmc.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi index af39e5370fa1..045e4413d339 100644 --- a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi +++ b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi @@ -13,6 +13,10 @@ memory@80000000 { }; };
+&cpu1 { + cpu-supply = <®_DCDC2>; +}; + &gpio6 { gpio-line-names = "", "",
From: Marcel Ziswiler marcel.ziswiler@toradex.com
[ Upstream commit dbeb8e72cc51536a70313e6d523dcb1429b40477 ]
Rename display interface to match other modules to make it easier to use device tree overlays.
The parallel RGB interface (lcdif) and all related stuff turn on in a device tree overlay. Keep them disabled in the main devicetree. As these subsystems are provided by module and not a part of boards, move their definitions into the module-level devicetree.
Disable ad7879 touchscreen which turns on in a devic tree overlay. Remains it disabled in the main devicetree.
Move Atmel MXT capacitive touch controller device tree nodes from carrier board to module level and add iomux pinctl groups for both the Capacitive Touch Adapter (using SODIMM 28/30) and the capacitive touch connector as found on later carrier boards (using SODIMM 106/107).
Keep touchscreen and display nodes enabled for NAND based i.MX 7 modules, since device tree overlays are not yet supported. For the Colibri Evaluation Board keep the Capacitive Touch Adapter node disabled and PWM2, PWM3 enabled instead.
For eMMC based modules keep nodes disabled to work in conjunction with device tree overlays.
Add the iomuxc pinctrl group for the LVDS transceiver related signals to use it in a device tree overlay.
While at it also alphabetically re=order them properties.
Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx7-colibri-aster.dtsi | 53 ------------ arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi | 66 +++----------- arch/arm/boot/dts/imx7-colibri.dtsi | 95 ++++++++++++++++++--- arch/arm/boot/dts/imx7d-colibri-aster.dts | 20 +++++ arch/arm/boot/dts/imx7d-colibri-eval-v3.dts | 32 +++++++ arch/arm/boot/dts/imx7s-colibri-aster.dts | 20 +++++ arch/arm/boot/dts/imx7s-colibri-eval-v3.dts | 32 +++++++ 7 files changed, 197 insertions(+), 121 deletions(-)
diff --git a/arch/arm/boot/dts/imx7-colibri-aster.dtsi b/arch/arm/boot/dts/imx7-colibri-aster.dtsi index b770fc937970..950b4e5f6cf4 100644 --- a/arch/arm/boot/dts/imx7-colibri-aster.dtsi +++ b/arch/arm/boot/dts/imx7-colibri-aster.dtsi @@ -4,10 +4,6 @@ * */
- -#include <dt-bindings/input/input.h> -#include <dt-bindings/pwm/pwm.h> - / { chosen { stdout-path = "serial0:115200n8"; @@ -27,18 +23,6 @@ power { }; };
- panel: panel { - compatible = "edt,et057090dhu"; - backlight = <&bl>; - power-supply = <®_3v3>; - - port { - panel_in: endpoint { - remote-endpoint = <&lcdif_out>; - }; - }; - }; - reg_3v3: regulator-3v3 { compatible = "regulator-fixed"; regulator-name = "3.3V"; @@ -77,13 +61,6 @@ &adc2 { status = "disabled"; };
-&bl { - brightness-levels = <0 4 8 16 32 64 128 255>; - default-brightness-level = <6>; - power-supply = <®_3v3>; - status = "okay"; -}; - &fec1 { status = "okay"; }; @@ -91,17 +68,6 @@ &fec1 { &i2c4 { status = "okay";
- /* Microchip/Atmel maxtouch controller */ - touchscreen@4a { - compatible = "atmel,maxtouch"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpiotouch>; - reg = <0x4a>; - interrupt-parent = <&gpio2>; - interrupts = <15 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 107 */ - reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; /* SODIMM 106 */ - }; - /* M41T0M6 real time clock on carrier board */ rtc: rtc@68 { compatible = "st,m41t0"; @@ -109,25 +75,6 @@ rtc: rtc@68 { }; };
-&iomuxc { - pinctrl_gpiotouch: touchgpios { - fsl,pins = < - MX7D_PAD_EPDC_DATA15__GPIO2_IO15 0x74 - MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x14 - >; - }; -}; - -&lcdif { - status = "okay"; - - port { - lcdif_out: endpoint { - remote-endpoint = <&panel_in>; - }; - }; -}; - &pwm1 { status = "okay"; }; diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi index 3b9df8c82ae3..d6fa74222960 100644 --- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi @@ -34,18 +34,6 @@ power { }; };
- panel: panel { - compatible = "edt,et057090dhu"; - backlight = <&bl>; - power-supply = <®_3v3>; - - port { - panel_in: endpoint { - remote-endpoint = <&lcdif_out>; - }; - }; - }; - reg_3v3: regulator-3v3 { compatible = "regulator-fixed"; regulator-name = "3.3V"; @@ -72,14 +60,6 @@ reg_usbh_vbus: regulator-usbh-vbus { }; };
-&bl { - brightness-levels = <0 4 8 16 32 64 128 255>; - default-brightness-level = <6>; - power-supply = <®_3v3>; - - status = "okay"; -}; - &adc1 { status = "okay"; }; @@ -88,6 +68,18 @@ &adc2 { status = "okay"; };
+/* + * The Atmel maxtouch controller uses SODIMM 28/30, also used for PWM<B>, PWM<C>, aka pwm2, pwm3. + * So if you enable following capacitive touch controller, disable pwm2/pwm3 first. + */ +&atmel_mxt_ts { + interrupt-parent = <&gpio1>; + interrupts = <9 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 28 / INT */ + pinctrl-0 = <&pinctrl_atmel_adapter>; + reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; /* SODIMM 30 / RST */ + status = "disabled"; +}; + &ecspi3 { status = "okay";
@@ -113,21 +105,6 @@ &fec1 { &i2c4 { status = "okay";
- /* - * Touchscreen is using SODIMM 28/30, also used for PWM<B>, PWM<C>, - * aka pwm2, pwm3. so if you enable touchscreen, disable the pwms - */ - touchscreen@4a { - compatible = "atmel,maxtouch"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpiotouch>; - reg = <0x4a>; - interrupt-parent = <&gpio1>; - interrupts = <9 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 28 */ - reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; /* SODIMM 30 */ - status = "disabled"; - }; - /* M41T0M6 real time clock on carrier board */ rtc: rtc@68 { compatible = "st,m41t0"; @@ -135,16 +112,6 @@ rtc: rtc@68 { }; };
-&lcdif { - status = "okay"; - - port { - lcdif_out: endpoint { - remote-endpoint = <&panel_in>; - }; - }; -}; - &pwm1 { status = "okay"; }; @@ -183,12 +150,3 @@ &usdhc1 { vmmc-supply = <®_3v3>; status = "okay"; }; - -&iomuxc { - pinctrl_gpiotouch: touchgpios { - fsl,pins = < - MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x74 - MX7D_PAD_GPIO1_IO10__GPIO1_IO10 0x14 - >; - }; -}; diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi index f1c60b0cb143..e20b0977f38f 100644 --- a/arch/arm/boot/dts/imx7-colibri.dtsi +++ b/arch/arm/boot/dts/imx7-colibri.dtsi @@ -3,13 +3,32 @@ * Copyright 2016-2020 Toradex */
+#include <dt-bindings/pwm/pwm.h> + / { - bl: backlight { + backlight: backlight { + brightness-levels = <0 45 63 88 119 158 203 255>; compatible = "pwm-backlight"; + default-brightness-level = <4>; + enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio_bl_on>; - pwms = <&pwm1 0 5000000 0>; - enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; + power-supply = <®_module_3v3>; + pwms = <&pwm1 0 6666667 PWM_POLARITY_INVERTED>; + status = "disabled"; + }; + + panel_dpi: panel-dpi { + backlight = <&backlight>; + compatible = "edt,et057090dhu"; + power-supply = <®_3v3>; + status = "disabled"; + + port { + lcd_panel_in: endpoint { + remote-endpoint = <&lcdif_out>; + }; + }; };
reg_module_3v3: regulator-module-3v3 { @@ -301,18 +320,19 @@ codec: sgtl5000@a { VDDD-supply = <®_DCDC3>; };
- ad7879@2c { + ad7879_ts: touchscreen@2c { + adi,acquisition-time = /bits/ 8 <1>; + adi,averaging = /bits/ 8 <1>; + adi,conversion-interval = /bits/ 8 <255>; + adi,first-conversion-delay = /bits/ 8 <3>; + adi,median-filter-size = /bits/ 8 <2>; + adi,resistance-plate-x = <120>; compatible = "adi,ad7879-1"; - reg = <0x2c>; interrupt-parent = <&gpio1>; interrupts = <13 IRQ_TYPE_EDGE_FALLING>; + reg = <0x2c>; touchscreen-max-pressure = <4096>; - adi,resistance-plate-x = <120>; - adi,first-conversion-delay = /bits/ 8 <3>; - adi,acquisition-time = /bits/ 8 <1>; - adi,median-filter-size = /bits/ 8 <2>; - adi,averaging = /bits/ 8 <1>; - adi,conversion-interval = /bits/ 8 <255>; + status = "disabled"; };
pmic@33 { @@ -392,12 +412,32 @@ &i2c4 { pinctrl-1 = <&pinctrl_i2c4_recovery>; scl-gpios = <&gpio7 8 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; sda-gpios = <&gpio7 9 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + status = "disabled"; + + /* Atmel maxtouch controller */ + atmel_mxt_ts: touchscreen@4a { + compatible = "atmel,maxtouch"; + interrupt-parent = <&gpio2>; + interrupts = <15 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 107 / INT */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_atmel_connector>; + reg = <0x4a>; + reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; /* SODIMM 106 / RST */ + status = "disabled"; + }; };
&lcdif { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcdif_dat &pinctrl_lcdif_ctrl>; + status = "disabled"; + + port { + lcdif_out: endpoint { + remote-endpoint = <&lcd_panel_in>; + }; + }; };
&pwm1 { @@ -486,7 +526,27 @@ &usdhc3 { &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4 - &pinctrl_gpio7 &pinctrl_usbc_det>; + &pinctrl_usbc_det>; + + /* + * Atmel MXT touchsceen + Capacitive Touch Adapter + * NOTE: This pin group conflicts with pin groups pinctrl_pwm2/pinctrl_pwm3. + * Don't use them simultaneously. + */ + pinctrl_atmel_adapter: atmelconnectorgrp { + fsl,pins = < + MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x74 /* SODIMM 28 / INT */ + MX7D_PAD_GPIO1_IO10__GPIO1_IO10 0x14 /* SODIMM 30 / RST */ + >; + }; + + /* Atmel MXT touchsceen + boards with built-in Capacitive Touch Connector */ + pinctrl_atmel_connector: atmeladaptergrp { + fsl,pins = < + MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x14 /* SODIMM 106 / RST */ + MX7D_PAD_EPDC_DATA15__GPIO2_IO15 0x74 /* SODIMM 107 / INT */ + >; + };
pinctrl_gpio1: gpio1-grp { fsl,pins = < @@ -494,8 +554,6 @@ MX7D_PAD_SAI1_RX_SYNC__GPIO6_IO16 0x14 /* SODIMM 77 */ MX7D_PAD_EPDC_DATA09__GPIO2_IO9 0x14 /* SODIMM 89 */ MX7D_PAD_EPDC_DATA08__GPIO2_IO8 0x74 /* SODIMM 91 */ MX7D_PAD_LCD_RESET__GPIO3_IO4 0x14 /* SODIMM 93 */ - MX7D_PAD_EPDC_DATA13__GPIO2_IO13 0x14 /* SODIMM 95 */ - MX7D_PAD_ENET1_RGMII_TXC__GPIO7_IO11 0x14 /* SODIMM 99 */ MX7D_PAD_EPDC_DATA10__GPIO2_IO10 0x74 /* SODIMM 105 */ MX7D_PAD_EPDC_DATA00__GPIO2_IO0 0x14 /* SODIMM 111 */ MX7D_PAD_EPDC_DATA01__GPIO2_IO1 0x14 /* SODIMM 113 */ @@ -729,6 +787,15 @@ MX7D_PAD_LCD_HSYNC__LCD_HSYNC 0x79 >; };
+ pinctrl_lvds_transceiver: lvdstx { + fsl,pins = < + MX7D_PAD_ENET1_RGMII_RD2__GPIO7_IO2 0x14 /* SODIMM 63 */ + MX7D_PAD_ENET1_RGMII_RD3__GPIO7_IO3 0x74 /* SODIMM 55 */ + MX7D_PAD_ENET1_RGMII_TXC__GPIO7_IO11 0x14 /* SODIMM 99 */ + MX7D_PAD_EPDC_DATA13__GPIO2_IO13 0x14 /* SODIMM 95 */ + >; + }; + pinctrl_pwm1: pwm1-grp { fsl,pins = < MX7D_PAD_GPIO1_IO08__PWM1_OUT 0x79 diff --git a/arch/arm/boot/dts/imx7d-colibri-aster.dts b/arch/arm/boot/dts/imx7d-colibri-aster.dts index f3f0537d5a37..ce0e6bb7db37 100644 --- a/arch/arm/boot/dts/imx7d-colibri-aster.dts +++ b/arch/arm/boot/dts/imx7d-colibri-aster.dts @@ -14,6 +14,26 @@ / { "fsl,imx7d"; };
+&ad7879_ts { + status = "okay"; +}; + +&atmel_mxt_ts { + status = "okay"; +}; + +&backlight { + status = "okay"; +}; + +&lcdif { + status = "okay"; +}; + +&panel_dpi { + status = "okay"; +}; + &usbotg2 { vbus-supply = <®_usbh_vbus>; status = "okay"; diff --git a/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts b/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts index 87b132bcd272..c610c50c003a 100644 --- a/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts +++ b/arch/arm/boot/dts/imx7d-colibri-eval-v3.dts @@ -13,6 +13,38 @@ / { "fsl,imx7d"; };
+&ad7879_ts { + status = "okay"; +}; + +/* + * The Atmel maxtouch controller uses SODIMM 28/30, also used for PWM<B>, PWM<C>, aka pwm2, pwm3. + * So if you enable following capacitive touch controller, disable pwm2/pwm3 first. + */ +&atmel_mxt_ts { + status = "disabled"; +}; + +&backlight { + status = "okay"; +}; + +&lcdif { + status = "okay"; +}; + +&panel_dpi { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; + &usbotg2 { vbus-supply = <®_usbh_vbus>; status = "okay"; diff --git a/arch/arm/boot/dts/imx7s-colibri-aster.dts b/arch/arm/boot/dts/imx7s-colibri-aster.dts index fca4e0a95c1b..87f9e0e079a8 100644 --- a/arch/arm/boot/dts/imx7s-colibri-aster.dts +++ b/arch/arm/boot/dts/imx7s-colibri-aster.dts @@ -13,3 +13,23 @@ / { compatible = "toradex,colibri-imx7s-aster", "toradex,colibri-imx7s", "fsl,imx7s"; }; + +&ad7879_ts { + status = "okay"; +}; + +&atmel_mxt_ts { + status = "okay"; +}; + +&backlight { + status = "okay"; +}; + +&lcdif { + status = "okay"; +}; + +&panel_dpi { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts b/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts index aa70d3f2e2e2..81956c16b95b 100644 --- a/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts +++ b/arch/arm/boot/dts/imx7s-colibri-eval-v3.dts @@ -12,3 +12,35 @@ / { compatible = "toradex,colibri-imx7s-eval-v3", "toradex,colibri-imx7s", "fsl,imx7s"; }; + +&ad7879_ts { + status = "okay"; +}; + +/* + * The Atmel maxtouch controller uses SODIMM 28/30, also used for PWM<B>, PWM<C>, aka pwm2, pwm3. + * So if you enable following capacitive touch controller, disable pwm2/pwm3 first. + */ +&atmel_mxt_ts { + status = "disabled"; +}; + +&backlight { + status = "okay"; +}; + +&lcdif { + status = "okay"; +}; + +&panel_dpi { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; +};
From: Philippe Schenker philippe.schenker@toradex.com
[ Upstream commit 136f88458d829987548b3321e7122e05acd78dd9 ]
Add USB dual-role switching using extcon.
Signed-off-by: Philippe Schenker philippe.schenker@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi | 8 ++++++++ arch/arm/boot/dts/imx7-colibri.dtsi | 5 ++--- 2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi index d6fa74222960..17ad9065646d 100644 --- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi @@ -20,6 +20,13 @@ clk16m: clk16m { clock-frequency = <16000000>; };
+ extcon_usbc_det: usbc-det { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbc_det>; + }; + gpio-keys { compatible = "gpio-keys"; pinctrl-names = "default"; @@ -141,6 +148,7 @@ &uart3 { };
&usbotg1 { + extcon = <0>, <&extcon_usbc_det>; status = "okay"; };
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi index e20b0977f38f..4146564c3e4b 100644 --- a/arch/arm/boot/dts/imx7-colibri.dtsi +++ b/arch/arm/boot/dts/imx7-colibri.dtsi @@ -497,7 +497,7 @@ &uart3 { };
&usbotg1 { - dr_mode = "host"; + dr_mode = "otg"; };
&usdhc1 { @@ -525,8 +525,7 @@ &usdhc3 {
&iomuxc { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4 - &pinctrl_usbc_det>; + pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4>;
/* * Atmel MXT touchsceen + Capacitive Touch Adapter
From: Oleksandr Suvorov oleksandr.suvorov@toradex.com
[ Upstream commit fd5d2974652c96935d94301af6eaf6b3585ab330 ]
The pin GPIO1_IO01 externally pulls down, it is required to sequentially connect this pin (signal WAKE_MICO#) to +3v3 and then disconnect it to trigger a wakeup interrupt. Adding the flag GPIO_PULL_DOWN allows the system to be woken up just connecting the pin GPIO1_IO01 to +3v3.
Signed-off-by: Oleksandr Suvorov oleksandr.suvorov@toradex.com Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx7-colibri-aster.dtsi | 2 +- arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx7-colibri-aster.dtsi b/arch/arm/boot/dts/imx7-colibri-aster.dtsi index 950b4e5f6cf4..69ee85084ad4 100644 --- a/arch/arm/boot/dts/imx7-colibri-aster.dtsi +++ b/arch/arm/boot/dts/imx7-colibri-aster.dtsi @@ -16,7 +16,7 @@ gpio-keys {
power { label = "Wake-Up"; - gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; linux,code = <KEY_WAKEUP>; debounce-interval = <10>; wakeup-source; diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi index 17ad9065646d..d6775e3c64f1 100644 --- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi @@ -34,7 +34,7 @@ gpio-keys {
power { label = "Wake-Up"; - gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; linux,code = <KEY_WAKEUP>; debounce-interval = <10>; wakeup-source;
From: Marcel Ziswiler marcel.ziswiler@toradex.com
[ Upstream commit 0ef1969ea5699b00394e1a8c8c7f927b2d0bc5bb ]
Move aliases, chosen, extcon and gpio-keys to module-level device tree given they are standard Colibri functionalities.
Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx7-colibri-aster.dtsi | 18 ------------ arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi | 31 -------------------- arch/arm/boot/dts/imx7-colibri.dtsi | 32 +++++++++++++++++++++ 3 files changed, 32 insertions(+), 49 deletions(-)
diff --git a/arch/arm/boot/dts/imx7-colibri-aster.dtsi b/arch/arm/boot/dts/imx7-colibri-aster.dtsi index 69ee85084ad4..02c49ed686a8 100644 --- a/arch/arm/boot/dts/imx7-colibri-aster.dtsi +++ b/arch/arm/boot/dts/imx7-colibri-aster.dtsi @@ -5,24 +5,6 @@ */
/ { - chosen { - stdout-path = "serial0:115200n8"; - }; - - gpio-keys { - compatible = "gpio-keys"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpiokeys>; - - power { - label = "Wake-Up"; - gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; - linux,code = <KEY_WAKEUP>; - debounce-interval = <10>; - wakeup-source; - }; - }; - reg_3v3: regulator-3v3 { compatible = "regulator-fixed"; regulator-name = "3.3V"; diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi index d6775e3c64f1..4cf4107fb642 100644 --- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi @@ -4,15 +4,6 @@ */
/ { - aliases { - rtc0 = &rtc; - rtc1 = &snvs_rtc; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - /* fixed crystal dedicated to mpc258x */ clk16m: clk16m { compatible = "fixed-clock"; @@ -20,27 +11,6 @@ clk16m: clk16m { clock-frequency = <16000000>; };
- extcon_usbc_det: usbc-det { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usbc_det>; - }; - - gpio-keys { - compatible = "gpio-keys"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpiokeys>; - - power { - label = "Wake-Up"; - gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; - linux,code = <KEY_WAKEUP>; - debounce-interval = <10>; - wakeup-source; - }; - }; - reg_3v3: regulator-3v3 { compatible = "regulator-fixed"; regulator-name = "3.3V"; @@ -148,7 +118,6 @@ &uart3 { };
&usbotg1 { - extcon = <0>, <&extcon_usbc_det>; status = "okay"; };
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi index 4146564c3e4b..79f041988c7b 100644 --- a/arch/arm/boot/dts/imx7-colibri.dtsi +++ b/arch/arm/boot/dts/imx7-colibri.dtsi @@ -6,6 +6,11 @@ #include <dt-bindings/pwm/pwm.h>
/ { + aliases { + rtc0 = &rtc; + rtc1 = &snvs_rtc; + }; + backlight: backlight { brightness-levels = <0 45 63 88 119 158 203 255>; compatible = "pwm-backlight"; @@ -18,6 +23,32 @@ backlight: backlight { status = "disabled"; };
+ chosen { + stdout-path = "serial0:115200n8"; + }; + + extcon_usbc_det: usbc-det { + compatible = "linux,extcon-usb-gpio"; + debounce = <25>; + id-gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>; /* SODIMM 137 / USBC_DET */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbc_det>; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpiokeys>; + + wakeup { + debounce-interval = <10>; + gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; /* SODIMM 45 */ + label = "Wake-Up"; + linux,code = <KEY_WAKEUP>; + wakeup-source; + }; + }; + panel_dpi: panel-dpi { backlight = <&backlight>; compatible = "edt,et057090dhu"; @@ -498,6 +529,7 @@ &uart3 {
&usbotg1 { dr_mode = "otg"; + extcon = <0>, <&extcon_usbc_det>; };
&usdhc1 {
From: Marcel Ziswiler marcel.ziswiler@toradex.com
[ Upstream commit 32f054fef145878c5331f9dd343014970a15ebfa ]
Correct CAN controller comment. It is a MCP2515 rather than a mpc258x.
Fixes: 66d59b678a87 ("ARM: dts: imx7-colibri: add MCP2515 CAN controller") Signed-off-by: Marcel Ziswiler marcel.ziswiler@toradex.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi index 4cf4107fb642..b5f632921df2 100644 --- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi @@ -4,7 +4,7 @@ */
/ { - /* fixed crystal dedicated to mpc258x */ + /* Fixed crystal dedicated to MCP2515. */ clk16m: clk16m { compatible = "fixed-clock"; #clock-cells = <0>;
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit bccceabb92ce8eb78bbf2de08308e2cc2761a2e5 ]
The PDR values for the A2DP1 and A2CV[2357] power areas on R-Car V3U are incorrect (copied-and-pasted from A2DP0 and A2CV[0146]). Fix them.
Reported-by: Renesas Vietnam via Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Fixes: 1b4298f000064cc2 ("soc: renesas: r8a779a0-sysc: Add r8a779a0 support") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/87bc2e70ba4082970cf8c65871beae4be3503189.165469618... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/renesas/r8a779a0-sysc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/soc/renesas/r8a779a0-sysc.c b/drivers/soc/renesas/r8a779a0-sysc.c index fdfc857df334..04f1bc322ae7 100644 --- a/drivers/soc/renesas/r8a779a0-sysc.c +++ b/drivers/soc/renesas/r8a779a0-sysc.c @@ -57,11 +57,11 @@ static struct rcar_gen4_sysc_area r8a779a0_areas[] __initdata = { { "a2cv6", R8A779A0_PD_A2CV6, R8A779A0_PD_A3IR }, { "a2cn2", R8A779A0_PD_A2CN2, R8A779A0_PD_A3IR }, { "a2imp23", R8A779A0_PD_A2IMP23, R8A779A0_PD_A3IR }, - { "a2dp1", R8A779A0_PD_A2DP0, R8A779A0_PD_A3IR }, - { "a2cv2", R8A779A0_PD_A2CV0, R8A779A0_PD_A3IR }, - { "a2cv3", R8A779A0_PD_A2CV1, R8A779A0_PD_A3IR }, - { "a2cv5", R8A779A0_PD_A2CV4, R8A779A0_PD_A3IR }, - { "a2cv7", R8A779A0_PD_A2CV6, R8A779A0_PD_A3IR }, + { "a2dp1", R8A779A0_PD_A2DP1, R8A779A0_PD_A3IR }, + { "a2cv2", R8A779A0_PD_A2CV2, R8A779A0_PD_A3IR }, + { "a2cv3", R8A779A0_PD_A2CV3, R8A779A0_PD_A3IR }, + { "a2cv5", R8A779A0_PD_A2CV5, R8A779A0_PD_A3IR }, + { "a2cv7", R8A779A0_PD_A2CV7, R8A779A0_PD_A3IR }, { "a2cn1", R8A779A0_PD_A2CN1, R8A779A0_PD_A3IR }, { "a1cnn0", R8A779A0_PD_A1CNN0, R8A779A0_PD_A2CN0 }, { "a1cnn2", R8A779A0_PD_A1CNN2, R8A779A0_PD_A2CN2 },
From: Liang He windhl@126.com
[ Upstream commit d18529a4c12f66d83daac78045ea54063bd43257 ]
In meson_secure_pwrc_probe(), there is a refcount leak in one fail path.
Signed-off-by: Liang He windhl@126.com Acked-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Fixes: b3dde5013e13 ("soc: amlogic: Add support for Secure power domains controller") Reviewed-by: Neil Armstrong narmstrong@baylibre.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://lore.kernel.org/r/20220616144915.3988071-1-windhl@126.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/amlogic/meson-secure-pwrc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/amlogic/meson-secure-pwrc.c b/drivers/soc/amlogic/meson-secure-pwrc.c index a10a417a87db..e93518763526 100644 --- a/drivers/soc/amlogic/meson-secure-pwrc.c +++ b/drivers/soc/amlogic/meson-secure-pwrc.c @@ -152,8 +152,10 @@ static int meson_secure_pwrc_probe(struct platform_device *pdev) }
pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL); - if (!pwrc) + if (!pwrc) { + of_node_put(sm_np); return -ENOMEM; + }
pwrc->fw = meson_sm_get(sm_np); of_node_put(sm_np);
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 62e8a53431145e06e503b71625a34eaa87b72b2c ]
"make dtbs_check":
arch/arm64/boot/dts/renesas/r8a774c0-cat874.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[74], [0]] is too long arch/arm64/boot/dts/renesas/r8a774c0-ek874.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[79], [0]] is too long arch/arm64/boot/dts/renesas/r8a774c0-ek874-idk-2121wr.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[82], [0]] is too long arch/arm64/boot/dts/renesas/r8a774c0-ek874-mipi-2.1.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[87], [0]] is too long arch/arm64/boot/dts/renesas/r8a77990-ebisu.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[105], [0]] is too long From schema: Documentation/devicetree/bindings/thermal/thermal-zones.yaml
Indeed, the thermal sensors on R-Car E3 and RZ/G2E support only a single zone, hence #thermal-sensor-cells = <0>.
Fix this by dropping the bogus zero cell from the thermal sensor specifiers.
Fixes: 8fa7d18f9ee2dc20 ("arm64: dts: renesas: r8a77990: Create thermal zone to support IPA") Fixes: 8438bfda9d768157 ("arm64: dts: renesas: r8a774c0: Create thermal zone to support IPA") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se Link: https://lore.kernel.org/r/28b812fdd1fc3698311fac984ab8b91d3d655c1c.165530168... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/renesas/r8a774c0.dtsi | 2 +- arch/arm64/boot/dts/renesas/r8a77990.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi index b6aeb22e8836..86e8c9b5147a 100644 --- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi @@ -1952,7 +1952,7 @@ thermal-zones { cpu-thermal { polling-delay-passive = <250>; polling-delay = <0>; - thermal-sensors = <&thermal 0>; + thermal-sensors = <&thermal>; sustainable-power = <717>;
cooling-maps { diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index d33021202637..800274de1fe0 100644 --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi @@ -2129,7 +2129,7 @@ thermal-zones { cpu-thermal { polling-delay-passive = <250>; polling-delay = <0>; - thermal-sensors = <&thermal 0>; + thermal-sensors = <&thermal>; sustainable-power = <717>;
cooling-maps {
From: Max Krummenacher max.krummenacher@toradex.com
[ Upstream commit 9c0919acb3fa7c1a24e384ff912f2d88f060c373 ]
The STMPE MFD device binding requires the child node to have a fixed name, i.e. with '_', not '-'. Otherwise the stmpe_adc, stmpe_touchscreen drivers will not be probed.
Fixes: 56086b5e804f ("ARM: dts: imx6qdl-apalis: Avoid underscore in node name") Reviewed-by: Ahmad Fatoum a.fatoum@pengutronix.de Signed-off-by: Max Krummenacher max.krummenacher@toradex.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx6qdl-apalis.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi index bd763bae596b..da919d0544a8 100644 --- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi +++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi @@ -315,7 +315,7 @@ stmpe811@41 { /* ADC conversion time: 80 clocks */ st,sample-time = <4>;
- stmpe_touchscreen: stmpe-touchscreen { + stmpe_touchscreen: stmpe_touchscreen { compatible = "st,stmpe-ts"; /* 8 sample average control */ st,ave-ctrl = <3>; @@ -332,7 +332,7 @@ stmpe_touchscreen: stmpe-touchscreen { st,touch-det-delay = <5>; };
- stmpe_adc: stmpe-adc { + stmpe_adc: stmpe_adc { compatible = "st,stmpe-adc"; /* forbid to use ADC channels 3-0 (touch) */ st,norequest-mask = <0x0F>;
From: Johan Hovold johan@kernel.org
[ Upstream commit 229e73d46994f15314f58b2d39bf952111d89193 ]
Make sure to free the platform device in the unlikely event that registration fails.
Fixes: 7a67832c7e44 ("libnvdimm, e820: make CONFIG_X86_PMEM_LEGACY a tristate option") Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Borislav Petkov bp@suse.de Link: https://lore.kernel.org/r/20220620140723.9810-1-johan@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/pmem.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/pmem.c b/arch/x86/kernel/pmem.c index 6b07faaa1579..23154d24b117 100644 --- a/arch/x86/kernel/pmem.c +++ b/arch/x86/kernel/pmem.c @@ -27,6 +27,11 @@ static __init int register_e820_pmem(void) * simply here to trigger the module to load on demand. */ pdev = platform_device_alloc("e820_pmem", -1); - return platform_device_add(pdev); + + rc = platform_device_add(pdev); + if (rc) + platform_device_put(pdev); + + return rc; } device_initcall(register_e820_pmem);
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 30b276fca5c0644f3cb17bceb1bd6a626c670184 ]
The AST2500 EVB board should have dedicated compatible.
Fixes: 02440622656d ("arm/dst: Add Aspeed ast2500 device tree") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220529104928.79636-4-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/aspeed-ast2500-evb.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/aspeed-ast2500-evb.dts b/arch/arm/boot/dts/aspeed-ast2500-evb.dts index 1d24b394ea4c..a497dd135491 100644 --- a/arch/arm/boot/dts/aspeed-ast2500-evb.dts +++ b/arch/arm/boot/dts/aspeed-ast2500-evb.dts @@ -5,7 +5,7 @@
/ { model = "AST2500 EVB"; - compatible = "aspeed,ast2500"; + compatible = "aspeed,ast2500-evb", "aspeed,ast2500";
aliases { serial4 = &uart5;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit aa5e06208500a0db41473caebdee5a2e81d5a277 ]
The AST2600 EVB board should have dedicated compatible.
Fixes: 2ca5646b5c2f ("ARM: dts: aspeed: Add AST2600 and EVB") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220529104928.79636-5-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/aspeed-ast2600-evb.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/aspeed-ast2600-evb.dts b/arch/arm/boot/dts/aspeed-ast2600-evb.dts index 5a6063bd4508..c698e6538269 100644 --- a/arch/arm/boot/dts/aspeed-ast2600-evb.dts +++ b/arch/arm/boot/dts/aspeed-ast2600-evb.dts @@ -8,7 +8,7 @@
/ { model = "AST2600 EVB"; - compatible = "aspeed,ast2600"; + compatible = "aspeed,ast2600-evb-a1", "aspeed,ast2600";
aliases { serial4 = &uart5;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 33c39140cc298e0d4e36083cb9a665a837773a60 ]
The AST2600 EVB A1 board should have dedicated compatible.
Fixes: a72955180372 ("ARM: dts: aspeed: ast2600evb: Add dts file for A1 and A0") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220529104928.79636-6-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts b/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts index dd7148060c4a..d0a5c2ff0fec 100644 --- a/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts +++ b/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts @@ -5,6 +5,7 @@
/ { model = "AST2600 A1 EVB"; + compatible = "aspeed,ast2600-evb-a1", "aspeed,ast2600";
/delete-node/regulator-vcc-sdhci0; /delete-node/regulator-vcc-sdhci1;
From: Nícolas F. R. A. Prado nfraprado@collabora.com
[ Upstream commit 399e23ad51caaf62400a531c9268ad3c453c3d76 ]
Tweak the name of the idle-states subnodes so that they follow the binding pattern, getting rid of dtbs_check warnings.
Only the usage of "-" in the name was necessary, but "off" was also exchanged for "sleep" since that seems to be a more common wording in other dts files.
Fixes: 9260918d3a4f ("arm64: dts: mt8192: Add cpu-idle-states") 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/20220617233150.2466344-2-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 | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi index 733aec2e7f77..c739e910883a 100644 --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi @@ -43,7 +43,7 @@ cpu0: cpu@0 { reg = <0x000>; enable-method = "psci"; clock-frequency = <1701000000>; - cpu-idle-states = <&cpuoff_l &clusteroff_l>; + cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; capacity-dmips-mhz = <530>; }; @@ -54,7 +54,7 @@ cpu1: cpu@100 { reg = <0x100>; enable-method = "psci"; clock-frequency = <1701000000>; - cpu-idle-states = <&cpuoff_l &clusteroff_l>; + cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; capacity-dmips-mhz = <530>; }; @@ -65,7 +65,7 @@ cpu2: cpu@200 { reg = <0x200>; enable-method = "psci"; clock-frequency = <1701000000>; - cpu-idle-states = <&cpuoff_l &clusteroff_l>; + cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; capacity-dmips-mhz = <530>; }; @@ -76,7 +76,7 @@ cpu3: cpu@300 { reg = <0x300>; enable-method = "psci"; clock-frequency = <1701000000>; - cpu-idle-states = <&cpuoff_l &clusteroff_l>; + cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>; next-level-cache = <&l2_0>; capacity-dmips-mhz = <530>; }; @@ -87,7 +87,7 @@ cpu4: cpu@400 { reg = <0x400>; enable-method = "psci"; clock-frequency = <2171000000>; - cpu-idle-states = <&cpuoff_b &clusteroff_b>; + cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>; next-level-cache = <&l2_1>; capacity-dmips-mhz = <1024>; }; @@ -98,7 +98,7 @@ cpu5: cpu@500 { reg = <0x500>; enable-method = "psci"; clock-frequency = <2171000000>; - cpu-idle-states = <&cpuoff_b &clusteroff_b>; + cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>; next-level-cache = <&l2_1>; capacity-dmips-mhz = <1024>; }; @@ -109,7 +109,7 @@ cpu6: cpu@600 { reg = <0x600>; enable-method = "psci"; clock-frequency = <2171000000>; - cpu-idle-states = <&cpuoff_b &clusteroff_b>; + cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>; next-level-cache = <&l2_1>; capacity-dmips-mhz = <1024>; }; @@ -120,7 +120,7 @@ cpu7: cpu@700 { reg = <0x700>; enable-method = "psci"; clock-frequency = <2171000000>; - cpu-idle-states = <&cpuoff_b &clusteroff_b>; + cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>; next-level-cache = <&l2_1>; capacity-dmips-mhz = <1024>; }; @@ -173,7 +173,7 @@ l3_0: l3-cache {
idle-states { entry-method = "arm,psci"; - cpuoff_l: cpuoff_l { + cpu_sleep_l: cpu-sleep-l { compatible = "arm,idle-state"; arm,psci-suspend-param = <0x00010001>; local-timer-stop; @@ -181,7 +181,7 @@ cpuoff_l: cpuoff_l { exit-latency-us = <140>; min-residency-us = <780>; }; - cpuoff_b: cpuoff_b { + cpu_sleep_b: cpu-sleep-b { compatible = "arm,idle-state"; arm,psci-suspend-param = <0x00010001>; local-timer-stop; @@ -189,7 +189,7 @@ cpuoff_b: cpuoff_b { exit-latency-us = <145>; min-residency-us = <720>; }; - clusteroff_l: clusteroff_l { + cluster_sleep_l: cluster-sleep-l { compatible = "arm,idle-state"; arm,psci-suspend-param = <0x01010002>; local-timer-stop; @@ -197,7 +197,7 @@ clusteroff_l: clusteroff_l { exit-latency-us = <155>; min-residency-us = <860>; }; - clusteroff_b: clusteroff_b { + cluster_sleep_b: cluster-sleep-b { compatible = "arm,idle-state"; arm,psci-suspend-param = <0x01010002>; local-timer-stop;
From: Nícolas F. R. A. Prado nfraprado@collabora.com
[ Upstream commit 2e599740f7e423ee89fb027896cb2635dd43784f ]
The entry-method property of the idle-states node should be "psci" as described in the idle-states binding, since this is already the value of enable-method in the CPU nodes. Fix it to get rid of a dtbs_check warning.
Fixes: 9260918d3a4f ("arm64: dts: mt8192: Add cpu-idle-states") 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/20220617233150.2466344-3-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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi index c739e910883a..d5cae38c842a 100644 --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi @@ -172,7 +172,7 @@ l3_0: l3-cache { };
idle-states { - entry-method = "arm,psci"; + entry-method = "psci"; cpu_sleep_l: cpu-sleep-l { compatible = "arm,idle-state"; arm,psci-suspend-param = <0x00010001>;
From: Mark Rutland mark.rutland@arm.com
[ Upstream commit 3381da254fab37ba08c4b7c4f19b4ee28b1a27ec ]
Due to an oversight, on arm64 lockdep IRQ state tracking doesn't work as intended in NMI context. This demonstrably results in bogus warnings from lockdep, and in theory could mask a variety of issues.
On arm64, we've consistently tracked IRQ flag state for NMIs (and saved/restored the state of the interrupted context) since commit:
f0cd5ac1e4c53cb6 ("arm64: entry: fix NMI {user, kernel}->kernel transitions")
That commit fixed most lockdep issues with NMI by virtue of the save/restore of the lockdep state of the interrupted context. However, for lockdep IRQ state tracking to consistently take effect in NMI context it has been necessary to select TRACE_IRQFLAGS_NMI_SUPPORT since commit:
ed00495333ccc80f ("locking/lockdep: Fix TRACE_IRQFLAGS vs. NMIs")
As arm64 does not select TRACE_IRQFLAGS_NMI_SUPPORT, this means that the lockdep state can be stale in NMI context, and some uses of that state can consume stale data.
When an NMI is taken arm64 entry code will call arm64_enter_nmi(). This will enter NMI context via __nmi_enter() before calling lockdep_hardirqs_off() to inform lockdep that IRQs have been masked. Where TRACE_IRQFLAGS_NMI_SUPPORT is not selected, lockdep_hardirqs_off() will not update lockdep state if called in NMI context. Thus if IRQs were enabled in the original context, lockdep will continue to believe that IRQs are enabled despite the call to lockdep_hardirqs_off().
However, the lockdep_assert_*() checks do take effect in NMI context, and will consume the stale lockdep state. If an NMI is taken from a context which had IRQs enabled, and during the handling of the NMI something calls lockdep_assert_irqs_disabled(), this will result in a spurious warning based upon the stale lockdep state.
This can be seen when using perf with GICv3 pseudo-NMIs. Within the perf NMI handler we may attempt a uaccess to record the userspace callchain, and is this faults the el1_abort() call in the nested context will call exit_to_kernel_mode() when returning, which has a lockdep_assert_irqs_disabled() assertion:
| # ./perf record -a -g sh | ------------[ cut here ]------------ | WARNING: CPU: 0 PID: 164 at arch/arm64/kernel/entry-common.c:73 exit_to_kernel_mode+0x118/0x1ac | Modules linked in: | CPU: 0 PID: 164 Comm: perf Not tainted 5.18.0-rc5 #1 | Hardware name: linux,dummy-virt (DT) | pstate: 004003c5 (nzcv DAIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : exit_to_kernel_mode+0x118/0x1ac | lr : el1_abort+0x80/0xbc | sp : ffff8000080039f0 | pmr_save: 000000f0 | x29: ffff8000080039f0 x28: ffff6831054e4980 x27: ffff683103adb400 | x26: 0000000000000000 x25: 0000000000000001 x24: 0000000000000001 | x23: 00000000804000c5 x22: 00000000000000c0 x21: 0000000000000001 | x20: ffffbd51e635ec44 x19: ffff800008003a60 x18: 0000000000000000 | x17: ffffaadf98d23000 x16: ffff800008004000 x15: 0000ffffd14f25c0 | x14: 0000000000000000 x13: 00000000000018eb x12: 0000000000000040 | x11: 000000000000001e x10: 000000002b820020 x9 : 0000000100110000 | x8 : 000000000045cac0 x7 : 0000ffffd14f25c0 x6 : ffffbd51e639b000 | x5 : 00000000000003e5 x4 : ffffbd51e58543b0 x3 : 0000000000000001 | x2 : ffffaadf98d23000 x1 : ffff6831054e4980 x0 : 0000000100110000 | Call trace: | exit_to_kernel_mode+0x118/0x1ac | el1_abort+0x80/0xbc | el1h_64_sync_handler+0xa4/0xd0 | el1h_64_sync+0x74/0x78 | __arch_copy_from_user+0xa4/0x230 | get_perf_callchain+0x134/0x1e4 | perf_callchain+0x7c/0xa0 | perf_prepare_sample+0x414/0x660 | perf_event_output_forward+0x80/0x180 | __perf_event_overflow+0x70/0x13c | perf_event_overflow+0x1c/0x30 | armv8pmu_handle_irq+0xe8/0x160 | armpmu_dispatch_irq+0x2c/0x70 | handle_percpu_devid_fasteoi_nmi+0x7c/0xbc | generic_handle_domain_nmi+0x3c/0x60 | gic_handle_irq+0x1dc/0x310 | call_on_irq_stack+0x2c/0x54 | do_interrupt_handler+0x80/0x94 | el1_interrupt+0xb0/0xe4 | el1h_64_irq_handler+0x18/0x24 | el1h_64_irq+0x74/0x78 | lockdep_hardirqs_off+0x50/0x120 | trace_hardirqs_off+0x38/0x214 | _raw_spin_lock_irq+0x98/0xa0 | pipe_read+0x1f8/0x404 | new_sync_read+0x140/0x150 | vfs_read+0x190/0x1dc | ksys_read+0xdc/0xfc | __arm64_sys_read+0x20/0x30 | invoke_syscall+0x48/0x114 | el0_svc_common.constprop.0+0x158/0x17c | do_el0_svc+0x28/0x90 | el0_svc+0x60/0x150 | el0t_64_sync_handler+0xa4/0x130 | el0t_64_sync+0x19c/0x1a0 | irq event stamp: 483 | hardirqs last enabled at (483): [<ffffbd51e636aa24>] _raw_spin_unlock_irqrestore+0xa4/0xb0 | hardirqs last disabled at (482): [<ffffbd51e636acd0>] _raw_spin_lock_irqsave+0xb0/0xb4 | softirqs last enabled at (468): [<ffffbd51e5216f58>] put_cpu_fpsimd_context+0x28/0x70 | softirqs last disabled at (466): [<ffffbd51e5216ed4>] get_cpu_fpsimd_context+0x0/0x5c | ---[ end trace 0000000000000000 ]---
Note that as lockdep_assert_irqs_disabled() uses WARN_ON_ONCE(), and this uses a BRK, the warning is logged with the real PSTATE at the time of the warning, which clearly has DAIF.I set, meaning IRQs (and pseudo-NMIs) were definitely masked and the warning is spurious.
Fix this by selecting TRACE_IRQFLAGS_NMI_SUPPORT such that the existing entry tracking takes effect, as we had originally intended when the arm64 entry code was fixed for transitions to/from NMI.
Arguably the lockdep_assert_*() functions should have the same NMI checks as the rest of the code to prevent spurious warnings when TRACE_IRQFLAGS_NMI_SUPPORT is not selected, but the real fix for any architecture is to explicitly handle the transitions to/from NMI in the entry code.
Fixes: f0cd5ac1e4c5 ("arm64: entry: fix NMI {user, kernel}->kernel transitions") Signed-off-by: Mark Rutland mark.rutland@arm.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Ingo Molnar mingo@kernel.org Cc: Peter Zijlstra (Intel) peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Will Deacon will@kernel.org Link: https://lore.kernel.org/r/20220511131733.4074499-3-mark.rutland@arm.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3ad734de8e49..a5d1b561ed53 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -226,6 +226,7 @@ config ARM64 select THREAD_INFO_IN_TASK select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD select TRACE_IRQFLAGS_SUPPORT + select TRACE_IRQFLAGS_NMI_SUPPORT help ARM 64-bit (AArch64) Linux support.
From: Alexandru Elisei alexandru.elisei@arm.com
[ Upstream commit 506506cad3947b942425b119ffa2b06715d5d804 ]
Commit b20d1ba3cf4b ("arm64: cpufeature: allow for version discrepancy in PMU implementations") made it possible to run Linux on a machine with PMUs with different versions without tainting the kernel. The patch relaxed the restriction only for the ID_AA64DFR0_EL1.PMUVer field, and missed doing the same for ID_DFR0_EL1.PerfMon , which also reports the PMU version, but for the AArch32 state.
For example, with Linux running on two clusters with different PMU versions, the kernel is tainted when bringing up secondaries with the following message:
[ 0.097027] smp: Bringing up secondary CPUs ... [..] [ 0.142805] Detected PIPT I-cache on CPU4 [ 0.142805] CPU features: SANITY CHECK: Unexpected variation in SYS_ID_DFR0_EL1. Boot CPU: 0x00000004011088, CPU4: 0x00000005011088 [ 0.143555] CPU features: Unsupported CPU feature variation detected. [ 0.143702] GICv3: CPU4: found redistributor 10000 region 0:0x000000002f180000 [ 0.143702] GICv3: CPU4: using allocated LPI pending table @0x00000008800d0000 [ 0.144888] CPU4: Booted secondary processor 0x0000010000 [0x410fd0f0]
The boot CPU implements FEAT_PMUv3p1 (ID_DFR0_EL1.PerfMon, bits 27:24, is 0b0100), but CPU4, part of the other cluster, implements FEAT_PMUv3p4 (ID_DFR0_EL1.PerfMon = 0b0101).
Treat the PerfMon field as FTR_NONSTRICT and FTR_EXACT to pass the sanity check and to match how PMUVer is treated for the 64bit ID register.
Fixes: b20d1ba3cf4b ("arm64: cpufeature: allow for version discrepancy in PMU implementations") Signed-off-by: Alexandru Elisei alexandru.elisei@arm.com Link: https://lore.kernel.org/r/20220617111332.203061-1-alexandru.elisei@arm.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/cpufeature.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 90018643d424..ebdfbd1cf207 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -562,7 +562,7 @@ static const struct arm64_ftr_bits ftr_id_pfr2[] = {
static const struct arm64_ftr_bits ftr_id_dfr0[] = { /* [31:28] TraceFilt */ - S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_PERFMON_SHIFT, 4, 0xf), + S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_DFR0_PERFMON_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_MPROFDBG_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_MMAPTRC_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_COPTRC_SHIFT, 4, 0),
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit eae6d58d67d9739be5f7ae2dbead1d0ef6528243 ]
Commit dfd5e3f5fe27 ("locking/lockdep: Mark local_lock_t") added yet another lockdep_init_map_*() variant, but forgot to update all the existing users of the most complicated version.
This could lead to a loss of lock_type and hence an incorrect report. Given the relative rarity of both local_lock and these annotations, this is unlikely to happen in practise, still, best fix things.
Fixes: dfd5e3f5fe27 ("locking/lockdep: Mark local_lock_t") Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/YqyEDtoan20K0CVD@worktop.programming.kicks-ass.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/lockdep.h | 30 +++++++++++++++++------------- kernel/locking/lockdep.c | 7 ++++--- 2 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index b6829b970093..1f1099dac3f0 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -188,7 +188,7 @@ static inline void lockdep_init_map_waits(struct lockdep_map *lock, const char *name, struct lock_class_key *key, int subclass, u8 inner, u8 outer) { - lockdep_init_map_type(lock, name, key, subclass, inner, LD_WAIT_INV, LD_LOCK_NORMAL); + lockdep_init_map_type(lock, name, key, subclass, inner, outer, LD_LOCK_NORMAL); }
static inline void @@ -211,24 +211,28 @@ static inline void lockdep_init_map(struct lockdep_map *lock, const char *name, * or they are too narrow (they suffer from a false class-split): */ #define lockdep_set_class(lock, key) \ - lockdep_init_map_waits(&(lock)->dep_map, #key, key, 0, \ - (lock)->dep_map.wait_type_inner, \ - (lock)->dep_map.wait_type_outer) + lockdep_init_map_type(&(lock)->dep_map, #key, key, 0, \ + (lock)->dep_map.wait_type_inner, \ + (lock)->dep_map.wait_type_outer, \ + (lock)->dep_map.lock_type)
#define lockdep_set_class_and_name(lock, key, name) \ - lockdep_init_map_waits(&(lock)->dep_map, name, key, 0, \ - (lock)->dep_map.wait_type_inner, \ - (lock)->dep_map.wait_type_outer) + lockdep_init_map_type(&(lock)->dep_map, name, key, 0, \ + (lock)->dep_map.wait_type_inner, \ + (lock)->dep_map.wait_type_outer, \ + (lock)->dep_map.lock_type)
#define lockdep_set_class_and_subclass(lock, key, sub) \ - lockdep_init_map_waits(&(lock)->dep_map, #key, key, sub,\ - (lock)->dep_map.wait_type_inner, \ - (lock)->dep_map.wait_type_outer) + lockdep_init_map_type(&(lock)->dep_map, #key, key, sub, \ + (lock)->dep_map.wait_type_inner, \ + (lock)->dep_map.wait_type_outer, \ + (lock)->dep_map.lock_type)
#define lockdep_set_subclass(lock, sub) \ - lockdep_init_map_waits(&(lock)->dep_map, #lock, (lock)->dep_map.key, sub,\ - (lock)->dep_map.wait_type_inner, \ - (lock)->dep_map.wait_type_outer) + lockdep_init_map_type(&(lock)->dep_map, #lock, (lock)->dep_map.key, sub,\ + (lock)->dep_map.wait_type_inner, \ + (lock)->dep_map.wait_type_outer, \ + (lock)->dep_map.lock_type)
#define lockdep_set_novalidate_class(lock) \ lockdep_set_class_and_name(lock, &__lockdep_no_validate__, #lock) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index f06b91ca6482..e2f179491b08 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -5238,9 +5238,10 @@ __lock_set_class(struct lockdep_map *lock, const char *name, return 0; }
- lockdep_init_map_waits(lock, name, key, 0, - lock->wait_type_inner, - lock->wait_type_outer); + lockdep_init_map_type(lock, name, key, 0, + lock->wait_type_inner, + lock->wait_type_outer, + lock->lock_type); class = register_lock_class(lock, subclass, 0); hlock->class_idx = class - lock_classes;
From: Stephen Boyd swboyd@chromium.org
[ Upstream commit e60414644cf3a703e10ed4429c15263095945ffe ]
We don't use this carveout on trogdor boards, and having it defined in the sc7180 SoC file causes an overlap message to be printed at boot.
OF: reserved mem: OVERLAP DETECTED! memory@86000000 (0x0000000086000000--0x000000008ec00000) overlaps with memory@8b700000 (0x000000008b700000--0x000000008b710000)
Delete the node in the trogdor dtsi file to fix the overlap problem and remove the error message.
Cc: Alex Elder elder@linaro.org Cc: Matthias Kaehlcke mka@chromium.org Fixes: 310b266655a3 ("arm64: dts: qcom: sc7180: define ipa_fw_mem node") Signed-off-by: Stephen Boyd swboyd@chromium.org Reviewed-by: Alex Elder elder@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220517193307.3034602-1-swboyd@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi index e55dbaa6dc12..a071b8f5d7dc 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi @@ -43,6 +43,7 @@ charger-crit { */
/delete-node/ &hyp_mem; +/delete-node/ &ipa_fw_mem; /delete-node/ &xbl_mem; /delete-node/ &aop_mem; /delete-node/ &sec_apps_mem;
From: Michael Walle michael@walle.cc
[ Upstream commit ab3f045774f704c4e7b6a878102f4e9d4ae7bc74 ]
If both the model and the compatible properties are missing, then machine will not be set. Initialize it with NULL.
Fixes: 34c1c21e94ac ("soc: fsl: fix section mismatch build warnings") Signed-off-by: Michael Walle michael@walle.cc Acked-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/fsl/guts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index 5ed2fc1c53a0..be18d46c7b0f 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -140,7 +140,7 @@ static int fsl_guts_probe(struct platform_device *pdev) struct device_node *root, *np = pdev->dev.of_node; struct device *dev = &pdev->dev; const struct fsl_soc_die_attr *soc_die; - const char *machine; + const char *machine = NULL; u32 svr;
/* Initialize guts */
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit a813c47d22b0a0c51567292bc198a39bdcdc3799 ]
All struct s3c64xx_spi_port_config should be const.
Fixes: 4ebb15a15799 ("spi: s3c64xx: Add spi port configuration for Tesla FSD SoC") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220627094541.95166-1-krzysztof.kozlowski@linaro.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-s3c64xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index c26440e9058d..8fa21afc6a35 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -1413,7 +1413,7 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = { .quirks = S3C64XX_SPI_QUIRK_CS_AUTO, };
-static struct s3c64xx_spi_port_config fsd_spi_port_config = { +static const struct s3c64xx_spi_port_config fsd_spi_port_config = { .fifo_lvl_mask = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f}, .rx_lvl_offset = 15, .tx_st_done = 25,
From: Keith Busch kbusch@kernel.org
[ Upstream commit b82d9fa257cb3725c49d94d2aeafc4677c34448a ]
Returning 0 early from __bio_iov_append_get_pages() for the max_append_sectors warning just creates an infinite loop since 0 means success, and the bio will never fill from the unadvancing iov_iter. We could turn the return into an error value, but it will already be turned into an error value later on, so just remove the warning. Clearly no one ever hit it anyway.
Fixes: 0512a75b98f84 ("block: Introduce REQ_OP_ZONE_APPEND") Signed-off-by: Keith Busch kbusch@kernel.org Reviewed-by: Damien Le Moal damien.lemoal@opensource.wdc.com Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Link: https://lore.kernel.org/r/20220610195830.3574005-2-kbusch@fb.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bio.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/block/bio.c b/block/bio.c index 51c99f2c5c90..d9ff51fc457e 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1229,9 +1229,6 @@ static int __bio_iov_append_get_pages(struct bio *bio, struct iov_iter *iter) size_t offset; int ret = 0;
- if (WARN_ON_ONCE(!max_append_sectors)) - return 0; - /* * Move page array up in the allocated memory for the bio vecs as far as * possible so that we can start filling biovecs from the beginning
From: Marijn Suijten marijn.suijten@somainline.org
[ Upstream commit 4148a9eeb15152865d60b0913d96beb7ca166f9a ]
2700000 is not a multiple of pmic4_pldo's step size of 8000 (with base voltage 1664000), resulting in pm8998-rpmh-regulators not probing. Just as we did with MSM8998's Sony Yoshino Poplar [1], round the voltages down to err on the cautious side and leave a comment in place to document this discrepancy wrt downstream sources.
[1]: https://lore.kernel.org/linux-arm-msm/20220507153627.1478268-1-marijn.suijte...
Fixes: 30a7f99befc6 ("arm64: dts: qcom: Add support for SONY Xperia XZ2 / XZ2C / XZ3 (Tama platform)") Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-by: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220620211212.269956-1-marijn.suijten@somainline.... Signed-off-by: Sasha Levin sashal@kernel.org --- .../arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts index 8a0d94e7f598..2f5e12deaada 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts @@ -19,8 +19,9 @@ &vreg_l14a_1p8 { };
&vreg_l22a_2p8 { - regulator-min-microvolt = <2700000>; - regulator-max-microvolt = <2700000>; + /* Note: Round-down from 2700000 to be a multiple of PLDO step-size 8000 */ + regulator-min-microvolt = <2696000>; + regulator-max-microvolt = <2696000>; };
&vreg_l28a_2p8 {
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit dc590cdc31f636ea15658f1206c3e380a53fb78e ]
'reg' property is required in SSBI children: qcom-mdm9615-wp8548-mangoh-green.dtb: gpio@150: 'reg' is a required property
Fixes: 2c5e596524e7 ("ARM: dts: Add MDM9615 dtsi") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220507194913.261121-11-krzysztof.kozlowski@linar... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-mdm9615.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom-mdm9615.dtsi index 8f0752ce1c7b..0ce0d04bd994 100644 --- a/arch/arm/boot/dts/qcom-mdm9615.dtsi +++ b/arch/arm/boot/dts/qcom-mdm9615.dtsi @@ -321,6 +321,7 @@ rtc@11d {
pmicgpio: gpio@150 { compatible = "qcom,pm8018-gpio", "qcom,ssbi-gpio"; + reg = <0x150>; interrupt-controller; #interrupt-cells = <2>; gpio-controller;
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 9705db1eff38d6b9114121f9e253746199b759c9 ]
omapdss_find_dss_of_node() calls of_find_compatible_node() to get device node. of_find_compatible_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. Add missing of_node_put() in later error path and normal path.
Fixes: e0c827aca0730 ("drm/omap: Populate DSS children in omapdss driver") Signed-off-by: Miaoqian Lin linmq006@gmail.com Message-Id: 20220601044858.3352-1-linmq006@gmail.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap2/display.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index eb09a25e3b45..8d829f3dafe7 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -260,11 +260,13 @@ static int __init omapdss_init_of(void)
if (!pdev) { pr_err("Unable to find DSS platform device\n"); + of_node_put(node); return -ENODEV; }
r = of_platform_populate(node, NULL, NULL, &pdev->dev); put_device(&pdev->dev); + of_node_put(node); if (r) { pr_err("Unable to populate DSS submodule devices\n"); return r;
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 942228fbf5d4901112178b93d41225be7c0dd9de ]
of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: 1e037794f7f0 ("ARM: OMAP3+: PRM: register interrupt information from DT") Signed-off-by: Miaoqian Lin linmq006@gmail.com Message-Id: 20220526073724.21169-1-linmq006@gmail.com Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap2/prm3xxx.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index 1b442b128569..63e73e9b82bc 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c @@ -708,6 +708,7 @@ static int omap3xxx_prm_late_init(void) }
irq_num = of_irq_get(np, 0); + of_node_put(np); if (irq_num == -EPROBE_DEFER) return irq_num;
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 1c047919763b4548381d1ab3320af1df66ab83df ]
The SoC's device tree file disables gpucc and adreno's SMMU by default. So let's disable the GPU too. Moreover it looks like SMMU might be not usable without additional patches (which means that GPU is unusable too). No board uses GPU at this moment.
Fixes: 5cf69dcbec8b ("arm64: dts: qcom: sdm630: Add Adreno 508 GPU configuration") Reviewed-by: Konrad Dybcio konrad.dybcio@somainline.org Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220521202708.1509308-4-dmitry.baryshkov@linaro.o... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi index b72e8e6c52f3..b4dcfecd5cf3 100644 --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -1050,6 +1050,8 @@ adreno_gpu: gpu@5000000 {
operating-points-v2 = <&gpu_sdm630_opp_table>;
+ status = "disabled"; + gpu_sdm630_opp_table: opp-table { compatible = "operating-points-v2"; opp-775000000 {
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 924bbd8dd60e094344711c3526a5b308d71dc008 ]
According to the downstram DT file, the qusb2phy ref clock should be GCC_RX0_USB2_CLKREF_CLK, not GCC_RX1_USB2_CLKREF_CLK.
Fixes: c65a4ed2ea8b ("arm64: dts: qcom: sdm630: Add USB configuration") Cc: Konrad Dybcio konrad.dybcio@somainline.org Reviewed-by: Konrad Dybcio konrad.dybcio@somainline.org Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220521202708.1509308-5-dmitry.baryshkov@linaro.o... 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 b4dcfecd5cf3..dc184d47c8b3 100644 --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -1266,7 +1266,7 @@ qusb2phy: phy@c012000 { #phy-cells = <0>;
clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, - <&gcc GCC_RX1_USB2_CLKREF_CLK>; + <&gcc GCC_RX0_USB2_CLKREF_CLK>; clock-names = "cfg_ahb", "ref";
resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 3cd1c4f41d64a40ea6bc4575ae28e37542123d77 ]
ICC path for the GPU incorrectly states <&gnoc 1 &bimc 5>, which is a path from SLAVE_GNOC_BIMC to SLAVE_EBI. According to the downstream kernel sources, the GPU uses MASTER_OXILI here, which is equivalent to <&bimc 1 ...>.
While we are at it, use defined names instead of the numbers for this interconnect path.
Fixes: 5cf69dcbec8b ("arm64: dts: qcom: sdm630: Add Adreno 508 GPU configuration") Reported-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220521202708.1509308-8-dmitry.baryshkov@linaro.o... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm630.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi index dc184d47c8b3..2acd55bd3e5b 100644 --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -8,6 +8,7 @@ #include <dt-bindings/clock/qcom,gpucc-sdm660.h> #include <dt-bindings/clock/qcom,mmcc-sdm660.h> #include <dt-bindings/clock/qcom,rpmcc.h> +#include <dt-bindings/interconnect/qcom,sdm660.h> #include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/arm-gic.h> @@ -1045,7 +1046,7 @@ adreno_gpu: gpu@5000000 { nvmem-cells = <&gpu_speed_bin>; nvmem-cell-names = "speed_bin";
- interconnects = <&gnoc 1 &bimc 5>; + interconnects = <&bimc MASTER_OXILI &bimc SLAVE_EBI>; interconnect-names = "gfx-mem";
operating-points-v2 = <&gpu_sdm630_opp_table>;
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 3a04cec9cba393abfe70fc62e523f381c9baec2e ]
Fix the device tree node in the &sdc2_state_on override. The sdm630 uses 'clk' rather than 'pinconf-clk'.
Fixes: 4c1d849ec047 ("arm64: dts: qcom: sdm630-xperia: Retire sdm630-sony-xperia-ganges.dtsi") Reviewed-by: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220521202708.1509308-9-dmitry.baryshkov@linaro.o... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts b/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts index b96da53f2f1e..58f687fc49e0 100644 --- a/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts +++ b/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts @@ -19,7 +19,7 @@ / { };
&sdc2_state_on { - pinconf-clk { + clk { drive-strength = <14>; }; };
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit d1ff2559cef0f6f8d97fba6337b28adb10689e16 ]
of_find_compatible_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. Add missing of_node_put() to avoid refcount leak.
Fixes: 00f7dc636366 ("ARM: zynq: Add support for SOC_BUS") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220605082807.21526-1-linmq006@gmail.com Signed-off-by: Michal Simek michal.simek@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-zynq/common.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index e1ca6a5732d2..15e8a321a713 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -77,6 +77,7 @@ static int __init zynq_get_revision(void) }
zynq_devcfg_base = of_iomap(np, 0); + of_node_put(np); if (!zynq_devcfg_base) { pr_err("%s: Unable to map I/O memory\n", __func__); return -1;
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit f48cb21a28c07d0754d5f2f85444cfb0e7b1fd05 ]
The highest-performance mode for the Cortex-A57 CPU cores supported on R-Car H3Ne (R8A779M8) is the Power Optimized (1.5 GHz) mode. The Normal (1.6 GHz) and High Performance (1.7 GHz) modes are not supported.
Hence drop the "turbo-mode" entries from the operating points table inherited from r8a77951.dtsi.
Fixes: 6e87525d751fac57 ("arm64: dts: renesas: Add Renesas R8A779M8 SoC support") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/aeb4530f7fbac8329b334dcb169382c836a5f32d.165545856... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/renesas/r8a779m8.dtsi | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r8a779m8.dtsi b/arch/arm64/boot/dts/renesas/r8a779m8.dtsi index 752440b0c40f..750bd8ccdb7f 100644 --- a/arch/arm64/boot/dts/renesas/r8a779m8.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779m8.dtsi @@ -10,3 +10,8 @@ / { compatible = "renesas,r8a779m8", "renesas,r8a7795"; }; + +&cluster0_opp { + /delete-node/ opp-1600000000; + /delete-node/ opp-1700000000; +};
From: Chris Paterson chris.paterson2@renesas.com
[ Upstream commit d1273f541ab409242e08da6bb836bb564021274c ]
This dts is for the RZ/V2L SMARC EVK, not RZ/G2L.
Fixes: f91c4c74796a ("arm64: dts: renesas: Add initial device tree for RZ/V2L SMARC EVK") Signed-off-by: Chris Paterson chris.paterson2@renesas.com Link: https://lore.kernel.org/r/20220623103024.24222-1-chris.paterson2@renesas.com Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts b/arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts index 4e07e1a0fb66..3d01a4cf0fbe 100644 --- a/arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts +++ b/arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) /* - * Device Tree Source for the RZ/G2L SMARC EVK board + * Device Tree Source for the RZ/V2L SMARC EVK board * * Copyright (C) 2021 Renesas Electronics Corp. */
From: Stephan Gerhold stephan.gerhold@kernkonzept.com
[ Upstream commit e8977917e116d1571dacb8e9864474551c1c12bd ]
The PM8916 device specification [1] documents a programmable range of 1.75V to 3.337V with 12.5mV steps for the PMOS LDOs in PM8916. This range is also used when controlling the regulator directly using the qcom_spmi-regulator driver ("ult_pldo" there).
However, for some reason the qcom_smd-regulator driver allows a much larger range for the same hardware component. This could be simply a typo, since the start of the range is essentially just missing a '1'.
In practice this does not cause any major problems, since the driver just sends the actual voltage to the RPM firmware instead of making use of the incorrect voltage selector. Still, having the wrong range there is confusing and prevents the regulator core from validating requests correctly.
[1]: https://developer.qualcomm.com/download/sd410/pm8916pm8916-1-power-managemen...
Fixes: 57d6567680ed ("regulator: qcom-smd: Add PM8916 support") Signed-off-by: Stephan Gerhold stephan.gerhold@kernkonzept.com Link: https://lore.kernel.org/r/20220623094614.1410180-2-stephan.gerhold@kernkonze... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/qcom_smd-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index ef6e47d025ca..60f3513f7038 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -357,10 +357,10 @@ static const struct regulator_desc pm8941_switch = {
static const struct regulator_desc pm8916_pldo = { .linear_ranges = (struct linear_range[]) { - REGULATOR_LINEAR_RANGE(750000, 0, 208, 12500), + REGULATOR_LINEAR_RANGE(1750000, 0, 127, 12500), }, .n_linear_ranges = 1, - .n_voltages = 209, + .n_voltages = 128, .ops = &rpm_smps_ldo_ops, };
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit b13a3e5fd40b7d1b394c5ecbb5eb301a4c38e7b2 ]
When a platform marks a memory range as "special purpose" it is not onlined as System RAM by default. However, it is still suitable for error injection. Add IORES_DESC_SOFT_RESERVED to einj_error_inject() as a permissible memory type in the sanity checking of the arguments to _EINJ.
Fixes: 262b45ae3ab4 ("x86/efi: EFI soft reservation to E820 enumeration") Reviewed-by: Tony Luck tony.luck@intel.com Reported-by: Omar Avelar omar.avelar@intel.com Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/apei/einj.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index d4326ec12d29..6b583373c58a 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c @@ -546,6 +546,8 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, != REGION_INTERSECTS) && (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY) != REGION_INTERSECTS) && + (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_SOFT_RESERVED) + != REGION_INTERSECTS) && !arch_is_platform_page(base_addr))) return -EINVAL;
From: Ansuel Smith ansuelsmth@gmail.com
[ Upstream commit eb9e93937756a05787977875830c0dc482cb57e0 ]
Replace gcc PXO phandle to pxo_board fixed clock declared in the dts. gcc driver doesn't provide PXO_SRC as it's a fixed-clock. This cause a kernel panic if any driver actually try to use it.
Fixes: 40cf5c884a96 ("ARM: dts: qcom: add L2CC and RPM for IPQ8064") Signed-off-by: Ansuel Smith ansuelsmth@gmail.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220430055118.1947-2-ansuelsmth@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-ipq8064.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi index 808ea1862283..d09354ca100d 100644 --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi @@ -784,7 +784,7 @@ tcsr: syscon@1a400000 { l2cc: clock-controller@2011000 { compatible = "qcom,kpss-gcc", "syscon"; reg = <0x2011000 0x1000>; - clocks = <&gcc PLL8_VOTE>, <&gcc PXO_SRC>; + clocks = <&gcc PLL8_VOTE>, <&pxo_board>; clock-names = "pll8_vote", "pxo"; clock-output-names = "acpu_l2_aux"; };
From: Luca Weiss luca@z3ntu.xyz
[ Upstream commit ab1489017aa7a9f02e24bee73cf9ec8079cd3909 ]
IRQ_TYPE_NONE is invalid, so use the correct interrupt type.
Signed-off-by: Luca Weiss luca@z3ntu.xyz Fixes: b05f82b152c9 ("ARM: dts: qcom: msm8974: Add blsp2_uart7 for bluetooth on sirius") Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220522083618.17894-1-luca@z3ntu.xyz Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index c3b8a6d63027..ce9cb5e4e95d 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -580,7 +580,7 @@ blsp2_dma: dma-controller@f9944000 { blsp2_uart1: serial@f995d000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; reg = <0xf995d000 0x1000>; - interrupts = <GIC_SPI 113 IRQ_TYPE_NONE>; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; clocks = <&gcc GCC_BLSP2_UART1_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>; clock-names = "core", "iface"; pinctrl-names = "default", "sleep";
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 92a563fcf14b3093226fb36f12e9b5cf630c5a5d ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak. of_node_put() will check NULL pointer.
Fixes: 88c1e9404f1d ("soc: qcom: add OCMEM driver") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Brian Masney masneyb@onstation.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220602042430.1114-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/ocmem.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c index 97fd24c178f8..c92d26b73e6f 100644 --- a/drivers/soc/qcom/ocmem.c +++ b/drivers/soc/qcom/ocmem.c @@ -194,14 +194,17 @@ struct ocmem *of_get_ocmem(struct device *dev) devnode = of_parse_phandle(dev->of_node, "sram", 0); if (!devnode || !devnode->parent) { dev_err(dev, "Cannot look up sram phandle\n"); + of_node_put(devnode); return ERR_PTR(-ENODEV); }
pdev = of_find_device_by_node(devnode->parent); if (!pdev) { dev_err(dev, "Cannot find device node %s\n", devnode->name); + of_node_put(devnode); return ERR_PTR(-EPROBE_DEFER); } + of_node_put(devnode);
ocmem = platform_get_drvdata(pdev); if (!ocmem) {
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit e6e0951414a314e7db3e9e24fd924b3e15515288 ]
Every iteration of for_each_available_child_of_node() decrements the reference count of the previous node. When breaking early from a for_each_available_child_of_node() loop, we need to explicitly call of_node_put() on the child node. Add missing of_node_put() to avoid refcount leak.
Fixes: 05589b30b21a ("soc: qcom: Extend AOSS QMP driver to support resources that are used to wake up the SoC.") Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220606064252.42595-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/qcom_aoss.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c index a59bb34e5eba..18c856056475 100644 --- a/drivers/soc/qcom/qcom_aoss.c +++ b/drivers/soc/qcom/qcom_aoss.c @@ -399,8 +399,10 @@ static int qmp_cooling_devices_register(struct qmp *qmp) continue; ret = qmp_cooling_device_add(qmp, &qmp->cooling_devs[count++], child); - if (ret) + if (ret) { + of_node_put(child); goto unroll; + } }
if (!count)
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 7a16ea7f3a5ec0f30b146b058c273b7a9c8ceadf ]
The OCMEM bindings require ranges property.
Fixes: a2cc991ed634 ("ARM: dts: qcom: msm8974: add ocmem node") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Luca Weiss luca@z3ntu.xyz Tested-by: Luca Weiss luca@z3ntu.xyz Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220607171848.535128-7-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-msm8974.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index ce9cb5e4e95d..3c31c95aa6b9 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -1630,6 +1630,7 @@ ocmem@fdd00000 { reg = <0xfdd00000 0x2000>, <0xfec00000 0x180000>; reg-names = "ctrl", "mem"; + ranges = <0 0xfec00000 0x180000>; clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, <&mmcc OCMEMCX_OCMEMNOC_CLK>; clock-names = "core", "iface";
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit e2759fa0676c9a32bbddb9aff955b54bb35066ad ]
The PM8841 temperature sensor has to define thermal-sensor-cells.
Fixes: dab8134ca072 ("ARM: dts: qcom: Add PM8841 functions device nodes") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220608112702.80873-2-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-pm8841.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/qcom-pm8841.dtsi b/arch/arm/boot/dts/qcom-pm8841.dtsi index 2caf71eacb52..b5cdde034d18 100644 --- a/arch/arm/boot/dts/qcom-pm8841.dtsi +++ b/arch/arm/boot/dts/qcom-pm8841.dtsi @@ -24,6 +24,7 @@ temp-alarm@2400 { compatible = "qcom,spmi-temp-alarm"; reg = <0x2400>; interrupts = <4 0x24 0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <0>; }; };
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 54872fea6a5ac967ec2272aea525d1438ac6735a ]
In error case in hisi_lpc_acpi_probe() after calling platform_device_add(), hisi_lpc_acpi_remove() can't release the failed 'pdev', so it will be leak, call platform_device_put() to fix this problem. I'v constructed this error case and tested this patch on D05 board.
Fixes: 99c0228d6ff1 ("HISI LPC: Re-Add ACPI child enumeration support") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Acked-by: John Garry john.garry@huawei.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/hisi_lpc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c index 378f5d62a991..e7eaa8784fee 100644 --- a/drivers/bus/hisi_lpc.c +++ b/drivers/bus/hisi_lpc.c @@ -503,13 +503,13 @@ static int hisi_lpc_acpi_probe(struct device *hostdev) { struct acpi_device *adev = ACPI_COMPANION(hostdev); struct acpi_device *child; + struct platform_device *pdev; int ret;
/* Only consider the children of the host */ list_for_each_entry(child, &adev->children, node) { const char *hid = acpi_device_hid(child); const struct hisi_lpc_acpi_cell *cell; - struct platform_device *pdev; const struct resource *res; bool found = false; int num_res; @@ -571,22 +571,24 @@ static int hisi_lpc_acpi_probe(struct device *hostdev)
ret = platform_device_add_resources(pdev, res, num_res); if (ret) - goto fail; + goto fail_put_device;
ret = platform_device_add_data(pdev, cell->pdata, cell->pdata_size); if (ret) - goto fail; + goto fail_put_device;
ret = platform_device_add(pdev); if (ret) - goto fail; + goto fail_put_device;
acpi_device_set_enumerated(child); }
return 0;
+fail_put_device: + platform_device_put(pdev); fail: hisi_lpc_acpi_remove(hostdev); return ret;
From: Jason A. Donenfeld Jason@zx2c4.com
[ Upstream commit 170b2c350cfcb6f74074e44dd9f916787546db0d ]
A recent commit factored out a series of annoying (unsigned long) casts into a single variable declaration, but made the pointer type a `uintptr_t` rather than the usual `unsigned long`. This patch changes it to be the integer type more typically used by the kernel to represent addresses.
Fixes: 35fb9ae4aa2e ("usercopy: Cast pointer to an integer once") Cc: Matthew Wilcox willy@infradead.org Cc: Uladzislau Rezki urezki@gmail.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Joe Perches joe@perches.com Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20220616143617.449094-1-Jason@zx2c4.com Signed-off-by: Sasha Levin sashal@kernel.org --- mm/usercopy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/usercopy.c b/mm/usercopy.c index 4e1da708699b..c1ee15a98633 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c @@ -161,7 +161,7 @@ static inline void check_bogus_address(const unsigned long ptr, unsigned long n, static inline void check_heap_object(const void *ptr, unsigned long n, bool to_user) { - uintptr_t addr = (uintptr_t)ptr; + unsigned long addr = (unsigned long)ptr; unsigned long offset; struct folio *folio;
On Mon, Aug 15, 2022 at 07:53:22PM +0200, Greg Kroah-Hartman wrote:
From: Jason A. Donenfeld Jason@zx2c4.com
[ Upstream commit 170b2c350cfcb6f74074e44dd9f916787546db0d ]
A recent commit factored out a series of annoying (unsigned long) casts into a single variable declaration, but made the pointer type a `uintptr_t` rather than the usual `unsigned long`. This patch changes it to be the integer type more typically used by the kernel to represent addresses.
Fixes: 35fb9ae4aa2e ("usercopy: Cast pointer to an integer once")
Not sure why this needs to be backported?
Cc: Matthew Wilcox willy@infradead.org Cc: Uladzislau Rezki urezki@gmail.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Joe Perches joe@perches.com Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20220616143617.449094-1-Jason@zx2c4.com Signed-off-by: Sasha Levin sashal@kernel.org
mm/usercopy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/usercopy.c b/mm/usercopy.c index 4e1da708699b..c1ee15a98633 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c @@ -161,7 +161,7 @@ static inline void check_bogus_address(const unsigned long ptr, unsigned long n, static inline void check_heap_object(const void *ptr, unsigned long n, bool to_user) {
- uintptr_t addr = (uintptr_t)ptr;
- unsigned long addr = (unsigned long)ptr; unsigned long offset; struct folio *folio;
2.35.1
On Mon, Aug 15, 2022 at 09:06:21PM +0100, Matthew Wilcox wrote:
On Mon, Aug 15, 2022 at 07:53:22PM +0200, Greg Kroah-Hartman wrote:
From: Jason A. Donenfeld Jason@zx2c4.com
[ Upstream commit 170b2c350cfcb6f74074e44dd9f916787546db0d ]
A recent commit factored out a series of annoying (unsigned long) casts into a single variable declaration, but made the pointer type a `uintptr_t` rather than the usual `unsigned long`. This patch changes it to be the integer type more typically used by the kernel to represent addresses.
Fixes: 35fb9ae4aa2e ("usercopy: Cast pointer to an integer once")
Not sure why this needs to be backported?
Odd, shouldn't be, now dropped.
greg k-h
From: Kees Cook keescook@chromium.org
[ Upstream commit 6a022dd29f2cefbac4895a34e2e1f14b2d12d819 ]
The 64-bit overflow tests will trigger 64-bit division on 32-bit hosts, which is not currently used anywhere in the kernel, and tickles bugs in at least Clang 13 and earlier: https://github.com/ClangBuiltLinux/linux/issues/1636
In reality, there shouldn't be a reason to not build the 64-bit test cases on 32-bit systems, so these #ifdefs can be removed once the minimum Clang version reaches 13.
In the meantime, silence W=1 warnings given by the current code:
../lib/overflow_kunit.c:191:19: warning: 's64_tests' defined but not used [-Wunused-const-variable=] 191 | DEFINE_TEST_ARRAY(s64) = { | ^~~ ../lib/overflow_kunit.c:24:11: note: in definition of macro 'DEFINE_TEST_ARRAY' 24 | } t ## _tests[] | ^ ../lib/overflow_kunit.c:94:19: warning: 'u64_tests' defined but not used [-Wunused-const-variable=] 94 | DEFINE_TEST_ARRAY(u64) = { | ^~~ ../lib/overflow_kunit.c:24:11: note: in definition of macro 'DEFINE_TEST_ARRAY' 24 | } t ## _tests[] | ^
Reported-by: kernel test robot lkp@intel.com Link: https://lore.kernel.org/lkml/202205110324.7GrtxG8u-lkp@intel.com Fixes: 455a35a6cdb6 ("lib: add runtime test of check_*_overflow functions") Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Nick Desaulniers ndesaulniers@google.com Cc: Vitor Massaru Iha vitor@massaru.org Cc: "Gustavo A. R. Silva" gustavoars@kernel.org Tested-by: Daniel Latypov dlatypov@google.com Link: https://lore.kernel.org/lkml/CAGS_qxokQAjQRip2vPi80toW7hmBnXf=KMTNT51B1wuDqS... Signed-off-by: Kees Cook keescook@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/overflow_kunit.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/lib/overflow_kunit.c b/lib/overflow_kunit.c index 475f0c064bf6..7e3e43679b73 100644 --- a/lib/overflow_kunit.c +++ b/lib/overflow_kunit.c @@ -91,6 +91,7 @@ DEFINE_TEST_ARRAY(u32) = { {-4U, 5U, 1U, -9U, -20U, true, false, true}, };
+#if BITS_PER_LONG == 64 DEFINE_TEST_ARRAY(u64) = { {0, 0, 0, 0, 0, false, false, false}, {1, 1, 2, 0, 1, false, false, false}, @@ -114,6 +115,7 @@ DEFINE_TEST_ARRAY(u64) = { false, true, false}, {-15ULL, 10ULL, -5ULL, -25ULL, -150ULL, false, false, true}, }; +#endif
DEFINE_TEST_ARRAY(s8) = { {0, 0, 0, 0, 0, false, false, false}, @@ -188,6 +190,8 @@ DEFINE_TEST_ARRAY(s32) = { {S32_MIN, S32_MIN, 0, 0, 0, true, false, true}, {S32_MAX, S32_MAX, -2, 0, 1, true, false, true}, }; + +#if BITS_PER_LONG == 64 DEFINE_TEST_ARRAY(s64) = { {0, 0, 0, 0, 0, false, false, false},
@@ -216,6 +220,7 @@ DEFINE_TEST_ARRAY(s64) = { {-128, -1, -129, -127, 128, false, false, false}, {0, -S64_MAX, -S64_MAX, S64_MAX, 0, false, false, false}, }; +#endif
#define check_one_op(t, fmt, op, sym, a, b, r, of) do { \ t _r; \ @@ -650,6 +655,7 @@ static struct kunit_case overflow_test_cases[] = { KUNIT_CASE(s16_overflow_test), KUNIT_CASE(u32_overflow_test), KUNIT_CASE(s32_overflow_test), +/* Clang 13 and earlier generate unwanted libcalls on 32-bit. */ #if BITS_PER_LONG == 64 KUNIT_CASE(u64_overflow_test), KUNIT_CASE(s64_overflow_test),
From: GONG, Ruiqi gongruiqi1@huawei.com
[ Upstream commit 375561bd6195a31bf4c109732bd538cb97a941f4 ]
Fix the following Sparse warnings that got noticed when the PPC-dev patchwork was checking another patch (see the link below):
init/main.c:862:1: warning: symbol 'randomize_kstack_offset' was not declared. Should it be static? init/main.c:864:1: warning: symbol 'kstack_offset' was not declared. Should it be static?
Which in fact are triggered on all architectures that have HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET support (for instances x86, arm64 etc).
Link: https://lore.kernel.org/lkml/e7b0d68b-914d-7283-827c-101988923929@huawei.com... Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Xiu Jianfeng xiujianfeng@huawei.com Signed-off-by: GONG, Ruiqi gongruiqi1@huawei.com Reviewed-by: Christophe Leroy christophe.leroy@csgroup.eu Fixes: 39218ff4c625 ("stack: Optionally randomize kernel stack offset each syscall") Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20220629060423.2515693-1-gongruiqi1@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- init/main.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/init/main.c b/init/main.c index 0ee39cdcfcac..91642a4e69be 100644 --- a/init/main.c +++ b/init/main.c @@ -99,6 +99,7 @@ #include <linux/kcsan.h> #include <linux/init_syscalls.h> #include <linux/stackdepot.h> +#include <linux/randomize_kstack.h> #include <net/net_namespace.h>
#include <asm/io.h>
From: Sireesh Kodali sireeshkodali1@gmail.com
[ Upstream commit 5458d6f2827cd30218570f266b8d238417461f2f ]
The smem-state properties for the pronto node were incorrectly labelled, reading `qcom,state*` rather than `qcom,smem-state*`. Fix that, allowing the stop state to be used.
Fixes: 88106096cbf8 ("ARM: dts: msm8916: Add and enable wcnss node") Signed-off-by: Sireesh Kodali sireeshkodali1@gmail.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220526141740.15834-3-sireeshkodali1@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 05472510e29d..15c91fb59dba 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -1788,8 +1788,8 @@ pronto: remoteproc@a21b000 { <&rpmpd MSM8916_VDDMX>; power-domain-names = "cx", "mx";
- qcom,state = <&wcnss_smp2p_out 0>; - qcom,state-names = "stop"; + qcom,smem-states = <&wcnss_smp2p_out 0>; + qcom,smem-state-names = "stop";
pinctrl-names = "default"; pinctrl-0 = <&wcnss_pin_a>;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 07f3c7a11dadbead580b6d6e7d86bcc87119fe74 ]
The OCMEM bindings require ranges property.
Fixes: 9d511d0a7926 ("arm64: dts: qcom: msm8994: Add OCMEM node") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220607171848.535128-14-krzysztof.kozlowski@linar... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8994.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi index 1ac2913b182c..8cc3cb79ed05 100644 --- a/arch/arm64/boot/dts/qcom/msm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi @@ -1074,6 +1074,7 @@ ocmem: ocmem@fdd00000 { reg = <0xfdd00000 0x2000>, <0xfec00000 0x200000>; reg-names = "ctrl", "mem"; + ranges = <0 0xfec00000 0x200000>; clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, <&mmcc OCMEMCX_OCMEMNOC_CLK>; clock-names = "core", "iface";
From: Kan Liang kan.liang@linux.intel.com
[ Upstream commit 39a41278f041e4b7ee6c83caefac845c9b19fc61 ]
The PEBS memory access latency encoding for the e-core is slightly different from the p-core. The bit 4 is Lock, while the bit 5 is TLB access.
Add a new flag to indicate the load/store latency event on a hybrid platform. Add a new function pointer to retrieve the latency data for a hybrid platform. Only implement the new flag and function for the e-core on ADL. Still use the existing PERF_X86_EVENT_PEBS_LDLAT/STLAT flag for the p-core on ADL.
Factor out pebs_set_tlb_lock() to set the generic memory data source information of the TLB access and lock for both load and store latency.
Move the intel_get_event_constraints() to ahead of the :ppp check, otherwise the new flag never gets a chance to be set for the :ppp events.
Fixes: f83d2f91d259 ("perf/x86/intel: Add Alder Lake Hybrid support") Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Andi Kleen ak@linux.intel.com Link: https://lkml.kernel.org/r/20220629150840.2235741-1-kan.liang@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/intel/core.c | 5 ++- arch/x86/events/intel/ds.c | 80 ++++++++++++++++++++++-------------- arch/x86/events/perf_event.h | 8 ++++ 3 files changed, 60 insertions(+), 33 deletions(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 45024abd929f..07d4a5f20321 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -4141,6 +4141,8 @@ tnt_get_event_constraints(struct cpu_hw_events *cpuc, int idx, { struct event_constraint *c;
+ c = intel_get_event_constraints(cpuc, idx, event); + /* * :ppp means to do reduced skid PEBS, * which is available on PMC0 and fixed counter 0. @@ -4153,8 +4155,6 @@ tnt_get_event_constraints(struct cpu_hw_events *cpuc, int idx, return &counter0_constraint; }
- c = intel_get_event_constraints(cpuc, idx, event); - return c; }
@@ -6242,6 +6242,7 @@ __init int intel_pmu_init(void) x86_pmu.flags |= PMU_FL_MEM_LOADS_AUX; x86_pmu.lbr_pt_coexist = true; intel_pmu_pebs_data_source_skl(false); + x86_pmu.pebs_latency_data = adl_latency_data_small; x86_pmu.num_topdown_events = 8; x86_pmu.update_topdown_event = adl_update_topdown_event; x86_pmu.set_topdown_event_period = adl_set_topdown_event_period; diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index 376cc3d66094..de84385de414 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -171,6 +171,49 @@ static u64 precise_datala_hsw(struct perf_event *event, u64 status) return dse.val; }
+static inline void pebs_set_tlb_lock(u64 *val, bool tlb, bool lock) +{ + /* + * TLB access + * 0 = did not miss 2nd level TLB + * 1 = missed 2nd level TLB + */ + if (tlb) + *val |= P(TLB, MISS) | P(TLB, L2); + else + *val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2); + + /* locked prefix */ + if (lock) + *val |= P(LOCK, LOCKED); +} + +/* Retrieve the latency data for e-core of ADL */ +u64 adl_latency_data_small(struct perf_event *event, u64 status) +{ + union intel_x86_pebs_dse dse; + u64 val; + + WARN_ON_ONCE(hybrid_pmu(event->pmu)->cpu_type == hybrid_big); + + dse.val = status; + + val = pebs_data_source[dse.ld_dse]; + + /* + * For the atom core on ADL, + * bit 4: lock, bit 5: TLB access. + */ + pebs_set_tlb_lock(&val, dse.ld_locked, dse.ld_stlb_miss); + + if (dse.ld_data_blk) + val |= P(BLK, DATA); + else + val |= P(BLK, NA); + + return val; +} + static u64 load_latency_data(u64 status) { union intel_x86_pebs_dse dse; @@ -190,21 +233,8 @@ static u64 load_latency_data(u64 status) val |= P(TLB, NA) | P(LOCK, NA); return val; } - /* - * bit 4: TLB access - * 0 = did not miss 2nd level TLB - * 1 = missed 2nd level TLB - */ - if (dse.ld_stlb_miss) - val |= P(TLB, MISS) | P(TLB, L2); - else - val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2);
- /* - * bit 5: locked prefix - */ - if (dse.ld_locked) - val |= P(LOCK, LOCKED); + pebs_set_tlb_lock(&val, dse.ld_stlb_miss, dse.ld_locked);
/* * Ice Lake and earlier models do not support block infos. @@ -245,21 +275,7 @@ static u64 store_latency_data(u64 status) */ val = pebs_data_source[dse.st_lat_dse];
- /* - * bit 4: TLB access - * 0 = did not miss 2nd level TLB - * 1 = missed 2nd level TLB - */ - if (dse.st_lat_stlb_miss) - val |= P(TLB, MISS) | P(TLB, L2); - else - val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2); - - /* - * bit 5: locked prefix - */ - if (dse.st_lat_locked) - val |= P(LOCK, LOCKED); + pebs_set_tlb_lock(&val, dse.st_lat_stlb_miss, dse.st_lat_locked);
val |= P(BLK, NA);
@@ -781,8 +797,8 @@ struct event_constraint intel_glm_pebs_event_constraints[] = {
struct event_constraint intel_grt_pebs_event_constraints[] = { /* Allow all events as PEBS with no flags */ - INTEL_PLD_CONSTRAINT(0x5d0, 0xf), - INTEL_PSD_CONSTRAINT(0x6d0, 0xf), + INTEL_HYBRID_LAT_CONSTRAINT(0x5d0, 0xf), + INTEL_HYBRID_LAT_CONSTRAINT(0x6d0, 0xf), EVENT_CONSTRAINT_END };
@@ -1446,6 +1462,8 @@ static u64 get_data_src(struct perf_event *event, u64 aux) val = load_latency_data(aux); else if (fl & PERF_X86_EVENT_PEBS_STLAT) val = store_latency_data(aux); + else if (fl & PERF_X86_EVENT_PEBS_LAT_HYBRID) + val = x86_pmu.pebs_latency_data(event, aux); else if (fst && (fl & PERF_X86_EVENT_PEBS_HSW_PREC)) val = precise_datala_hsw(event, aux); else if (fst) diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 21a5482bcf84..ff6dd189739e 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -84,6 +84,7 @@ static inline bool constraint_match(struct event_constraint *c, u64 ecode) #define PERF_X86_EVENT_TOPDOWN 0x04000 /* Count Topdown slots/metrics events */ #define PERF_X86_EVENT_PEBS_STLAT 0x08000 /* st+stlat data address sampling */ #define PERF_X86_EVENT_AMD_BRS 0x10000 /* AMD Branch Sampling */ +#define PERF_X86_EVENT_PEBS_LAT_HYBRID 0x20000 /* ld and st lat for hybrid */
static inline bool is_topdown_count(struct perf_event *event) { @@ -460,6 +461,10 @@ struct cpu_hw_events { __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST)
+#define INTEL_HYBRID_LAT_CONSTRAINT(c, n) \ + __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \ + HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LAT_HYBRID) + /* Event constraint, but match on all event flags too. */ #define INTEL_FLAGS_EVENT_CONSTRAINT(c, n) \ EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS) @@ -825,6 +830,7 @@ struct x86_pmu { void (*drain_pebs)(struct pt_regs *regs, struct perf_sample_data *data); struct event_constraint *pebs_constraints; void (*pebs_aliases)(struct perf_event *event); + u64 (*pebs_latency_data)(struct perf_event *event, u64 status); unsigned long large_pebs_flags; u64 rtm_abort_event;
@@ -1392,6 +1398,8 @@ void intel_pmu_disable_bts(void);
int intel_pmu_drain_bts_buffer(void);
+u64 adl_latency_data_small(struct perf_event *event, u64 status); + extern struct event_constraint intel_core2_pebs_event_constraints[];
extern struct event_constraint intel_atom_pebs_event_constraints[];
From: Kan Liang kan.liang@linux.intel.com
[ Upstream commit ccf170e9d8fdacfe435bbe3749c897c7d86d32f8 ]
The PEBS data source encoding for the e-core is different from the p-core.
Add the pebs_data_source[] in the struct x86_hybrid_pmu to store the data source encoding for each type of the core.
Add intel_pmu_pebs_data_source_grt() for the e-core. There is nothing changed for the data source encoding of the p-core, which still reuse the intel_pmu_pebs_data_source_skl().
Fixes: f83d2f91d259 ("perf/x86/intel: Add Alder Lake Hybrid support") Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Andi Kleen ak@linux.intel.com Link: https://lkml.kernel.org/r/20220629150840.2235741-2-kan.liang@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/intel/core.c | 2 +- arch/x86/events/intel/ds.c | 51 +++++++++++++++++++++++++++--------- arch/x86/events/perf_event.h | 6 +++++ 3 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 07d4a5f20321..bd8b98857609 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -6241,7 +6241,7 @@ __init int intel_pmu_init(void) x86_pmu.flags |= PMU_FL_INSTR_LATENCY; x86_pmu.flags |= PMU_FL_MEM_LOADS_AUX; x86_pmu.lbr_pt_coexist = true; - intel_pmu_pebs_data_source_skl(false); + intel_pmu_pebs_data_source_adl(); x86_pmu.pebs_latency_data = adl_latency_data_small; x86_pmu.num_topdown_events = 8; x86_pmu.update_topdown_event = adl_update_topdown_event; diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index de84385de414..ba60427caa6d 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -94,15 +94,40 @@ void __init intel_pmu_pebs_data_source_nhm(void) pebs_data_source[0x07] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM); }
-void __init intel_pmu_pebs_data_source_skl(bool pmem) +static void __init __intel_pmu_pebs_data_source_skl(bool pmem, u64 *data_source) { u64 pmem_or_l4 = pmem ? LEVEL(PMEM) : LEVEL(L4);
- pebs_data_source[0x08] = OP_LH | pmem_or_l4 | P(SNOOP, HIT); - pebs_data_source[0x09] = OP_LH | pmem_or_l4 | REM | P(SNOOP, HIT); - pebs_data_source[0x0b] = OP_LH | LEVEL(RAM) | REM | P(SNOOP, NONE); - pebs_data_source[0x0c] = OP_LH | LEVEL(ANY_CACHE) | REM | P(SNOOPX, FWD); - pebs_data_source[0x0d] = OP_LH | LEVEL(ANY_CACHE) | REM | P(SNOOP, HITM); + data_source[0x08] = OP_LH | pmem_or_l4 | P(SNOOP, HIT); + data_source[0x09] = OP_LH | pmem_or_l4 | REM | P(SNOOP, HIT); + data_source[0x0b] = OP_LH | LEVEL(RAM) | REM | P(SNOOP, NONE); + data_source[0x0c] = OP_LH | LEVEL(ANY_CACHE) | REM | P(SNOOPX, FWD); + data_source[0x0d] = OP_LH | LEVEL(ANY_CACHE) | REM | P(SNOOP, HITM); +} + +void __init intel_pmu_pebs_data_source_skl(bool pmem) +{ + __intel_pmu_pebs_data_source_skl(pmem, pebs_data_source); +} + +static void __init intel_pmu_pebs_data_source_grt(u64 *data_source) +{ + data_source[0x05] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT); + data_source[0x06] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM); + data_source[0x08] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOPX, FWD); +} + +void __init intel_pmu_pebs_data_source_adl(void) +{ + u64 *data_source; + + data_source = x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX].pebs_data_source; + memcpy(data_source, pebs_data_source, sizeof(pebs_data_source)); + __intel_pmu_pebs_data_source_skl(false, data_source); + + data_source = x86_pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX].pebs_data_source; + memcpy(data_source, pebs_data_source, sizeof(pebs_data_source)); + intel_pmu_pebs_data_source_grt(data_source); }
static u64 precise_store_data(u64 status) @@ -198,7 +223,7 @@ u64 adl_latency_data_small(struct perf_event *event, u64 status)
dse.val = status;
- val = pebs_data_source[dse.ld_dse]; + val = hybrid_var(event->pmu, pebs_data_source)[dse.ld_dse];
/* * For the atom core on ADL, @@ -214,7 +239,7 @@ u64 adl_latency_data_small(struct perf_event *event, u64 status) return val; }
-static u64 load_latency_data(u64 status) +static u64 load_latency_data(struct perf_event *event, u64 status) { union intel_x86_pebs_dse dse; u64 val; @@ -224,7 +249,7 @@ static u64 load_latency_data(u64 status) /* * use the mapping table for bit 0-3 */ - val = pebs_data_source[dse.ld_dse]; + val = hybrid_var(event->pmu, pebs_data_source)[dse.ld_dse];
/* * Nehalem models do not support TLB, Lock infos @@ -263,7 +288,7 @@ static u64 load_latency_data(u64 status) return val; }
-static u64 store_latency_data(u64 status) +static u64 store_latency_data(struct perf_event *event, u64 status) { union intel_x86_pebs_dse dse; u64 val; @@ -273,7 +298,7 @@ static u64 store_latency_data(u64 status) /* * use the mapping table for bit 0-3 */ - val = pebs_data_source[dse.st_lat_dse]; + val = hybrid_var(event->pmu, pebs_data_source)[dse.st_lat_dse];
pebs_set_tlb_lock(&val, dse.st_lat_stlb_miss, dse.st_lat_locked);
@@ -1459,9 +1484,9 @@ static u64 get_data_src(struct perf_event *event, u64 aux) bool fst = fl & (PERF_X86_EVENT_PEBS_ST | PERF_X86_EVENT_PEBS_HSW_PREC);
if (fl & PERF_X86_EVENT_PEBS_LDLAT) - val = load_latency_data(aux); + val = load_latency_data(event, aux); else if (fl & PERF_X86_EVENT_PEBS_STLAT) - val = store_latency_data(aux); + val = store_latency_data(event, aux); else if (fl & PERF_X86_EVENT_PEBS_LAT_HYBRID) val = x86_pmu.pebs_latency_data(event, aux); else if (fst && (fl & PERF_X86_EVENT_PEBS_HSW_PREC)) diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index ff6dd189739e..821098aebf78 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -643,6 +643,8 @@ enum { x86_lbr_exclusive_max, };
+#define PERF_PEBS_DATA_SOURCE_MAX 0x10 + struct x86_hybrid_pmu { struct pmu pmu; const char *name; @@ -670,6 +672,8 @@ struct x86_hybrid_pmu { unsigned int late_ack :1, mid_ack :1, enabled_ack :1; + + u64 pebs_data_source[PERF_PEBS_DATA_SOURCE_MAX]; };
static __always_inline struct x86_hybrid_pmu *hybrid_pmu(struct pmu *pmu) @@ -1507,6 +1511,8 @@ void intel_pmu_pebs_data_source_nhm(void);
void intel_pmu_pebs_data_source_skl(bool pmem);
+void intel_pmu_pebs_data_source_adl(void); + int intel_pmu_setup_lbr_filter(struct perf_event *event);
void intel_pt_interrupt(void);
From: Chanho Park chanho61.park@samsung.com
[ Upstream commit ba205449828f47f80532a1453beef5eed2982176 ]
They should be started with "gpp5-".
Fixes: 31bbac5263aa ("arm64: dts: exynos: add initial support for exynosautov9 SoC") Signed-off-by: Chanho Park chanho61.park@samsung.com Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220627005832.8709-1-chanho61.park@samsung.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi index ef0349d1c3d0..68f4a0fae7cf 100644 --- a/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi +++ b/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi @@ -1089,21 +1089,21 @@ spi10_cs_func: spi10-cs-func-pins {
/* PERIC1 USI11_SPI */ spi11_bus: spi11-pins { - samsung,pins = "gpp3-6", "gpp3-5", "gpp3-4"; + samsung,pins = "gpp5-6", "gpp5-5", "gpp5-4"; samsung,pin-function = <EXYNOS_PIN_FUNC_2>; samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>; };
spi11_cs: spi11-cs-pins { - samsung,pins = "gpp3-7"; + samsung,pins = "gpp5-7"; samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>; };
spi11_cs_func: spi11-cs-func-pins { - samsung,pins = "gpp3-7"; + samsung,pins = "gpp5-7"; samsung,pin-function = <EXYNOS_PIN_FUNC_2>; samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
From: Eric Auger eric.auger@redhat.com
[ Upstream commit 3dcb861dbc6ab101838a1548b1efddd00ca3c3ec ]
Currently acpi_viot_init() gets called after the pci device has been scanned and pci_enable_acs() has been called. So pci_request_acs() fails to be taken into account leading to wrong single iommu group topologies when dealing with multi-function root ports for instance.
We cannot simply move the acpi_viot_init() earlier, similarly as the IORT init because the VIOT parsing relies on the pci scan. However we can detect VIOT is present earlier and in such a case, request ACS. Introduce a new acpi_viot_early_init() routine that allows to call pci_request_acs() before the scan.
While at it, guard the call to pci_request_acs() with #ifdef CONFIG_PCI.
Fixes: 3cf485540e7b ("ACPI: Add driver for the VIOT table") Signed-off-by: Eric Auger eric.auger@redhat.com Reported-by: Jin Liu jinl@redhat.com Reviewed-by: Jean-Philippe Brucker jean-philippe@linaro.org Tested-by: Jean-Philippe Brucker jean-philippe@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/bus.c | 1 + drivers/acpi/viot.c | 26 ++++++++++++++++++++------ include/linux/acpi_viot.h | 2 ++ 3 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index e2db1bdd9dd2..1d36bb684f5c 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1399,6 +1399,7 @@ static int __init acpi_init(void)
pci_mmcfg_late_init(); acpi_iort_init(); + acpi_viot_early_init(); acpi_hest_init(); acpi_ghes_init(); acpi_scan_init(); diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c index d2256326c73a..647f11cf165d 100644 --- a/drivers/acpi/viot.c +++ b/drivers/acpi/viot.c @@ -248,6 +248,26 @@ static int __init viot_parse_node(const struct acpi_viot_header *hdr) return ret; }
+/** + * acpi_viot_early_init - Test the presence of VIOT and enable ACS + * + * If the VIOT does exist, ACS must be enabled. This cannot be + * done in acpi_viot_init() which is called after the bus scan + */ +void __init acpi_viot_early_init(void) +{ +#ifdef CONFIG_PCI + acpi_status status; + struct acpi_table_header *hdr; + + status = acpi_get_table(ACPI_SIG_VIOT, 0, &hdr); + if (ACPI_FAILURE(status)) + return; + pci_request_acs(); + acpi_put_table(hdr); +#endif +} + /** * acpi_viot_init - Parse the VIOT table * @@ -319,12 +339,6 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data) epid = ((domain_nr - ep->segment_start) << 16) + dev_id - ep->bdf_start + ep->endpoint_id;
- /* - * If we found a PCI range managed by the viommu, we're - * the one that has to request ACS. - */ - pci_request_acs(); - return viot_dev_iommu_init(&pdev->dev, ep->viommu, epid); } diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h index 1eb8ee5b0e5f..a5a122431563 100644 --- a/include/linux/acpi_viot.h +++ b/include/linux/acpi_viot.h @@ -6,9 +6,11 @@ #include <linux/acpi.h>
#ifdef CONFIG_ACPI_VIOT +void __init acpi_viot_early_init(void); void __init acpi_viot_init(void); int viot_iommu_configure(struct device *dev); #else +static inline void acpi_viot_early_init(void) {} static inline void acpi_viot_init(void) {} static inline int viot_iommu_configure(struct device *dev) {
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 566a2d6d8e429727832c7e347cbe736b12ad7297 ]
Add the missing platform_device_unregister() before return from virt_platform_init() in the error handling case.
Fixes: 05d51e42df06 ("m68k: Introduce a virtual m68k machine") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Laurent Vivier laurent@vivier.eu Link: https://lore.kernel.org/r/20220628084903.3147123-1-yangyingliang@huawei.com Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/m68k/virt/platform.c | 58 ++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 25 deletions(-)
diff --git a/arch/m68k/virt/platform.c b/arch/m68k/virt/platform.c index cb820f19a221..1560c4140ab9 100644 --- a/arch/m68k/virt/platform.c +++ b/arch/m68k/virt/platform.c @@ -8,20 +8,15 @@
#define VIRTIO_BUS_NB 128
-static int __init virt_virtio_init(unsigned int id) +static struct platform_device * __init virt_virtio_init(unsigned int id) { const struct resource res[] = { DEFINE_RES_MEM(virt_bi_data.virtio.mmio + id * 0x200, 0x200), DEFINE_RES_IRQ(virt_bi_data.virtio.irq + id), }; - struct platform_device *pdev;
- pdev = platform_device_register_simple("virtio-mmio", id, + return platform_device_register_simple("virtio-mmio", id, res, ARRAY_SIZE(res)); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - return 0; }
static int __init virt_platform_init(void) @@ -35,8 +30,10 @@ static int __init virt_platform_init(void) DEFINE_RES_MEM(virt_bi_data.rtc.mmio + 0x1000, 0x1000), DEFINE_RES_IRQ(virt_bi_data.rtc.irq + 1), }; - struct platform_device *pdev; + struct platform_device *pdev1, *pdev2; + struct platform_device *pdevs[VIRTIO_BUS_NB]; unsigned int i; + int ret = 0;
if (!MACH_IS_VIRT) return -ENODEV; @@ -44,29 +41,40 @@ static int __init virt_platform_init(void) /* We need this to have DMA'able memory provided to goldfish-tty */ min_low_pfn = 0;
- pdev = platform_device_register_simple("goldfish_tty", - PLATFORM_DEVID_NONE, - goldfish_tty_res, - ARRAY_SIZE(goldfish_tty_res)); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); + pdev1 = platform_device_register_simple("goldfish_tty", + PLATFORM_DEVID_NONE, + goldfish_tty_res, + ARRAY_SIZE(goldfish_tty_res)); + if (IS_ERR(pdev1)) + return PTR_ERR(pdev1);
- pdev = platform_device_register_simple("goldfish_rtc", - PLATFORM_DEVID_NONE, - goldfish_rtc_res, - ARRAY_SIZE(goldfish_rtc_res)); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); + pdev2 = platform_device_register_simple("goldfish_rtc", + PLATFORM_DEVID_NONE, + goldfish_rtc_res, + ARRAY_SIZE(goldfish_rtc_res)); + if (IS_ERR(pdev2)) { + ret = PTR_ERR(pdev2); + goto err_unregister_tty; + }
for (i = 0; i < VIRTIO_BUS_NB; i++) { - int err; - - err = virt_virtio_init(i); - if (err) - return err; + pdevs[i] = virt_virtio_init(i); + if (IS_ERR(pdevs[i])) { + ret = PTR_ERR(pdevs[i]); + goto err_unregister_rtc_virtio; + } }
return 0; + +err_unregister_rtc_virtio: + while (i > 0) + platform_device_unregister(pdevs[--i]); + platform_device_unregister(pdev2); +err_unregister_tty: + platform_device_unregister(pdev1); + + return ret; }
arch_initcall(virt_platform_init);
From: Marijn Suijten marijn.suijten@somainline.org
[ Upstream commit 6990640a93ba4e76dd62ca3ea1082a7354db09d7 ]
Both the sdc2-on and sdc2-off pinctrl nodes are used by the sdhci@4784000 node in sm6125.dtsi. Surprisingly sdc2-off is defined in sm6125, yet its sdc2-on counterpart is only defined in board-specific DT for the Sony Seine PDX201 board/device resulting in an "undefined label &sdc2_state_on" error if sm6125.dtsi were included elsewhere. This sm6125 base dtsi should not rely on externally defined labels; the properties referencing it should then also be written externally. Since the sdc2-on pin configuration is board-independent just like sdc2-off, move it from seine-pdx201.dts into sm6125.dtsi.
The SDCard-detect pin (gpio98) is however board-specific, and remains as an overwrite in seine-pdx201.dts for both the on and off state.
As a drive-by cleanup, reorder bias- and drive-strength properties.
Fixes: cff4bbaf2a2d ("arm64: dts: qcom: Add support for SM6125") Fixes: 82e1783890b7 ("arm64: dts: qcom: sm6125: Add support for Sony Xperia 10II") Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220508100336.127176-1-marijn.suijten@somainline.... Signed-off-by: Sasha Levin sashal@kernel.org --- .../qcom/sm6125-sony-xperia-seine-pdx201.dts | 34 +++++-------------- arch/arm64/boot/dts/qcom/sm6125.dtsi | 24 +++++++++++-- 2 files changed, 30 insertions(+), 28 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts index 871ccbba445b..4916e6c8b625 100644 --- a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts +++ b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts @@ -91,8 +91,16 @@ &hsusb_phy1 { &sdc2_state_off { sd-cd { pins = "gpio98"; + drive-strength = <2>; bias-disable; + }; +}; + +&sdc2_state_on { + sd-cd { + pins = "gpio98"; drive-strength = <2>; + bias-pull-up; }; };
@@ -102,32 +110,6 @@ &sdhc_1 {
&tlmm { gpio-reserved-ranges = <22 2>, <28 6>; - - sdc2_state_on: sdc2-on { - clk { - pins = "sdc2_clk"; - bias-disable; - drive-strength = <16>; - }; - - cmd { - pins = "sdc2_cmd"; - bias-pull-up; - drive-strength = <10>; - }; - - data { - pins = "sdc2_data"; - bias-pull-up; - drive-strength = <10>; - }; - - sd-cd { - pins = "gpio98"; - bias-pull-up; - drive-strength = <2>; - }; - }; };
&usb3 { diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi index 135e6e0da27a..a0d8580739c5 100644 --- a/arch/arm64/boot/dts/qcom/sm6125.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi @@ -389,20 +389,40 @@ tlmm: pinctrl@500000 { sdc2_state_off: sdc2-off { clk { pins = "sdc2_clk"; - bias-disable; drive-strength = <2>; + bias-disable; };
cmd { pins = "sdc2_cmd"; + drive-strength = <2>; bias-pull-up; + }; + + data { + pins = "sdc2_data"; drive-strength = <2>; + bias-pull-up; + }; + }; + + sdc2_state_on: sdc2-on { + clk { + pins = "sdc2_clk"; + drive-strength = <16>; + bias-disable; + }; + + cmd { + pins = "sdc2_cmd"; + drive-strength = <10>; + bias-pull-up; };
data { pins = "sdc2_data"; + drive-strength = <10>; bias-pull-up; - drive-strength = <2>; }; }; };
From: Marijn Suijten marijn.suijten@somainline.org
[ Upstream commit cbfb5668aece448877fa7826cde81c9d06f4a4ac ]
According to qcom,sm6125-pinctrl.yaml all nodes inside the tlmm must be suffixed by -state:
qcom/sm6125-sony-xperia-seine-pdx201.dtb: pinctrl@500000: 'sdc2-off', 'sdc2-on' do not match any of the regexes: '-state$', 'pinctrl-[0-9]+'
The label names have been updated to match, going from sdc2_state_X to sdc2_X_state.
Fixes: cff4bbaf2a2d ("arm64: dts: qcom: Add support for SM6125") Fixes: 82e1783890b7 ("arm64: dts: qcom: sm6125: Add support for Sony Xperia 10II") Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220508100336.127176-2-marijn.suijten@somainline.... Signed-off-by: Sasha Levin sashal@kernel.org --- .../boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts | 4 ++-- arch/arm64/boot/dts/qcom/sm6125.dtsi | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts index 4916e6c8b625..038970c0b68e 100644 --- a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts +++ b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts @@ -88,7 +88,7 @@ &hsusb_phy1 { status = "okay"; };
-&sdc2_state_off { +&sdc2_off_state { sd-cd { pins = "gpio98"; drive-strength = <2>; @@ -96,7 +96,7 @@ sd-cd { }; };
-&sdc2_state_on { +&sdc2_on_state { sd-cd { pins = "gpio98"; drive-strength = <2>; diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi index a0d8580739c5..5ee1e4b20301 100644 --- a/arch/arm64/boot/dts/qcom/sm6125.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi @@ -386,7 +386,7 @@ tlmm: pinctrl@500000 { interrupt-controller; #interrupt-cells = <2>;
- sdc2_state_off: sdc2-off { + sdc2_off_state: sdc2-off-state { clk { pins = "sdc2_clk"; drive-strength = <2>; @@ -406,7 +406,7 @@ data { }; };
- sdc2_state_on: sdc2-on { + sdc2_on_state: sdc2-on-state { clk { pins = "sdc2_clk"; drive-strength = <16>; @@ -490,8 +490,8 @@ sdhc_2: sdhci@4784000 { <&xo_board>; clock-names = "iface", "core", "xo";
- pinctrl-0 = <&sdc2_state_on>; - pinctrl-1 = <&sdc2_state_off>; + pinctrl-0 = <&sdc2_on_state>; + pinctrl-1 = <&sdc2_off_state>; pinctrl-names = "default", "sleep";
power-domains = <&rpmpd SM6125_VDDCX>;
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit b874fff9a7683df30e5aff16d5a85b1f8a43aa5d ]
The commit 82d61e19fccb ("arm64: dts: qcom: msm8996: Move '#clock-cells' to QMP PHY child node") moved the '#clock-cells' properties to the child nodes. However it missed the fact that the property must have been set to <0> (as all pipe clocks use of_clk_hw_simple_get as the xlate function. Also the mentioned commit didn't add '#clock-cells' properties to second and third PCIe PHY nodes. Correct both these mistakes:
- Set '#clock-cells' to <0>, - Add the property to pciephy_1 and pciephy_2 nodes.
Fixes: 82d61e19fccb ("arm64: dts: qcom: msm8996: Move '#clock-cells' to QMP PHY child node") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220620071936.1558906-3-dmitry.baryshkov@linaro.o... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 9932186f7ceb..b670d0412760 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -609,7 +609,7 @@ pciephy_0: phy@35000 { <0x00035400 0x1dc>; #phy-cells = <0>;
- #clock-cells = <1>; + #clock-cells = <0>; clock-output-names = "pcie_0_pipe_clk_src"; clocks = <&gcc GCC_PCIE_0_PIPE_CLK>; clock-names = "pipe0"; @@ -623,6 +623,7 @@ pciephy_1: phy@36000 { <0x00036400 0x1dc>; #phy-cells = <0>;
+ #clock-cells = <0>; clock-output-names = "pcie_1_pipe_clk_src"; clocks = <&gcc GCC_PCIE_1_PIPE_CLK>; clock-names = "pipe1"; @@ -636,6 +637,7 @@ pciephy_2: phy@37000 { <0x00037400 0x1dc>; #phy-cells = <0>;
+ #clock-cells = <0>; clock-output-names = "pcie_2_pipe_clk_src"; clocks = <&gcc GCC_PCIE_2_PIPE_CLK>; clock-names = "pipe2"; @@ -2769,7 +2771,7 @@ ssusb_phy_0: phy@7410200 { <0x07410600 0x1a8>; #phy-cells = <0>;
- #clock-cells = <1>; + #clock-cells = <0>; clock-output-names = "usb3_phy_pipe_clk_src"; clocks = <&gcc GCC_USB3_PHY_PIPE_CLK>; clock-names = "pipe0";
From: Johan Hovold johan+linaro@kernel.org
[ Upstream commit 531c738fb36069d60aff267a0b25533a35d59fd0 ]
The QMP PCIe PHY provides a single clock so drop the redundant clock index.
Signed-off-by: Johan Hovold johan+linaro@kernel.org Fixes: bd7d507935ca ("arm64: dts: qcom: sc7280: Add pcie clock support") Fixes: 92e0ee9f83b3 ("arm64: dts: qcom: sc7280: Add PCIe and PHY related nodes") Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220705114032.22787-2-johan+linaro@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sc7280.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index d22405658f13..116b3e0abe93 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -818,7 +818,7 @@ gcc: clock-controller@100000 { reg = <0 0x00100000 0 0x1f0000>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>, - <0>, <&pcie1_lane 0>, + <0>, <&pcie1_lane>, <0>, <0>, <0>, <0>; clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", "pcie_0_pipe_clk", "pcie_1_pipe_clk", @@ -2110,7 +2110,7 @@ pcie1_lane: phy@1c0e200 { clock-names = "pipe0";
#phy-cells = <0>; - #clock-cells = <1>; + #clock-cells = <0>; clock-output-names = "pcie_1_pipe_clk"; }; };
From: Johan Hovold johan+linaro@kernel.org
[ Upstream commit d9fd162ce764c227fcfd4242f6c1639895a9481f ]
Add the missing '#clock-cells' properties to the PCIe QMP PHY nodes.
Signed-off-by: Johan Hovold johan+linaro@kernel.org Fixes: e53bdfc00977 ("arm64: dts: qcom: sm8250: Add PCIe support") Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220705114032.22787-3-johan+linaro@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8250.dtsi | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index d0760e6ec942..e8cdca50bc83 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -1884,6 +1884,8 @@ pcie0_lane: phy@1c06200 { clock-names = "pipe0";
#phy-cells = <0>; + + #clock-cells = <0>; clock-output-names = "pcie_0_pipe_clk"; }; }; @@ -1990,6 +1992,8 @@ pcie1_lane: phy@1c0e200 { clock-names = "pipe0";
#phy-cells = <0>; + + #clock-cells = <0>; clock-output-names = "pcie_1_pipe_clk"; }; }; @@ -2096,6 +2100,8 @@ pcie2_lane: phy@1c16200 { clock-names = "pipe0";
#phy-cells = <0>; + + #clock-cells = <0>; clock-output-names = "pcie_2_pipe_clk"; }; };
From: Nick Hainke vincent@systemli.org
[ Upstream commit c98e6e683632386a3bd284acda4342e68aec4c41 ]
The bananapi R64 (BPI-R64) experiences wrong WPS button signals. In OpenWrt pushing the WPS button while powering on the device will set it to recovery mode. Currently, this also happens without any user interaction. In particular, the wrong signals appear while booting the device or restarting it, e.g. after doing a system upgrade. If the device is in recovery mode the user needs to manually power cycle or restart it.
The official BPI-R64 sources set the WPS button to GPIO_ACTIVE_LOW in the device tree. This setting seems to suppress the unwanted WPS button press signals. So this commit changes the button from GPIO_ACTIVE_HIGH to GPIO_ACTIVE_LOW.
The official BPI-R64 sources can be found on https://github.com/BPI-SINOVOIP/BPI-R64-openwrt
Fixes: 0b6286dd96c0 ("arm64: dts: mt7622: add bananapi BPI-R64 board")
Suggested-by: INAGAKI Hiroshi musashino.open@gmail.com Signed-off-by: Nick Hainke vincent@systemli.org Link: https://lore.kernel.org/r/20220630111746.4098-1-vincent@systemli.org Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts index 2b9bf8dd14ec..7538918c7a82 100644 --- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts @@ -49,7 +49,7 @@ factory { wps { label = "wps"; linux,code = <KEY_WPS_BUTTON>; - gpios = <&pio 102 GPIO_ACTIVE_HIGH>; + gpios = <&pio 102 GPIO_ACTIVE_LOW>; }; };
From: Mikko Perttunen mperttunen@nvidia.com
[ Upstream commit 61192a9d8a6367ae1b8234876941b037910a2459 ]
The Tegra SYSRAM contains regions access to which is restricted to certain hardware blocks on the system, and speculative accesses to those will cause issues.
Patch 'misc: sram: Only map reserved areas in Tegra SYSRAM' attempted to resolve this by only mapping the regions specified in the device tree on the assumption that there are no such restricted areas within the 64K-aligned area of memory that contains the memory we wish to map.
Turns out this assumption is wrong, as there are such areas above the 4K pages described in the device trees. As such, we need to use the bigger hammer that is no-memory-wc, which causes the memory to be mapped as Device memory to which speculative accesses are disallowed.
As such, the previous patch in the series, 'firmware: tegra: bpmp: do only aligned access to IPC memory area', is required with this patch to make the BPMP driver only issue aligned memory accesses as those are also required with Device memory.
Fixes: fec29bf04994 ("misc: sram: Only map reserved areas in Tegra SYSRAM") Signed-off-by: Mikko Perttunen mperttunen@nvidia.com Reviewed-by: Yousaf Kaukab ykaukab@suse.de Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/nvidia/tegra186.dtsi | 1 + arch/arm64/boot/dts/nvidia/tegra194.dtsi | 1 + arch/arm64/boot/dts/nvidia/tegra234.dtsi | 1 + 3 files changed, 3 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 0e9afc3e2f26..9eca18b54698 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -1820,6 +1820,7 @@ sram@30000000 { #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x0 0x30000000 0x50000>; + no-memory-wc;
cpu_bpmp_tx: sram@4e000 { reg = <0x4e000 0x1000>; diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi index d1f8248c00f4..3fdb0b852718 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -2684,6 +2684,7 @@ sram@40000000 { #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x0 0x40000000 0x50000>; + no-memory-wc;
cpu_bpmp_tx: sram@4e000 { reg = <0x4e000 0x1000>; diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi index cb3af539e477..0213a7e3dad0 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi @@ -1325,6 +1325,7 @@ sram@40000000 { #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x0 0x40000000 0x80000>; + no-memory-wc;
cpu_bpmp_tx: sram@70000 { reg = <0x70000 0x1000>;
From: Tamás Szűcs tszucs@protonmail.ch
[ Upstream commit b415bb7c976f1d595ed752001c0938f702645dab ]
Hook SDMMC1 CD up with CVM GPIO02 (SOC_GPIO11) used for card detection on J4 (uSD socket) on the carrier.
Fixes: ef633bfc21e9 ("arm64: tegra: Enable card detect for SD card on P2888") Signed-off-by: Tamás Szűcs tszucs@protonmail.ch Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi index a7d7cfd66379..b0f9393dd39c 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi @@ -75,7 +75,7 @@ eeprom@50 {
/* SDMMC1 (SD/MMC) */ mmc@3400000 { - cd-gpios = <&gpio TEGRA194_MAIN_GPIO(A, 0) GPIO_ACTIVE_LOW>; + cd-gpios = <&gpio TEGRA194_MAIN_GPIO(G, 7) GPIO_ACTIVE_LOW>; };
/* SDMMC4 (eMMC) */
From: Johan Hovold johan+linaro@kernel.org
[ Upstream commit 330fc08dbdd913ac37a31f8aec1a88f68e39ae39 ]
The recent commit that dropped the PCIe PHY clock index failed to update the PCIe node reference.
Fixes: 531c738fb360 ("arm64: dts: qcom: sc7280: drop PCIe PHY clock index") Reported-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Johan Hovold johan+linaro@kernel.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220707064222.15717-1-johan+linaro@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sc7280.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index 116b3e0abe93..75e174316d00 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -2035,7 +2035,7 @@ pcie1: pci@1c08000 {
clocks = <&gcc GCC_PCIE_1_PIPE_CLK>, <&gcc GCC_PCIE_1_PIPE_CLK_SRC>, - <&pcie1_lane 0>, + <&pcie1_lane>, <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_PCIE_1_AUX_CLK>, <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
From: Yuwen Chen chenyuwen1@meizu.com
[ Upstream commit 2df7c4bd7c1d2bc5ece5e9ed19dbd386810c2a65 ]
When the user mounts the erofs second times, the decompression thread may hung. The problem happens due to a sequence of steps like the following:
1) Task A called z_erofs_load_lzma_config which obtain all of the node from the z_erofs_lzma_head.
2) At this time, task B called the z_erofs_lzma_decompress and wanted to get a node. But the z_erofs_lzma_head was empty, the Task B had to sleep.
3) Task A release nodes and push nodes into the z_erofs_lzma_head. But task B was still sleeping.
One example report when the hung happens: task:kworker/u3:1 state:D stack:14384 pid: 86 ppid: 2 flags:0x00004000 Workqueue: erofs_unzipd z_erofs_decompressqueue_work Call Trace: <TASK> __schedule+0x281/0x760 schedule+0x49/0xb0 z_erofs_lzma_decompress+0x4bc/0x580 ? cpu_core_flags+0x10/0x10 z_erofs_decompress_pcluster+0x49b/0xba0 ? __update_load_avg_se+0x2b0/0x330 ? __update_load_avg_se+0x2b0/0x330 ? update_load_avg+0x5f/0x690 ? update_load_avg+0x5f/0x690 ? set_next_entity+0xbd/0x110 ? _raw_spin_unlock+0xd/0x20 z_erofs_decompress_queue.isra.0+0x2e/0x50 z_erofs_decompressqueue_work+0x30/0x60 process_one_work+0x1d3/0x3a0 worker_thread+0x45/0x3a0 ? process_one_work+0x3a0/0x3a0 kthread+0xe2/0x110 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x22/0x30 </TASK>
Signed-off-by: Yuwen Chen chenyuwen1@meizu.com Fixes: 622ceaddb764 ("erofs: lzma compression support") Reviewed-by: Gao Xiang hsiangkao@linux.alibaba.com Link: https://lore.kernel.org/r/20220626224041.4288-1-chenyuwen1@meizu.com Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/erofs/decompressor_lzma.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c index 05a3063cf2bc..5e59b3f523eb 100644 --- a/fs/erofs/decompressor_lzma.c +++ b/fs/erofs/decompressor_lzma.c @@ -143,6 +143,7 @@ int z_erofs_load_lzma_config(struct super_block *sb, DBG_BUGON(z_erofs_lzma_head); z_erofs_lzma_head = head; spin_unlock(&z_erofs_lzma_lock); + wake_up_all(&z_erofs_lzma_wq);
z_erofs_lzma_max_dictsize = dict_size; mutex_unlock(&lzma_resize_mutex);
From: Gao Xiang hsiangkao@linux.alibaba.com
[ Upstream commit 448b5a1548d87c246c3d0c3df8480d3c6eb6c11a ]
Currently, vmap()s are avoided if physical addresses are consecutive for decompressed buffers.
I observed that is very common for 4KiB pclusters since the numbers of decompressed pages are almost 2 or 3.
However, such detection doesn't work for Highmem pages on 32-bit machines, let's fix it now.
Reported-by: Liu Jinbao liujinbao1@xiaomi.com Fixes: 7fc45dbc938a ("staging: erofs: introduce generic decompression backend") Link: https://lore.kernel.org/r/20220708101001.21242-1-hsiangkao@linux.alibaba.com Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/erofs/decompressor.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c index 6dca1900c733..45be8f4aeb68 100644 --- a/fs/erofs/decompressor.c +++ b/fs/erofs/decompressor.c @@ -91,14 +91,18 @@ static int z_erofs_lz4_prepare_dstpages(struct z_erofs_lz4_decompress_ctx *ctx,
if (page) { __clear_bit(j, bounced); - if (kaddr) { - if (kaddr + PAGE_SIZE == page_address(page)) + if (!PageHighMem(page)) { + if (!i) { + kaddr = page_address(page); + continue; + } + if (kaddr && + kaddr + PAGE_SIZE == page_address(page)) { kaddr += PAGE_SIZE; - else - kaddr = NULL; - } else if (!i) { - kaddr = page_address(page); + continue; + } } + kaddr = NULL; continue; } kaddr = NULL;
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 9c22ec4ac27bcc5a54dd406da168f403327a5b55 ]
If the controller is not available, it might be in the future and we would like to re-probe the peripheral again. For that purpose return deferred probe.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215993 Fixes: 87e59b36e5e2 ("spi: Support selection of the index of the ACPI Spi Resource before alloc") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20220709212956.25530-1-andriy.shevchenko@linux.int... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index ea09d1b42bf6..62aa3f062f3d 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2398,7 +2398,7 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data)
ctlr = acpi_spi_find_controller_by_adev(adev); if (!ctlr) - return -ENODEV; + return -EPROBE_DEFER;
lookup->ctlr = ctlr; }
From: Ming Lei ming.lei@redhat.com
[ Upstream commit f3ec5d11554778c24ac8915e847223ed71d104fc ]
blk_mq_debugfs_register_hctx() can be called by blk_mq_update_nr_hw_queues when gendisk isn't added yet, such as nvme tcp.
Fixes the warning of 'debugfs: Directory 'hctx0' with parent '/' already present!' which can be observed reliably when running blktests nvme/005.
Fixes: 6cfc0081b046 ("blk-mq: no need to check return value of debugfs_create functions") Reported-by: Yi Zhang yi.zhang@redhat.com Signed-off-by: Ming Lei ming.lei@redhat.com Tested-by: Yi Zhang yi.zhang@redhat.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220711090808.259682-1-ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-mq-debugfs.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index 4d1ce9ef4318..61f179e5f151 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c @@ -730,6 +730,9 @@ void blk_mq_debugfs_register_hctx(struct request_queue *q, char name[20]; int i;
+ if (!q->debugfs_dir) + return; + snprintf(name, sizeof(name), "hctx%u", hctx->queue_num); hctx->debugfs_dir = debugfs_create_dir(name, q->debugfs_dir);
From: Nandhini Srikandan nandhini.srikandan@intel.com
[ Upstream commit 5d76b7509cb223e94ff73a672273e58f1957ac68 ]
Add the missing underscore in IP version macro to avoid compilation issue. The macro is used for IP version comparison in the current patchset.
Fixes: 2cc8d9227bbb ("spi: dw: Introduce Synopsys IP-core versions interface") Signed-off-by: Nandhini Srikandan nandhini.srikandan@intel.com Acked-by: Serge Semin fancer.lancer@gmail.com Link: https://lore.kernel.org/r/20220713042223.1458-2-nandhini.srikandan@intel.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-dw.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index d5ee5130601e..79d853f6d192 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -23,7 +23,7 @@ ((_dws)->ip == DW_ ## _ip ## _ID)
#define __dw_spi_ver_cmp(_dws, _ip, _ver, _op) \ - (dw_spi_ip_is(_dws, _ip) && (_dws)->ver _op DW_ ## _ip ## _ver) + (dw_spi_ip_is(_dws, _ip) && (_dws)->ver _op DW_ ## _ip ## _ ## _ver)
#define dw_spi_ver_is(_dws, _ip, _ver) __dw_spi_ver_cmp(_dws, _ip, _ver, ==)
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 43cc5a0afe4184a7fafe1eba32b5a11bb69c9ce0 ]
This reverts commit 59ebbe40fb51 ("spi: simplify devm_spi_register_controller").
If devm_add_action() fails in devm_add_action_or_reset(), devm_spi_unregister() will be called, it decreases the refcount of 'ctlr->dev' to 0, then it will cause uaf in the drivers that calling spi_put_controller() in error path.
Fixes: 59ebbe40fb51 ("spi: simplify devm_spi_register_controller") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Conor Dooley conor.dooley@microchip.com Link: https://lore.kernel.org/r/20220712135504.1055688-1-yangyingliang@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 62aa3f062f3d..2c616024f7c0 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3050,9 +3050,9 @@ int spi_register_controller(struct spi_controller *ctlr) } EXPORT_SYMBOL_GPL(spi_register_controller);
-static void devm_spi_unregister(void *ctlr) +static void devm_spi_unregister(struct device *dev, void *res) { - spi_unregister_controller(ctlr); + spi_unregister_controller(*(struct spi_controller **)res); }
/** @@ -3071,13 +3071,22 @@ static void devm_spi_unregister(void *ctlr) int devm_spi_register_controller(struct device *dev, struct spi_controller *ctlr) { + struct spi_controller **ptr; int ret;
+ ptr = devres_alloc(devm_spi_unregister, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return -ENOMEM; + ret = spi_register_controller(ctlr); - if (ret) - return ret; + if (!ret) { + *ptr = ctlr; + devres_add(dev, ptr); + } else { + devres_free(ptr); + }
- return devm_add_action_or_reset(dev, devm_spi_unregister, ctlr); + return ret; } EXPORT_SYMBOL_GPL(devm_spi_register_controller);
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 7e9984d183bb1e99e766c5c2b950ff21f7f7b6c0 ]
After calling spi_unregister_master(), the refcount of master will be decrease to 0, and it will be freed in spi_controller_release(), the device data also will be freed, so it will lead a UAF when using 'tspi'. To fix this, get the master before unregister and put it when finish using it.
Fixes: 26c863418221 ("spi: tegra20-slink: Don't use resource-managed spi_register helper") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20220713094024.1508869-1-yangyingliang@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-tegra20-slink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index 38360434d6e9..148043d0c2b8 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -1136,7 +1136,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
static int tegra_slink_remove(struct platform_device *pdev) { - struct spi_master *master = platform_get_drvdata(pdev); + struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); struct tegra_slink_data *tspi = spi_master_get_devdata(master);
spi_unregister_master(master); @@ -1151,6 +1151,7 @@ static int tegra_slink_remove(struct platform_device *pdev) if (tspi->rx_dma_chan) tegra_slink_deinit_dma_param(tspi, true);
+ spi_master_put(master); return 0; }
From: Armin Wolf W_Armin@gmx.de
[ Upstream commit fd2d53c367ae9983c2100ac733a834e0c79d7537 ]
Some devices like the Fujitsu Celsius W380 do contain a working sch56xx hardware monitoring device, but do not contain the necessary DMI onboard device.
Do not check for the presence of an suitable onboard device on these machines. The list of affected machines was created using data collected by the Linux Hardware Project.
Tested on a Fujitsu Esprimo P720, but sadly not on a affected machine.
Fixes: 393935baa45e (hwmon: (sch56xx-common) Add automatic module loading on supported devices) Signed-off-by: Armin Wolf W_Armin@gmx.de Reviewed-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20220604220200.2567-1-W_Armin@gmx.de Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/sch56xx-common.c | 44 ++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-)
diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c index 3ece53adabd6..de3a0886c2f7 100644 --- a/drivers/hwmon/sch56xx-common.c +++ b/drivers/hwmon/sch56xx-common.c @@ -523,6 +523,28 @@ static int __init sch56xx_device_add(int address, const char *name) return PTR_ERR_OR_ZERO(sch56xx_pdev); }
+static const struct dmi_system_id sch56xx_dmi_override_table[] __initconst = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS W380"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO P710"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO E9900"), + }, + }, + { } +}; + /* For autoloading only */ static const struct dmi_system_id sch56xx_dmi_table[] __initconst = { { @@ -543,16 +565,18 @@ static int __init sch56xx_init(void) if (!dmi_check_system(sch56xx_dmi_table)) return -ENODEV;
- /* - * Some machines like the Esprimo P720 and Esprimo C700 have - * onboard devices named " Antiope"/" Theseus" instead of - * "Antiope"/"Theseus", so we need to check for both. - */ - if (!dmi_find_device(DMI_DEV_TYPE_OTHER, "Antiope", NULL) && - !dmi_find_device(DMI_DEV_TYPE_OTHER, " Antiope", NULL) && - !dmi_find_device(DMI_DEV_TYPE_OTHER, "Theseus", NULL) && - !dmi_find_device(DMI_DEV_TYPE_OTHER, " Theseus", NULL)) - return -ENODEV; + if (!dmi_check_system(sch56xx_dmi_override_table)) { + /* + * Some machines like the Esprimo P720 and Esprimo C700 have + * onboard devices named " Antiope"/" Theseus" instead of + * "Antiope"/"Theseus", so we need to check for both. + */ + if (!dmi_find_device(DMI_DEV_TYPE_OTHER, "Antiope", NULL) && + !dmi_find_device(DMI_DEV_TYPE_OTHER, " Antiope", NULL) && + !dmi_find_device(DMI_DEV_TYPE_OTHER, "Theseus", NULL) && + !dmi_find_device(DMI_DEV_TYPE_OTHER, " Theseus", NULL)) + return -ENODEV; + } }
/*
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit 5918036cfa8ded7aa8094db70295011ce2275447 ]
Adding a MODULE_ALIAS() to drivetemp will make the driver easier for modprobe to autoprobe.
Signed-off-by: Linus Walleij linus.walleij@linaro.org Link: https://lore.kernel.org/r/20220712214624.1845158-1-linus.walleij@linaro.org Fixes: 5b46903d8bf3 ("hwmon: Driver for disk and solid state drives with temperature sensors") Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/drivetemp.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/hwmon/drivetemp.c b/drivers/hwmon/drivetemp.c index 1eb37106a220..5bac2b0fc7bb 100644 --- a/drivers/hwmon/drivetemp.c +++ b/drivers/hwmon/drivetemp.c @@ -621,3 +621,4 @@ module_exit(drivetemp_exit); MODULE_AUTHOR("Guenter Roeck linus@roeck-us.net"); MODULE_DESCRIPTION("Hard drive temperature monitor"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:drivetemp");
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 22c80aac882f712897b88b7ea8f5a74ea19019df ]
Trace the remapped operation and its flags instead of only the data direction of remapped operations. This issue was detected by analyzing the warnings reported by sparse related to the new blk_opf_t type.
Reviewed-by: Jun'ichi Nomura junichi.nomura@nec.com Cc: Mike Snitzer snitzer@kernel.org Cc: Mike Christie michael.christie@oracle.com Cc: Li Zefan lizf@cn.fujitsu.com Cc: Chaitanya Kulkarni kch@nvidia.com Fixes: 1b9a9ab78b0a ("blktrace: use op accessors") Signed-off-by: Bart Van Assche bvanassche@acm.org Link: https://lore.kernel.org/r/20220714180729.1065367-11-bvanassche@acm.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/trace/blktrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index fe04c6f96ca5..b334c033cee7 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -1058,7 +1058,7 @@ static void blk_add_trace_rq_remap(void *ignore, struct request *rq, dev_t dev, r.sector_from = cpu_to_be64(from);
__blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), - rq_data_dir(rq), 0, BLK_TA_REMAP, 0, + req_op(rq), rq->cmd_flags, BLK_TA_REMAP, 0, sizeof(r), &r, blk_trace_request_get_cgid(rq)); rcu_read_unlock(); }
From: Hsin-Yi Wang hsinyi@chromium.org
[ Upstream commit 37101d3c719386040ded735a5ec06974f1d94d1f ]
Both genpd_debug_add() and genpd_debug_remove() may be called indirectly by other drivers while genpd_debugfs_dir is not yet set. For example, drivers can call pm_genpd_init() in probe or pm_genpd_init() in probe fail/cleanup path:
pm_genpd_init() --> genpd_debug_add()
pm_genpd_remove() --> genpd_remove() --> genpd_debug_remove()
At this time, genpd_debug_init() may not yet be called.
genpd_debug_add() checks that if genpd_debugfs_dir is NULL, it will return directly. Make sure this is also checked in pm_genpd_remove(), otherwise components under debugfs root which has the same name as other components under pm_genpd may be accidentally removed, since NULL represents debugfs root.
Fixes: 718072ceb211 ("PM: domains: create debugfs nodes when adding power domains") Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-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 | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 739e52cd4aba..55a10e6d4e2a 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -222,6 +222,9 @@ static void genpd_debug_remove(struct generic_pm_domain *genpd) { struct dentry *d;
+ if (!genpd_debugfs_dir) + return; + d = debugfs_lookup(genpd->name, genpd_debugfs_dir); debugfs_remove(d); }
From: Mikulas Patocka mpatocka@redhat.com
[ Upstream commit 9bc0c92e4b82adb017026dbb2aa816b1ac2bef31 ]
The functions writecache_map_remap_origin and writecache_bio_copy_ssd only return a single value, thus they can be made to return void.
This helps simplify the following IO accounting changes.
Signed-off-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/dm-writecache.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index d74c5a7a0ab4..e4753e8c46d3 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -1329,8 +1329,8 @@ enum wc_map_op { WC_MAP_ERROR, };
-static enum wc_map_op writecache_map_remap_origin(struct dm_writecache *wc, struct bio *bio, - struct wc_entry *e) +static void writecache_map_remap_origin(struct dm_writecache *wc, struct bio *bio, + struct wc_entry *e) { if (e) { sector_t next_boundary = @@ -1338,8 +1338,6 @@ static enum wc_map_op writecache_map_remap_origin(struct dm_writecache *wc, stru if (next_boundary < bio->bi_iter.bi_size >> SECTOR_SHIFT) dm_accept_partial_bio(bio, next_boundary); } - - return WC_MAP_REMAP_ORIGIN; }
static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio *bio) @@ -1366,14 +1364,15 @@ static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio * map_op = WC_MAP_REMAP; } } else { - map_op = writecache_map_remap_origin(wc, bio, e); + writecache_map_remap_origin(wc, bio, e); + map_op = WC_MAP_REMAP_ORIGIN; }
return map_op; }
-static enum wc_map_op writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio, - struct wc_entry *e, bool search_used) +static void writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio, + struct wc_entry *e, bool search_used) { unsigned bio_size = wc->block_size; sector_t start_cache_sec = cache_sector(wc, e); @@ -1419,8 +1418,6 @@ static enum wc_map_op writecache_bio_copy_ssd(struct dm_writecache *wc, struct b } else { writecache_schedule_autocommit(wc); } - - return WC_MAP_REMAP; }
static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio *bio) @@ -1458,7 +1455,8 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio direct_write: wc->stats.writes_around++; e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING); - return writecache_map_remap_origin(wc, bio, e); + writecache_map_remap_origin(wc, bio, e); + return WC_MAP_REMAP_ORIGIN; } wc->stats.writes_blocked_on_freelist++; writecache_wait_on_freelist(wc); @@ -1469,10 +1467,12 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio wc->uncommitted_blocks++; wc->stats.writes_allocate++; bio_copy: - if (WC_MODE_PMEM(wc)) + if (WC_MODE_PMEM(wc)) { bio_copy_block(wc, bio, memory_data(wc, e)); - else - return writecache_bio_copy_ssd(wc, bio, e, search_used); + } else { + writecache_bio_copy_ssd(wc, bio, e, search_used); + return WC_MAP_REMAP; + } } while (bio->bi_iter.bi_size);
if (unlikely(bio->bi_opf & REQ_FUA || wc->uncommitted_blocks >= wc->autocommit_blocks))
From: Mikulas Patocka mpatocka@redhat.com
[ Upstream commit 2c6e755b49d273243431f5f1184654e71221fc78 ]
Change dm-writecache, so that it counts the number of blocks read instead of the number of read bios. Bios can be split and requeued using the dm_accept_partial_bio function, so counting bios caused inaccurate results.
Fixes: e3a35d03407c ("dm writecache: add event counters") Reported-by: Yu Kuai yukuai1@huaweicloud.com Signed-off-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/admin-guide/device-mapper/writecache.rst | 4 ++-- drivers/md/dm-writecache.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/device-mapper/writecache.rst b/Documentation/admin-guide/device-mapper/writecache.rst index 10429779a91a..7bead3b52690 100644 --- a/Documentation/admin-guide/device-mapper/writecache.rst +++ b/Documentation/admin-guide/device-mapper/writecache.rst @@ -78,8 +78,8 @@ Status: 2. the number of blocks 3. the number of free blocks 4. the number of blocks under writeback -5. the number of read requests -6. the number of read requests that hit the cache +5. the number of read blocks +6. the number of read blocks that hit the cache 7. the number of write requests 8. the number of write requests that hit uncommitted block 9. the number of write requests that hit committed block diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index e4753e8c46d3..b71efe08d809 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -1365,6 +1365,7 @@ static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio * } } else { writecache_map_remap_origin(wc, bio, e); + wc->stats.reads += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits; map_op = WC_MAP_REMAP_ORIGIN; }
From: Mikulas Patocka mpatocka@redhat.com
[ Upstream commit b2676e1482af89714af6988ce5d31a84692e2530 ]
Change dm-writecache, so that it counts the number of blocks written instead of the number of write bios. Bios can be split and requeued using the dm_accept_partial_bio function, so counting bios caused inaccurate results.
Fixes: e3a35d03407c ("dm writecache: add event counters") Reported-by: Yu Kuai yukuai1@huaweicloud.com Signed-off-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../admin-guide/device-mapper/writecache.rst | 10 +++++----- drivers/md/dm-writecache.c | 12 +++++++++--- 2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/Documentation/admin-guide/device-mapper/writecache.rst b/Documentation/admin-guide/device-mapper/writecache.rst index 7bead3b52690..6c9a2c74df8a 100644 --- a/Documentation/admin-guide/device-mapper/writecache.rst +++ b/Documentation/admin-guide/device-mapper/writecache.rst @@ -80,11 +80,11 @@ Status: 4. the number of blocks under writeback 5. the number of read blocks 6. the number of read blocks that hit the cache -7. the number of write requests -8. the number of write requests that hit uncommitted block -9. the number of write requests that hit committed block -10. the number of write requests that bypass the cache -11. the number of write requests that are allocated in the cache +7. the number of write blocks +8. the number of write blocks that hit uncommitted block +9. the number of write blocks that hit committed block +10. the number of write blocks that bypass the cache +11. the number of write blocks that are allocated in the cache 12. the number of write requests that are blocked on the freelist 13. the number of flush requests 14. the number of discard requests diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index b71efe08d809..d1dca8f44028 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -1413,6 +1413,9 @@ static void writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio, bio->bi_iter.bi_sector = start_cache_sec; dm_accept_partial_bio(bio, bio_size >> SECTOR_SHIFT);
+ wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits; + wc->stats.writes_allocate += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits; + if (unlikely(wc->uncommitted_blocks >= wc->autocommit_blocks)) { wc->uncommitted_blocks = 0; queue_work(wc->writeback_wq, &wc->flush_work); @@ -1428,9 +1431,10 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio do { bool found_entry = false; bool search_used = false; - wc->stats.writes++; - if (writecache_has_error(wc)) + if (writecache_has_error(wc)) { + wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits; return WC_MAP_ERROR; + } e = writecache_find_entry(wc, bio->bi_iter.bi_sector, 0); if (e) { if (!writecache_entry_is_committed(wc, e)) { @@ -1454,9 +1458,10 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio if (unlikely(!e)) { if (!WC_MODE_PMEM(wc) && !found_entry) { direct_write: - wc->stats.writes_around++; e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING); writecache_map_remap_origin(wc, bio, e); + wc->stats.writes_around += bio->bi_iter.bi_size >> wc->block_size_bits; + wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits; return WC_MAP_REMAP_ORIGIN; } wc->stats.writes_blocked_on_freelist++; @@ -1470,6 +1475,7 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio bio_copy: if (WC_MODE_PMEM(wc)) { bio_copy_block(wc, bio, memory_data(wc, e)); + wc->stats.writes++; } else { writecache_bio_copy_ssd(wc, bio, e, search_used); return WC_MAP_REMAP;
From: Mikulas Patocka mpatocka@redhat.com
[ Upstream commit 2ee73ef60db4d79b9f9b8cd501e8188b5179449f ]
Change dm-writecache, so that it counts the number of blocks discarded instead of the number of discard bios. Make it consistent with the read and write statistics counters that were changed to count the number of blocks instead of bios.
Fixes: e3a35d03407c ("dm writecache: add event counters") Signed-off-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/admin-guide/device-mapper/writecache.rst | 2 +- drivers/md/dm-writecache.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/device-mapper/writecache.rst b/Documentation/admin-guide/device-mapper/writecache.rst index 6c9a2c74df8a..724e028d1858 100644 --- a/Documentation/admin-guide/device-mapper/writecache.rst +++ b/Documentation/admin-guide/device-mapper/writecache.rst @@ -87,7 +87,7 @@ Status: 11. the number of write blocks that are allocated in the cache 12. the number of write requests that are blocked on the freelist 13. the number of flush requests -14. the number of discard requests +14. the number of discarded blocks
Messages: flush diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index d1dca8f44028..b4d5bab8d68b 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -1514,7 +1514,7 @@ static enum wc_map_op writecache_map_flush(struct dm_writecache *wc, struct bio
static enum wc_map_op writecache_map_discard(struct dm_writecache *wc, struct bio *bio) { - wc->stats.discards++; + wc->stats.discards += bio->bi_iter.bi_size >> wc->block_size_bits;
if (writecache_has_error(wc)) return WC_MAP_ERROR;
From: Liang He windhl@126.com
[ Upstream commit 66efb665cd5ad69b27dca8571bf89fc6b9c628a4 ]
We should call the of_node_put() for the reference returned by of_get_child_by_name() which has increased the refcount.
Fixes: 40e20d68bb3f ("regulator: of: Add support for parsing regulator_state for suspend state") Signed-off-by: Liang He windhl@126.com Link: https://lore.kernel.org/r/20220715111027.391032-1-windhl@126.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/of_regulator.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index f54d4f176882..e12b681c72e5 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -264,8 +264,12 @@ static int of_get_regulation_constraints(struct device *dev, }
suspend_np = of_get_child_by_name(np, regulator_states[i]); - if (!suspend_np || !suspend_state) + if (!suspend_np) continue; + if (!suspend_state) { + of_node_put(suspend_np); + continue; + }
if (!of_property_read_u32(suspend_np, "regulator-mode", &pval)) {
From: Konrad Dybcio konrad.dybcio@somainline.org
[ Upstream commit a6232f2aa99ce470799992e99e0012945bb5308f ]
QCOM_RPMPD requires PM_GENERIC_DOMAINS/_OF, which in turns requires CONFIG_PM. I forgot about the latter in my earlier patch (it's still in -next as of the time of committing, hence no Fixes: tag). Fix it.
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220707212158.32684-1-konrad.dybcio@somainline.or... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index e718b8735444..4472fb22ba04 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -129,6 +129,7 @@ config QCOM_RPMHPD
config QCOM_RPMPD tristate "Qualcomm RPM Power domain driver" + depends on PM depends on QCOM_SMD_RPM help QCOM RPM Power domain driver to support power-domains with
From: Parikshit Pareek quic_ppareek@quicinc.com
[ Upstream commit 5bed21af0005cc7d8bb05d2c4a63afbcede23382 ]
Change the id of SA8540P to its correct value, i.e., 461. Also, map the id 460 to its correct values, i.e. SA8295P.
Fixes: 76ee15ae1b13 ("soc: qcom: socinfo: Add some more PMICs and SoCs") Signed-off-by: Parikshit Pareek quic_ppareek@quicinc.com Reviewed-by: Eric Chanudet echanude@redhat.com Tested-by: Eric Chanudet echanude@redhat.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220711083957.12091-1-quic_ppareek@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/socinfo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index cee579a267a6..3af195b8583a 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -328,7 +328,8 @@ static const struct soc_id soc_id[] = { { 455, "QRB5165" }, { 457, "SM8450" }, { 459, "SM7225" }, - { 460, "SA8540P" }, + { 460, "SA8295P" }, + { 461, "SA8540P" }, { 480, "SM8450" }, { 482, "SM8450" }, { 487, "SC7280" },
From: Marijn Suijten marijn.suijten@somainline.org
[ Upstream commit 2aa54fa87cca1fa43870a9caf4fcce00eb087fa5 ]
These voltages are not a multiple of the given step-size 8000 (with base voltage 1664000) in pm8998_pldo, resulting in PLDO regulators l18 and l22 failing to validate and in turn not probing the rpm-pm8998-regulator driver:
l18: unsupportable voltage constraints 2856000-2848000uV qcom_rpm_smd_regulator rpm-glink:rpm-requests:pm8998-regulators: l18: devm_regulator_register() failed, ret=-22
Round the voltages down for the sake of erring on the safe side, leaving a comment in place to document this discrepancy wrt downstream sources.
Fixes: 390883af89d2 ("arm64: dts: qcom: msm8998: Introduce support for Sony Yoshino platform") Reported-by: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-by: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220507153627.1478268-1-marijn.suijten@somainline... Signed-off-by: Sasha Levin sashal@kernel.org --- .../dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts index 4a1f98a21031..c21333aa73c2 100644 --- a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts +++ b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts @@ -26,11 +26,13 @@ &lab { };
&vreg_l18a_2p85 { - regulator-min-microvolt = <2850000>; - regulator-max-microvolt = <2850000>; + /* Note: Round-down from 2850000 to be a multiple of PLDO step-size 8000 */ + regulator-min-microvolt = <2848000>; + regulator-max-microvolt = <2848000>; };
&vreg_l22a_2p85 { - regulator-min-microvolt = <2700000>; - regulator-max-microvolt = <2700000>; + /* Note: Round-down from 2700000 to be a multiple of PLDO step-size 8000 */ + regulator-min-microvolt = <2696000>; + regulator-max-microvolt = <2696000>; };
From: Sumit Garg sumit.garg@linaro.org
[ Upstream commit 58577966a42fc0b660b5e2c7c9e5a2241363ea83 ]
Currently the DT for QCS404 SoC has setup for 2 USB2 PHYs with one each assigned to USB3 controller and USB2 controller. This assignment is incorrect which only works by luck: as when each USB HCI comes up it configures the *other* controllers PHY which is enough to make them happy. If, for any reason, we were to disable one of the controllers then both would stop working.
This was a difficult inconsistency to be caught which was found while trying to enable USB support in u-boot. So with all the required drivers ported to u-boot, I couldn't get the same USB storage device enumerated in u-boot which was being enumerated fine by the kernel.
The root cause of the problem came out to be that I wasn't enabling USB2 PHY: "usb2_phy_prim" in u-boot. Then I realised that via simply disabling the same USB2 PHY currently assigned to USB2 host controller in the kernel disabled enumeration for USB3 host controller as well.
So fix this inconsistency by correctly assigning USB2 PHYs.
Fixes: 9375e7d719b3 ("arm64: dts: qcom: qcs404: Add USB devices and PHYs") Signed-off-by: Sumit Garg sumit.garg@linaro.org Reviewed-by: Daniel Thompson daniel.thompson@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220711083038.1518529-1-sumit.garg@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/qcs404.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi index d912166b7552..c8b7d8eb5996 100644 --- a/arch/arm64/boot/dts/qcom/qcs404.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi @@ -548,7 +548,7 @@ usb3_dwc3: usb@7580000 { compatible = "snps,dwc3"; reg = <0x07580000 0xcd00>; interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; - phys = <&usb2_phy_sec>, <&usb3_phy>; + phys = <&usb2_phy_prim>, <&usb3_phy>; phy-names = "usb2-phy", "usb3-phy"; snps,has-lpm-erratum; snps,hird-threshold = /bits/ 8 <0x10>; @@ -577,7 +577,7 @@ usb@78c0000 { compatible = "snps,dwc3"; reg = <0x078c0000 0xcc00>; interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; - phys = <&usb2_phy_prim>; + phys = <&usb2_phy_sec>; phy-names = "usb2-phy"; snps,has-lpm-erratum; snps,hird-threshold = /bits/ 8 <0x10>;
From: Stephan Gerhold stephan.gerhold@kernkonzept.com
[ Upstream commit 8d8be8dd7c1f5d50f84ecc7a6a41962da48c6164 ]
The remoteproc configuration in qcom-msm8974.dtsi is incomplete because it lacks the regulator supplies that should be added in the board DT files. Some of the msm8974 boards are currently missing the regulator supplies and should have the remoteprocs disabled to avoid making use of the incomplete configuration.
This also fixes dtbs_check warnings after moving "qcom,msm8974-mss-pil" to DT schema, which rightfully complains that the -supply properties are missing for some boards:
qcom-apq8074-dragonboard.dtb: remoteproc@fc880000: 'pll-supply' is a required property From schema: remoteproc/qcom,msm8916-mss-pil.yaml remoteproc@fc880000: 'mss-supply' is a required property From schema: remoteproc/qcom,msm8916-mss-pil.yaml remoteproc@fc880000: 'oneOf' conditional failed, one must be fixed: 'power-domains' is a required property 'power-domain-names' is a required property, or 'cx-supply' is a required property 'mx-supply' is a required property
Cc: Luca Weiss luca@z3ntu.xyz Cc: Konrad Dybcio konrad.dybcio@somainline.org Fixes: f300826d27be ("ARM: dts: qcom-msm8974: Sort and clean up nodes") Signed-off-by: Stephan Gerhold stephan.gerhold@kernkonzept.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220712124421.3129206-4-stephan.gerhold@kernkonze... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-msm8974.dtsi | 4 ++++ arch/arm/boot/dts/qcom-msm8974pro-fairphone-fp2.dts | 2 ++ arch/arm/boot/dts/qcom-msm8974pro-samsung-klte.dts | 2 ++ 3 files changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index 3c31c95aa6b9..2d9416d1a6c8 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -1182,6 +1182,8 @@ remoteproc_mss: remoteproc@fc880000 { qcom,smem-states = <&modem_smp2p_out 0>; qcom,smem-state-names = "stop";
+ status = "disabled"; + mba { memory-region = <&mba_region>; }; @@ -1662,6 +1664,8 @@ remoteproc_adsp: remoteproc@fe200000 { qcom,smem-states = <&adsp_smp2p_out 0>; qcom,smem-state-names = "stop";
+ status = "disabled"; + smd-edge { interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
diff --git a/arch/arm/boot/dts/qcom-msm8974pro-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974pro-fairphone-fp2.dts index 58cb2ce1e4df..8a6b8e4de887 100644 --- a/arch/arm/boot/dts/qcom-msm8974pro-fairphone-fp2.dts +++ b/arch/arm/boot/dts/qcom-msm8974pro-fairphone-fp2.dts @@ -147,10 +147,12 @@ wcnss { };
&remoteproc_adsp { + status = "okay"; cx-supply = <&pm8841_s2>; };
&remoteproc_mss { + status = "okay"; cx-supply = <&pm8841_s2>; mss-supply = <&pm8841_s3>; mx-supply = <&pm8841_s1>; diff --git a/arch/arm/boot/dts/qcom-msm8974pro-samsung-klte.dts b/arch/arm/boot/dts/qcom-msm8974pro-samsung-klte.dts index d6b2300a8223..577cbffad010 100644 --- a/arch/arm/boot/dts/qcom-msm8974pro-samsung-klte.dts +++ b/arch/arm/boot/dts/qcom-msm8974pro-samsung-klte.dts @@ -457,10 +457,12 @@ fuelgauge_pin: fuelgauge-int-pin { };
&remoteproc_adsp { + status = "okay"; cx-supply = <&pma8084_s2>; };
&remoteproc_mss { + status = "okay"; cx-supply = <&pma8084_s2>; mss-supply = <&pma8084_s6>; mx-supply = <&pma8084_s1>;
From: Xu Qiang xuqiang36@huawei.com
[ Upstream commit 6f194c99f466147148cc08452718b46664112548 ]
When using a NOMAP domain, __irq_resolve_mapping() doesn't store the Linux IRQ number at the address optionally provided by the caller. While this isn't a huge deal (the returned value is guaranteed to the hwirq that was passed as a parameter), let's honour the letter of the API by writing the expected value.
Fixes: d22558dd0a6c (“irqdomain: Introduce irq_resolve_mapping()”) Signed-off-by: Xu Qiang xuqiang36@huawei.com [maz: commit message] Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220719063641.56541-2-xuqiang36@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/irq/irqdomain.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index d5ce96510549..481abb885d61 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -910,6 +910,8 @@ struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain, data = irq_domain_get_irq_data(domain, hwirq); if (data && data->hwirq == hwirq) desc = irq_data_to_desc(data); + if (irq && desc) + *irq = hwirq; }
return desc;
From: Liang He windhl@126.com
[ Upstream commit 491f10d08fdae10a177edf6af4f43b83b293114b ]
In pmu_sbi_setup_irqs(), we should call of_node_put() for the 'cpu' when breaking out of for_each_of_cput_node() as its refcount will be automatically increased and decreased during the iteration.
Fixes: 4905ec2fb7e6 ("RISC-V: Add sscofpmf extension support") Signed-off-by: Liang He windhl@126.com Reviewed-by: Atish Patra atishp@rivosinc.com Reviewed-by: Andrew Jones ajones@ventanamicro.com Link: https://lore.kernel.org/r/20220715130330.443363-1-windhl@126.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/perf/riscv_pmu_sbi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index bae614c73b14..231d86d3949c 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -682,12 +682,15 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde child = of_get_compatible_child(cpu, "riscv,cpu-intc"); if (!child) { pr_err("Failed to find INTC node\n"); + of_node_put(cpu); return -ENODEV; } domain = irq_find_host(child); of_node_put(child); - if (domain) + if (domain) { + of_node_put(cpu); break; + } } if (!domain) { pr_err("Failed to find INTC IRQ root domain\n");
From: Anshuman Khandual anshuman.khandual@arm.com
[ Upstream commit 92f2b8bafa3d6e89c750e9d301a8b7ab76aaa8b6 ]
The arm_spe_pmu driver will enable SYS_PMSCR_EL1.CX in order to add CONTEXT packets into the traces, if the owner of the perf event runs with required capabilities i.e CAP_PERFMON or CAP_SYS_ADMIN via perfmon_capable() helper.
The value of this bit is computed in the arm_spe_event_to_pmscr() function but the check for capabilities happens in the pmu event init callback i.e arm_spe_pmu_event_init(). This suggests that the value of the CX bit should remain consistent for the duration of the perf session.
However, the function arm_spe_event_to_pmscr() may be called later during the event start callback i.e arm_spe_pmu_start() when the "current" process is not the owner of the perf session, hence the CX bit setting is currently not consistent.
One way to fix this, is by caching the required value of the CX bit during the initialization of the PMU event, so that it remains consistent for the duration of the session. It uses currently unused 'event->hw.flags' element to cache perfmon_capable() value, which can be referred during event start callback to compute SYS_PMSCR_EL1.CX. This ensures consistent availability of context packets in the trace as per event owner capabilities.
Drop BIT(SYS_PMSCR_EL1_CX_SHIFT) check in arm_spe_pmu_event_init(), because now CX bit cannot be set in arm_spe_event_to_pmscr() with perfmon_capable() disabled.
Cc: Will Deacon will@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Alexey Budankov alexey.budankov@linux.intel.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Fixes: d5d9696b0380 ("drivers/perf: Add support for ARMv8.2 Statistical Profiling Extension") Reported-by: German Gomez german.gomez@arm.com Signed-off-by: Anshuman Khandual anshuman.khandual@arm.com Reviewed-by: Suzuki K Poulose suzuki.poulose@arm.com Link: https://lore.kernel.org/r/20220714061302.2715102-1-anshuman.khandual@arm.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/perf/arm_spe_pmu.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c index db670b265897..b65a7d9640e1 100644 --- a/drivers/perf/arm_spe_pmu.c +++ b/drivers/perf/arm_spe_pmu.c @@ -39,6 +39,24 @@ #include <asm/mmu.h> #include <asm/sysreg.h>
+/* + * Cache if the event is allowed to trace Context information. + * This allows us to perform the check, i.e, perfmon_capable(), + * in the context of the event owner, once, during the event_init(). + */ +#define SPE_PMU_HW_FLAGS_CX BIT(0) + +static void set_spe_event_has_cx(struct perf_event *event) +{ + if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable()) + event->hw.flags |= SPE_PMU_HW_FLAGS_CX; +} + +static bool get_spe_event_has_cx(struct perf_event *event) +{ + return !!(event->hw.flags & SPE_PMU_HW_FLAGS_CX); +} + #define ARM_SPE_BUF_PAD_BYTE 0
struct arm_spe_pmu_buf { @@ -272,7 +290,7 @@ static u64 arm_spe_event_to_pmscr(struct perf_event *event) if (!attr->exclude_kernel) reg |= BIT(SYS_PMSCR_EL1_E1SPE_SHIFT);
- if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable()) + if (get_spe_event_has_cx(event)) reg |= BIT(SYS_PMSCR_EL1_CX_SHIFT);
return reg; @@ -709,10 +727,10 @@ static int arm_spe_pmu_event_init(struct perf_event *event) !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT)) return -EOPNOTSUPP;
+ set_spe_event_has_cx(event); reg = arm_spe_event_to_pmscr(event); if (!perfmon_capable() && (reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) | - BIT(SYS_PMSCR_EL1_CX_SHIFT) | BIT(SYS_PMSCR_EL1_PCT_SHIFT)))) return -EACCES;
From: Nicolas Saenz Julienne nsaenzju@redhat.com
[ Upstream commit 5c66d1b9b30f737fcef85a0b75bfe0590e16b62a ]
dequeue_task_rt() only decrements 'rt_rq->rt_nr_running' after having called sched_update_tick_dependency() preventing it from re-enabling the tick on systems that no longer have pending SCHED_RT tasks but have multiple runnable SCHED_OTHER tasks:
dequeue_task_rt() dequeue_rt_entity() dequeue_rt_stack() dequeue_top_rt_rq() sub_nr_running() // decrements rq->nr_running sched_update_tick_dependency() sched_can_stop_tick() // checks rq->rt.rt_nr_running, ... __dequeue_rt_entity() dec_rt_tasks() // decrements rq->rt.rt_nr_running ...
Every other scheduler class performs the operation in the opposite order, and sched_update_tick_dependency() expects the values to be updated as such. So avoid the misbehaviour by inverting the order in which the above operations are performed in the RT scheduler.
Fixes: 76d92ac305f2 ("sched: Migrate sched to use new tick dependency mask model") Signed-off-by: Nicolas Saenz Julienne nsaenzju@redhat.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Valentin Schneider vschneid@redhat.com Reviewed-by: Phil Auld pauld@redhat.com Link: https://lore.kernel.org/r/20220628092259.330171-1-nsaenzju@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/rt.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 8c9ed9664840..55f39c8f4203 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -480,7 +480,7 @@ static inline void rt_queue_push_tasks(struct rq *rq) #endif /* CONFIG_SMP */
static void enqueue_top_rt_rq(struct rt_rq *rt_rq); -static void dequeue_top_rt_rq(struct rt_rq *rt_rq); +static void dequeue_top_rt_rq(struct rt_rq *rt_rq, unsigned int count);
static inline int on_rt_rq(struct sched_rt_entity *rt_se) { @@ -601,7 +601,7 @@ static void sched_rt_rq_dequeue(struct rt_rq *rt_rq) rt_se = rt_rq->tg->rt_se[cpu];
if (!rt_se) { - dequeue_top_rt_rq(rt_rq); + dequeue_top_rt_rq(rt_rq, rt_rq->rt_nr_running); /* Kick cpufreq (see the comment in kernel/sched/sched.h). */ cpufreq_update_util(rq_of_rt_rq(rt_rq), 0); } @@ -687,7 +687,7 @@ static inline void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
static inline void sched_rt_rq_dequeue(struct rt_rq *rt_rq) { - dequeue_top_rt_rq(rt_rq); + dequeue_top_rt_rq(rt_rq, rt_rq->rt_nr_running); }
static inline int rt_rq_throttled(struct rt_rq *rt_rq) @@ -1089,7 +1089,7 @@ static void update_curr_rt(struct rq *rq) }
static void -dequeue_top_rt_rq(struct rt_rq *rt_rq) +dequeue_top_rt_rq(struct rt_rq *rt_rq, unsigned int count) { struct rq *rq = rq_of_rt_rq(rt_rq);
@@ -1100,7 +1100,7 @@ dequeue_top_rt_rq(struct rt_rq *rt_rq)
BUG_ON(!rq->nr_running);
- sub_nr_running(rq, rt_rq->rt_nr_running); + sub_nr_running(rq, count); rt_rq->rt_queued = 0;
} @@ -1486,18 +1486,21 @@ static void __dequeue_rt_entity(struct sched_rt_entity *rt_se, unsigned int flag static void dequeue_rt_stack(struct sched_rt_entity *rt_se, unsigned int flags) { struct sched_rt_entity *back = NULL; + unsigned int rt_nr_running;
for_each_sched_rt_entity(rt_se) { rt_se->back = back; back = rt_se; }
- dequeue_top_rt_rq(rt_rq_of_se(back)); + rt_nr_running = rt_rq_of_se(back)->rt_nr_running;
for (rt_se = back; rt_se; rt_se = rt_se->back) { if (on_rt_rq(rt_se)) __dequeue_rt_entity(rt_se, flags); } + + dequeue_top_rt_rq(rt_rq_of_se(back), rt_nr_running); }
static void enqueue_rt_entity(struct sched_rt_entity *rt_se, unsigned int flags)
From: Christian Göttsche cgzones@googlemail.com
[ Upstream commit 700a78335fc28a59c307f420857fd2d4521549f8 ]
sched_setattr(2) issues via kernel/sched/core.c:__sched_setscheduler() a CAP_SYS_NICE audit event unconditionally, even when the requested operation does not require that capability / is unprivileged, i.e. for reducing niceness. This is relevant in connection with SELinux, where a capability check results in a policy decision and by default a denial message on insufficient permission is issued. It can lead to three undesired cases: 1. A denial message is generated, even in case the operation was an unprivileged one and thus the syscall succeeded, creating noise. 2. To avoid the noise from 1. the policy writer adds a rule to ignore those denial messages, hiding future syscalls, where the task performs an actual privileged operation, leading to hidden limited functionality of that task. 3. To avoid the noise from 1. the policy writer adds a rule to allow the task the capability CAP_SYS_NICE, while it does not need it, violating the principle of least privilege.
Conduct privilged/unprivileged categorization first and perform a capable test (and at most once) only if needed.
Signed-off-by: Christian Göttsche cgzones@googlemail.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20220615152505.310488-1-cgzones@googlemail.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/core.c | 138 ++++++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 55 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 410b04decb90..f1e070551aa9 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7002,17 +7002,29 @@ void set_user_nice(struct task_struct *p, long nice) EXPORT_SYMBOL(set_user_nice);
/* - * can_nice - check if a task can reduce its nice value + * is_nice_reduction - check if nice value is an actual reduction + * + * Similar to can_nice() but does not perform a capability check. + * * @p: task * @nice: nice value */ -int can_nice(const struct task_struct *p, const int nice) +static bool is_nice_reduction(const struct task_struct *p, const int nice) { /* Convert nice value [19,-20] to rlimit style value [1,40]: */ int nice_rlim = nice_to_rlimit(nice);
- return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) || - capable(CAP_SYS_NICE)); + return (nice_rlim <= task_rlimit(p, RLIMIT_NICE)); +} + +/* + * can_nice - check if a task can reduce its nice value + * @p: task + * @nice: nice value + */ +int can_nice(const struct task_struct *p, const int nice) +{ + return is_nice_reduction(p, nice) || capable(CAP_SYS_NICE); }
#ifdef __ARCH_WANT_SYS_NICE @@ -7291,6 +7303,69 @@ static bool check_same_owner(struct task_struct *p) return match; }
+/* + * Allow unprivileged RT tasks to decrease priority. + * Only issue a capable test if needed and only once to avoid an audit + * event on permitted non-privileged operations: + */ +static int user_check_sched_setscheduler(struct task_struct *p, + const struct sched_attr *attr, + int policy, int reset_on_fork) +{ + if (fair_policy(policy)) { + if (attr->sched_nice < task_nice(p) && + !is_nice_reduction(p, attr->sched_nice)) + goto req_priv; + } + + if (rt_policy(policy)) { + unsigned long rlim_rtprio = task_rlimit(p, RLIMIT_RTPRIO); + + /* Can't set/change the rt policy: */ + if (policy != p->policy && !rlim_rtprio) + goto req_priv; + + /* Can't increase priority: */ + if (attr->sched_priority > p->rt_priority && + attr->sched_priority > rlim_rtprio) + goto req_priv; + } + + /* + * Can't set/change SCHED_DEADLINE policy at all for now + * (safest behavior); in the future we would like to allow + * unprivileged DL tasks to increase their relative deadline + * or reduce their runtime (both ways reducing utilization) + */ + if (dl_policy(policy)) + goto req_priv; + + /* + * Treat SCHED_IDLE as nice 20. Only allow a switch to + * SCHED_NORMAL if the RLIMIT_NICE would normally permit it. + */ + if (task_has_idle_policy(p) && !idle_policy(policy)) { + if (!is_nice_reduction(p, task_nice(p))) + goto req_priv; + } + + /* Can't change other user's priorities: */ + if (!check_same_owner(p)) + goto req_priv; + + /* Normal users shall not reset the sched_reset_on_fork flag: */ + if (p->sched_reset_on_fork && !reset_on_fork) + goto req_priv; + + return 0; + +req_priv: + if (!capable(CAP_SYS_NICE)) + return -EPERM; + + return 0; +} + static int __sched_setscheduler(struct task_struct *p, const struct sched_attr *attr, bool user, bool pi) @@ -7332,58 +7407,11 @@ static int __sched_setscheduler(struct task_struct *p, (rt_policy(policy) != (attr->sched_priority != 0))) return -EINVAL;
- /* - * Allow unprivileged RT tasks to decrease priority: - */ - if (user && !capable(CAP_SYS_NICE)) { - if (fair_policy(policy)) { - if (attr->sched_nice < task_nice(p) && - !can_nice(p, attr->sched_nice)) - return -EPERM; - } - - if (rt_policy(policy)) { - unsigned long rlim_rtprio = - task_rlimit(p, RLIMIT_RTPRIO); - - /* Can't set/change the rt policy: */ - if (policy != p->policy && !rlim_rtprio) - return -EPERM; - - /* Can't increase priority: */ - if (attr->sched_priority > p->rt_priority && - attr->sched_priority > rlim_rtprio) - return -EPERM; - } - - /* - * Can't set/change SCHED_DEADLINE policy at all for now - * (safest behavior); in the future we would like to allow - * unprivileged DL tasks to increase their relative deadline - * or reduce their runtime (both ways reducing utilization) - */ - if (dl_policy(policy)) - return -EPERM; - - /* - * Treat SCHED_IDLE as nice 20. Only allow a switch to - * SCHED_NORMAL if the RLIMIT_NICE would normally permit it. - */ - if (task_has_idle_policy(p) && !idle_policy(policy)) { - if (!can_nice(p, task_nice(p))) - return -EPERM; - } - - /* Can't change other user's priorities: */ - if (!check_same_owner(p)) - return -EPERM; - - /* Normal users shall not reset the sched_reset_on_fork flag: */ - if (p->sched_reset_on_fork && !reset_on_fork) - return -EPERM; - } - if (user) { + retval = user_check_sched_setscheduler(p, attr, policy, reset_on_fork); + if (retval) + return retval; + if (attr->sched_flags & SCHED_FLAG_SUGOV) return -EINVAL;
From: Mel Gorman mgorman@techsingularity.net
[ Upstream commit 70ce3ea9aa4ed901c8a90de667df5ef307766e71 ]
On clone, numa_migrate_retry is inherited from the parent which means that the first NUMA placement of a task is non-deterministic. This affects when load balancing recognises numa tasks and whether to migrate "regular", "remote" or "all" tasks between NUMA scheduler domains.
Signed-off-by: Mel Gorman mgorman@techsingularity.net Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Tested-by: K Prateek Nayak kprateek.nayak@amd.com Link: https://lore.kernel.org/r/20220520103519.1863-2-mgorman@techsingularity.net Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/fair.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 9d6058b0a3d4..0cba1b2e295b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2885,6 +2885,7 @@ void init_numa_balancing(unsigned long clone_flags, struct task_struct *p) p->node_stamp = 0; p->numa_scan_seq = mm ? mm->numa_scan_seq : 0; p->numa_scan_period = sysctl_numa_balancing_scan_delay; + p->numa_migrate_retry = 0; /* Protect against double add, see task_tick_numa and task_numa_work */ p->numa_work.next = &p->numa_work; p->numa_faults = NULL;
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit a1a5482a2c6e38a3ebed32e571625c56a8cc41a6 ]
On Fri, Jun 17, 2022 at 02:08:52PM +0300, Stephane Eranian wrote:
Some changes to the way invalid MSR accesses are reported by the kernel is causing some problems with messages printed on the console.
We have seen several cases of ex_handler_msr() printing invalid MSR accesses once but the callstack multiple times causing confusion on the console.
The problem here is that another earlier commit (5.13):
a358f40600b3 ("once: implement DO_ONCE_LITE for non-fast-path "do once" functionality")
Modifies all the pr_*_once() calls to always return true claiming that no caller is ever checking the return value of the functions.
This is why we are seeing the callstack printed without the associated printk() msg.
Extract the ONCE_IF(cond) part into __ONCE_LTE_IF() and use that to implement DO_ONCE_LITE_IF() and fix the extable code.
Fixes: a358f40600b3 ("once: implement DO_ONCE_LITE for non-fast-path "do once" functionality") Reported-by: Stephane Eranian eranian@google.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Tested-by: Stephane Eranian eranian@google.com Link: https://lkml.kernel.org/r/YqyVFsbviKjVGGZ9@worktop.programming.kicks-ass.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/mm/extable.c | 16 +++++++++------- include/linux/once_lite.h | 20 ++++++++++++++++---- 2 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c index dba2197c05c3..331310c29349 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c @@ -94,16 +94,18 @@ static bool ex_handler_copy(const struct exception_table_entry *fixup, static bool ex_handler_msr(const struct exception_table_entry *fixup, struct pt_regs *regs, bool wrmsr, bool safe, int reg) { - if (!safe && wrmsr && - pr_warn_once("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n", - (unsigned int)regs->cx, (unsigned int)regs->dx, - (unsigned int)regs->ax, regs->ip, (void *)regs->ip)) + if (__ONCE_LITE_IF(!safe && wrmsr)) { + pr_warn("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n", + (unsigned int)regs->cx, (unsigned int)regs->dx, + (unsigned int)regs->ax, regs->ip, (void *)regs->ip); show_stack_regs(regs); + }
- if (!safe && !wrmsr && - pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n", - (unsigned int)regs->cx, regs->ip, (void *)regs->ip)) + if (__ONCE_LITE_IF(!safe && !wrmsr)) { + pr_warn("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n", + (unsigned int)regs->cx, regs->ip, (void *)regs->ip); show_stack_regs(regs); + }
if (!wrmsr) { /* Pretend that the read succeeded and returned 0. */ diff --git a/include/linux/once_lite.h b/include/linux/once_lite.h index 861e606b820f..b7bce4983638 100644 --- a/include/linux/once_lite.h +++ b/include/linux/once_lite.h @@ -9,15 +9,27 @@ */ #define DO_ONCE_LITE(func, ...) \ DO_ONCE_LITE_IF(true, func, ##__VA_ARGS__) -#define DO_ONCE_LITE_IF(condition, func, ...) \ + +#define __ONCE_LITE_IF(condition) \ ({ \ static bool __section(".data.once") __already_done; \ - bool __ret_do_once = !!(condition); \ + bool __ret_cond = !!(condition); \ + bool __ret_once = false; \ \ - if (unlikely(__ret_do_once && !__already_done)) { \ + if (unlikely(__ret_cond && !__already_done)) { \ __already_done = true; \ - func(__VA_ARGS__); \ + __ret_once = true; \ } \ + unlikely(__ret_once); \ + }) + +#define DO_ONCE_LITE_IF(condition, func, ...) \ + ({ \ + bool __ret_do_once = !!(condition); \ + \ + if (__ONCE_LITE_IF(__ret_do_once)) \ + func(__VA_ARGS__); \ + \ unlikely(__ret_do_once); \ })
From: Jens Axboe axboe@kernel.dk
[ Upstream commit ed29b0b4fd835b058ddd151c49d021e28d631ee6 ]
In preparation for splitting io_uring up a bit, move it into its own top level directory. It didn't really belong in fs/ anyway, as it's not a file system only API.
This adds io_uring/ and moves the core files in there, and updates the MAINTAINERS file for the new location.
Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- MAINTAINERS | 7 +------ Makefile | 1 + fs/Makefile | 2 -- io_uring/Makefile | 6 ++++++ {fs => io_uring}/io-wq.c | 0 {fs => io_uring}/io-wq.h | 0 {fs => io_uring}/io_uring.c | 2 +- kernel/sched/core.c | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 io_uring/Makefile rename {fs => io_uring}/io-wq.c (100%) rename {fs => io_uring}/io-wq.h (100%) rename {fs => io_uring}/io_uring.c (99%)
diff --git a/MAINTAINERS b/MAINTAINERS index 64379c699903..08620b9a44fc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7773,9 +7773,6 @@ F: include/linux/fs.h F: include/linux/fs_types.h F: include/uapi/linux/fs.h F: include/uapi/linux/openat2.h -X: fs/io-wq.c -X: fs/io-wq.h -X: fs/io_uring.c
FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER M: Riku Voipio riku.voipio@iki.fi @@ -10476,9 +10473,7 @@ L: io-uring@vger.kernel.org S: Maintained T: git git://git.kernel.dk/linux-block T: git git://git.kernel.dk/liburing -F: fs/io-wq.c -F: fs/io-wq.h -F: fs/io_uring.c +F: io_uring/ F: include/linux/io_uring.h F: include/uapi/linux/io_uring.h F: tools/io_uring/ diff --git a/Makefile b/Makefile index cef467fc574e..68b3da2babd5 100644 --- a/Makefile +++ b/Makefile @@ -1102,6 +1102,7 @@ export MODULES_NSDEPS := $(extmod_prefix)modules.nsdeps ifeq ($(KBUILD_EXTMOD),) core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ core-$(CONFIG_BLOCK) += block/ +core-$(CONFIG_IO_URING) += io_uring/
vmlinux-dirs := $(patsubst %/,%,$(filter %/, \ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ diff --git a/fs/Makefile b/fs/Makefile index 208a74e0b00e..93b80529f8e8 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -34,8 +34,6 @@ obj-$(CONFIG_TIMERFD) += timerfd.o obj-$(CONFIG_EVENTFD) += eventfd.o obj-$(CONFIG_USERFAULTFD) += userfaultfd.o obj-$(CONFIG_AIO) += aio.o -obj-$(CONFIG_IO_URING) += io_uring.o -obj-$(CONFIG_IO_WQ) += io-wq.o obj-$(CONFIG_FS_DAX) += dax.o obj-$(CONFIG_FS_ENCRYPTION) += crypto/ obj-$(CONFIG_FS_VERITY) += verity/ diff --git a/io_uring/Makefile b/io_uring/Makefile new file mode 100644 index 000000000000..3680425df947 --- /dev/null +++ b/io_uring/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for io_uring + +obj-$(CONFIG_IO_URING) += io_uring.o +obj-$(CONFIG_IO_WQ) += io-wq.o diff --git a/fs/io-wq.c b/io_uring/io-wq.c similarity index 100% rename from fs/io-wq.c rename to io_uring/io-wq.c diff --git a/fs/io-wq.h b/io_uring/io-wq.h similarity index 100% rename from fs/io-wq.h rename to io_uring/io-wq.h diff --git a/fs/io_uring.c b/io_uring/io_uring.c similarity index 99% rename from fs/io_uring.c rename to io_uring/io_uring.c index e8e769be9ed0..b63956975109 100644 --- a/fs/io_uring.c +++ b/io_uring/io_uring.c @@ -87,7 +87,7 @@
#include <uapi/linux/io_uring.h>
-#include "internal.h" +#include "../fs/internal.h" #include "io-wq.h"
#define IORING_MAX_ENTRIES 32768 diff --git a/kernel/sched/core.c b/kernel/sched/core.c index f1e070551aa9..91471ba8dbd2 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -91,7 +91,7 @@ #include "stats.h"
#include "../workqueue_internal.h" -#include "../../fs/io-wq.h" +#include "../../io_uring/io-wq.h" #include "../smpboot.h"
/*
From: Jens Axboe axboe@kernel.dk
[ Upstream commit 0702e5364f643bc86683d9f585edfe76dbabae39 ]
Rather than have two giant switches for doing request preparation and then for doing request issue, add a prep and issue handler for each of them in the io_op_defs[] request definition.
Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- io_uring/io_uring.c | 838 +++++++++++++++++++------------------------- 1 file changed, 365 insertions(+), 473 deletions(-)
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index b63956975109..f429b68d1fc2 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1110,231 +1110,13 @@ struct io_op_def { unsigned iopoll : 1; /* size of async data needed, if any */ unsigned short async_size; -};
-static const struct io_op_def io_op_defs[] = { - [IORING_OP_NOP] = { - .audit_skip = 1, - .iopoll = 1, - }, - [IORING_OP_READV] = { - .needs_file = 1, - .unbound_nonreg_file = 1, - .pollin = 1, - .buffer_select = 1, - .needs_async_setup = 1, - .plug = 1, - .audit_skip = 1, - .ioprio = 1, - .iopoll = 1, - .async_size = sizeof(struct io_async_rw), - }, - [IORING_OP_WRITEV] = { - .needs_file = 1, - .hash_reg_file = 1, - .unbound_nonreg_file = 1, - .pollout = 1, - .needs_async_setup = 1, - .plug = 1, - .audit_skip = 1, - .ioprio = 1, - .iopoll = 1, - .async_size = sizeof(struct io_async_rw), - }, - [IORING_OP_FSYNC] = { - .needs_file = 1, - .audit_skip = 1, - }, - [IORING_OP_READ_FIXED] = { - .needs_file = 1, - .unbound_nonreg_file = 1, - .pollin = 1, - .plug = 1, - .audit_skip = 1, - .ioprio = 1, - .iopoll = 1, - .async_size = sizeof(struct io_async_rw), - }, - [IORING_OP_WRITE_FIXED] = { - .needs_file = 1, - .hash_reg_file = 1, - .unbound_nonreg_file = 1, - .pollout = 1, - .plug = 1, - .audit_skip = 1, - .ioprio = 1, - .iopoll = 1, - .async_size = sizeof(struct io_async_rw), - }, - [IORING_OP_POLL_ADD] = { - .needs_file = 1, - .unbound_nonreg_file = 1, - .audit_skip = 1, - }, - [IORING_OP_POLL_REMOVE] = { - .audit_skip = 1, - }, - [IORING_OP_SYNC_FILE_RANGE] = { - .needs_file = 1, - .audit_skip = 1, - }, - [IORING_OP_SENDMSG] = { - .needs_file = 1, - .unbound_nonreg_file = 1, - .pollout = 1, - .needs_async_setup = 1, - .ioprio = 1, - .async_size = sizeof(struct io_async_msghdr), - }, - [IORING_OP_RECVMSG] = { - .needs_file = 1, - .unbound_nonreg_file = 1, - .pollin = 1, - .buffer_select = 1, - .needs_async_setup = 1, - .ioprio = 1, - .async_size = sizeof(struct io_async_msghdr), - }, - [IORING_OP_TIMEOUT] = { - .audit_skip = 1, - .async_size = sizeof(struct io_timeout_data), - }, - [IORING_OP_TIMEOUT_REMOVE] = { - /* used by timeout updates' prep() */ - .audit_skip = 1, - }, - [IORING_OP_ACCEPT] = { - .needs_file = 1, - .unbound_nonreg_file = 1, - .pollin = 1, - .poll_exclusive = 1, - .ioprio = 1, /* used for flags */ - }, - [IORING_OP_ASYNC_CANCEL] = { - .audit_skip = 1, - }, - [IORING_OP_LINK_TIMEOUT] = { - .audit_skip = 1, - .async_size = sizeof(struct io_timeout_data), - }, - [IORING_OP_CONNECT] = { - .needs_file = 1, - .unbound_nonreg_file = 1, - .pollout = 1, - .needs_async_setup = 1, - .async_size = sizeof(struct io_async_connect), - }, - [IORING_OP_FALLOCATE] = { - .needs_file = 1, - }, - [IORING_OP_OPENAT] = {}, - [IORING_OP_CLOSE] = {}, - [IORING_OP_FILES_UPDATE] = { - .audit_skip = 1, - .iopoll = 1, - }, - [IORING_OP_STATX] = { - .audit_skip = 1, - }, - [IORING_OP_READ] = { - .needs_file = 1, - .unbound_nonreg_file = 1, - .pollin = 1, - .buffer_select = 1, - .plug = 1, - .audit_skip = 1, - .ioprio = 1, - .iopoll = 1, - .async_size = sizeof(struct io_async_rw), - }, - [IORING_OP_WRITE] = { - .needs_file = 1, - .hash_reg_file = 1, - .unbound_nonreg_file = 1, - .pollout = 1, - .plug = 1, - .audit_skip = 1, - .ioprio = 1, - .iopoll = 1, - .async_size = sizeof(struct io_async_rw), - }, - [IORING_OP_FADVISE] = { - .needs_file = 1, - .audit_skip = 1, - }, - [IORING_OP_MADVISE] = {}, - [IORING_OP_SEND] = { - .needs_file = 1, - .unbound_nonreg_file = 1, - .pollout = 1, - .audit_skip = 1, - .ioprio = 1, - }, - [IORING_OP_RECV] = { - .needs_file = 1, - .unbound_nonreg_file = 1, - .pollin = 1, - .buffer_select = 1, - .audit_skip = 1, - .ioprio = 1, - }, - [IORING_OP_OPENAT2] = { - }, - [IORING_OP_EPOLL_CTL] = { - .unbound_nonreg_file = 1, - .audit_skip = 1, - }, - [IORING_OP_SPLICE] = { - .needs_file = 1, - .hash_reg_file = 1, - .unbound_nonreg_file = 1, - .audit_skip = 1, - }, - [IORING_OP_PROVIDE_BUFFERS] = { - .audit_skip = 1, - .iopoll = 1, - }, - [IORING_OP_REMOVE_BUFFERS] = { - .audit_skip = 1, - .iopoll = 1, - }, - [IORING_OP_TEE] = { - .needs_file = 1, - .hash_reg_file = 1, - .unbound_nonreg_file = 1, - .audit_skip = 1, - }, - [IORING_OP_SHUTDOWN] = { - .needs_file = 1, - }, - [IORING_OP_RENAMEAT] = {}, - [IORING_OP_UNLINKAT] = {}, - [IORING_OP_MKDIRAT] = {}, - [IORING_OP_SYMLINKAT] = {}, - [IORING_OP_LINKAT] = {}, - [IORING_OP_MSG_RING] = { - .needs_file = 1, - .iopoll = 1, - }, - [IORING_OP_FSETXATTR] = { - .needs_file = 1 - }, - [IORING_OP_SETXATTR] = {}, - [IORING_OP_FGETXATTR] = { - .needs_file = 1 - }, - [IORING_OP_GETXATTR] = {}, - [IORING_OP_SOCKET] = { - .audit_skip = 1, - }, - [IORING_OP_URING_CMD] = { - .needs_file = 1, - .plug = 1, - .needs_async_setup = 1, - .async_size = uring_cmd_pdu_size(1), - }, + int (*prep)(struct io_kiocb *, const struct io_uring_sqe *); + int (*issue)(struct io_kiocb *, unsigned int); };
+static const struct io_op_def io_op_defs[]; + /* requests with any of those set should undergo io_disarm_next() */ #define IO_DISARM_MASK (REQ_F_ARM_LTIMEOUT | REQ_F_LINK_TIMEOUT | REQ_F_FAIL) #define IO_REQ_LINK_FLAGS (REQ_F_LINK | REQ_F_HARDLINK) @@ -8039,96 +7821,33 @@ static int io_files_update(struct io_kiocb *req, unsigned int issue_flags) return 0; }
-static int io_req_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) +static int io_req_prep_async(struct io_kiocb *req) { + const struct io_op_def *def = &io_op_defs[req->opcode]; + + /* assign early for deferred execution for non-fixed file */ + if (def->needs_file && !(req->flags & REQ_F_FIXED_FILE)) + req->file = io_file_get_normal(req, req->cqe.fd); + if (!def->needs_async_setup) + return 0; + if (WARN_ON_ONCE(req_has_async_data(req))) + return -EFAULT; + if (io_alloc_async_data(req)) + return -EAGAIN; + switch (req->opcode) { - case IORING_OP_NOP: - return io_nop_prep(req, sqe); case IORING_OP_READV: - case IORING_OP_READ_FIXED: - case IORING_OP_READ: + return io_readv_prep_async(req); case IORING_OP_WRITEV: - case IORING_OP_WRITE_FIXED: - case IORING_OP_WRITE: - return io_prep_rw(req, sqe); - case IORING_OP_POLL_ADD: - return io_poll_add_prep(req, sqe); - case IORING_OP_POLL_REMOVE: - return io_poll_remove_prep(req, sqe); - case IORING_OP_FSYNC: - return io_fsync_prep(req, sqe); - case IORING_OP_SYNC_FILE_RANGE: - return io_sfr_prep(req, sqe); + return io_writev_prep_async(req); case IORING_OP_SENDMSG: - case IORING_OP_SEND: - return io_sendmsg_prep(req, sqe); + return io_sendmsg_prep_async(req); case IORING_OP_RECVMSG: - case IORING_OP_RECV: - return io_recvmsg_prep(req, sqe); + return io_recvmsg_prep_async(req); case IORING_OP_CONNECT: - return io_connect_prep(req, sqe); - case IORING_OP_TIMEOUT: - return io_timeout_prep(req, sqe); - case IORING_OP_TIMEOUT_REMOVE: - return io_timeout_remove_prep(req, sqe); - case IORING_OP_ASYNC_CANCEL: - return io_async_cancel_prep(req, sqe); - case IORING_OP_LINK_TIMEOUT: - return io_link_timeout_prep(req, sqe); - case IORING_OP_ACCEPT: - return io_accept_prep(req, sqe); - case IORING_OP_FALLOCATE: - return io_fallocate_prep(req, sqe); - case IORING_OP_OPENAT: - return io_openat_prep(req, sqe); - case IORING_OP_CLOSE: - return io_close_prep(req, sqe); - case IORING_OP_FILES_UPDATE: - return io_files_update_prep(req, sqe); - case IORING_OP_STATX: - return io_statx_prep(req, sqe); - case IORING_OP_FADVISE: - return io_fadvise_prep(req, sqe); - case IORING_OP_MADVISE: - return io_madvise_prep(req, sqe); - case IORING_OP_OPENAT2: - return io_openat2_prep(req, sqe); - case IORING_OP_EPOLL_CTL: - return io_epoll_ctl_prep(req, sqe); - case IORING_OP_SPLICE: - return io_splice_prep(req, sqe); - case IORING_OP_PROVIDE_BUFFERS: - return io_provide_buffers_prep(req, sqe); - case IORING_OP_REMOVE_BUFFERS: - return io_remove_buffers_prep(req, sqe); - case IORING_OP_TEE: - return io_tee_prep(req, sqe); - case IORING_OP_SHUTDOWN: - return io_shutdown_prep(req, sqe); - case IORING_OP_RENAMEAT: - return io_renameat_prep(req, sqe); - case IORING_OP_UNLINKAT: - return io_unlinkat_prep(req, sqe); - case IORING_OP_MKDIRAT: - return io_mkdirat_prep(req, sqe); - case IORING_OP_SYMLINKAT: - return io_symlinkat_prep(req, sqe); - case IORING_OP_LINKAT: - return io_linkat_prep(req, sqe); - case IORING_OP_MSG_RING: - return io_msg_ring_prep(req, sqe); - case IORING_OP_FSETXATTR: - return io_fsetxattr_prep(req, sqe); - case IORING_OP_SETXATTR: - return io_setxattr_prep(req, sqe); - case IORING_OP_FGETXATTR: - return io_fgetxattr_prep(req, sqe); - case IORING_OP_GETXATTR: - return io_getxattr_prep(req, sqe); - case IORING_OP_SOCKET: - return io_socket_prep(req, sqe); + return io_connect_prep_async(req); case IORING_OP_URING_CMD: - return io_uring_cmd_prep(req, sqe); + return io_uring_cmd_prep_async(req); }
printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n", @@ -8136,39 +7855,6 @@ static int io_req_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) return -EINVAL; }
-static int io_req_prep_async(struct io_kiocb *req) -{ - const struct io_op_def *def = &io_op_defs[req->opcode]; - - /* assign early for deferred execution for non-fixed file */ - if (def->needs_file && !(req->flags & REQ_F_FIXED_FILE)) - req->file = io_file_get_normal(req, req->cqe.fd); - if (!def->needs_async_setup) - return 0; - if (WARN_ON_ONCE(req_has_async_data(req))) - return -EFAULT; - if (io_alloc_async_data(req)) - return -EAGAIN; - - switch (req->opcode) { - case IORING_OP_READV: - return io_readv_prep_async(req); - case IORING_OP_WRITEV: - return io_writev_prep_async(req); - case IORING_OP_SENDMSG: - return io_sendmsg_prep_async(req); - case IORING_OP_RECVMSG: - return io_recvmsg_prep_async(req); - case IORING_OP_CONNECT: - return io_connect_prep_async(req); - case IORING_OP_URING_CMD: - return io_uring_cmd_prep_async(req); - } - printk_once(KERN_WARNING "io_uring: prep_async() bad opcode %d\n", - req->opcode); - return -EFAULT; -} - static u32 io_get_sequence(struct io_kiocb *req) { u32 seq = req->ctx->cached_sq_head; @@ -8335,141 +8021,7 @@ static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags) if (!def->audit_skip) audit_uring_entry(req->opcode);
- switch (req->opcode) { - case IORING_OP_NOP: - ret = io_nop(req, issue_flags); - break; - case IORING_OP_READV: - case IORING_OP_READ_FIXED: - case IORING_OP_READ: - ret = io_read(req, issue_flags); - break; - case IORING_OP_WRITEV: - case IORING_OP_WRITE_FIXED: - case IORING_OP_WRITE: - ret = io_write(req, issue_flags); - break; - case IORING_OP_FSYNC: - ret = io_fsync(req, issue_flags); - break; - case IORING_OP_POLL_ADD: - ret = io_poll_add(req, issue_flags); - break; - case IORING_OP_POLL_REMOVE: - ret = io_poll_remove(req, issue_flags); - break; - case IORING_OP_SYNC_FILE_RANGE: - ret = io_sync_file_range(req, issue_flags); - break; - case IORING_OP_SENDMSG: - ret = io_sendmsg(req, issue_flags); - break; - case IORING_OP_SEND: - ret = io_send(req, issue_flags); - break; - case IORING_OP_RECVMSG: - ret = io_recvmsg(req, issue_flags); - break; - case IORING_OP_RECV: - ret = io_recv(req, issue_flags); - break; - case IORING_OP_TIMEOUT: - ret = io_timeout(req, issue_flags); - break; - case IORING_OP_TIMEOUT_REMOVE: - ret = io_timeout_remove(req, issue_flags); - break; - case IORING_OP_ACCEPT: - ret = io_accept(req, issue_flags); - break; - case IORING_OP_CONNECT: - ret = io_connect(req, issue_flags); - break; - case IORING_OP_ASYNC_CANCEL: - ret = io_async_cancel(req, issue_flags); - break; - case IORING_OP_FALLOCATE: - ret = io_fallocate(req, issue_flags); - break; - case IORING_OP_OPENAT: - ret = io_openat(req, issue_flags); - break; - case IORING_OP_CLOSE: - ret = io_close(req, issue_flags); - break; - case IORING_OP_FILES_UPDATE: - ret = io_files_update(req, issue_flags); - break; - case IORING_OP_STATX: - ret = io_statx(req, issue_flags); - break; - case IORING_OP_FADVISE: - ret = io_fadvise(req, issue_flags); - break; - case IORING_OP_MADVISE: - ret = io_madvise(req, issue_flags); - break; - case IORING_OP_OPENAT2: - ret = io_openat2(req, issue_flags); - break; - case IORING_OP_EPOLL_CTL: - ret = io_epoll_ctl(req, issue_flags); - break; - case IORING_OP_SPLICE: - ret = io_splice(req, issue_flags); - break; - case IORING_OP_PROVIDE_BUFFERS: - ret = io_provide_buffers(req, issue_flags); - break; - case IORING_OP_REMOVE_BUFFERS: - ret = io_remove_buffers(req, issue_flags); - break; - case IORING_OP_TEE: - ret = io_tee(req, issue_flags); - break; - case IORING_OP_SHUTDOWN: - ret = io_shutdown(req, issue_flags); - break; - case IORING_OP_RENAMEAT: - ret = io_renameat(req, issue_flags); - break; - case IORING_OP_UNLINKAT: - ret = io_unlinkat(req, issue_flags); - break; - case IORING_OP_MKDIRAT: - ret = io_mkdirat(req, issue_flags); - break; - case IORING_OP_SYMLINKAT: - ret = io_symlinkat(req, issue_flags); - break; - case IORING_OP_LINKAT: - ret = io_linkat(req, issue_flags); - break; - case IORING_OP_MSG_RING: - ret = io_msg_ring(req, issue_flags); - break; - case IORING_OP_FSETXATTR: - ret = io_fsetxattr(req, issue_flags); - break; - case IORING_OP_SETXATTR: - ret = io_setxattr(req, issue_flags); - break; - case IORING_OP_FGETXATTR: - ret = io_fgetxattr(req, issue_flags); - break; - case IORING_OP_GETXATTR: - ret = io_getxattr(req, issue_flags); - break; - case IORING_OP_SOCKET: - ret = io_socket(req, issue_flags); - break; - case IORING_OP_URING_CMD: - ret = io_uring_cmd(req, issue_flags); - break; - default: - ret = -EINVAL; - break; - } + ret = def->issue(req, issue_flags);
if (!def->audit_skip) audit_uring_exit(!ret, ret); @@ -8898,7 +8450,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, req->flags |= REQ_F_CREDS; }
- return io_req_prep(req, sqe); + return def->prep(req, sqe); }
static __cold int io_submit_fail_init(const struct io_uring_sqe *sqe, @@ -13200,8 +12752,343 @@ SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode, return ret; }
+static int io_no_issue(struct io_kiocb *req, unsigned int issue_flags) +{ + WARN_ON_ONCE(1); + return -ECANCELED; +} + +static const struct io_op_def io_op_defs[] = { + [IORING_OP_NOP] = { + .audit_skip = 1, + .iopoll = 1, + .prep = io_nop_prep, + .issue = io_nop, + }, + [IORING_OP_READV] = { + .needs_file = 1, + .unbound_nonreg_file = 1, + .pollin = 1, + .buffer_select = 1, + .needs_async_setup = 1, + .plug = 1, + .audit_skip = 1, + .ioprio = 1, + .iopoll = 1, + .async_size = sizeof(struct io_async_rw), + .prep = io_prep_rw, + .issue = io_read, + }, + [IORING_OP_WRITEV] = { + .needs_file = 1, + .hash_reg_file = 1, + .unbound_nonreg_file = 1, + .pollout = 1, + .needs_async_setup = 1, + .plug = 1, + .audit_skip = 1, + .ioprio = 1, + .iopoll = 1, + .async_size = sizeof(struct io_async_rw), + .prep = io_prep_rw, + .issue = io_write, + }, + [IORING_OP_FSYNC] = { + .needs_file = 1, + .audit_skip = 1, + .prep = io_fsync_prep, + .issue = io_fsync, + }, + [IORING_OP_READ_FIXED] = { + .needs_file = 1, + .unbound_nonreg_file = 1, + .pollin = 1, + .plug = 1, + .audit_skip = 1, + .ioprio = 1, + .iopoll = 1, + .async_size = sizeof(struct io_async_rw), + .prep = io_prep_rw, + .issue = io_read, + }, + [IORING_OP_WRITE_FIXED] = { + .needs_file = 1, + .hash_reg_file = 1, + .unbound_nonreg_file = 1, + .pollout = 1, + .plug = 1, + .audit_skip = 1, + .ioprio = 1, + .iopoll = 1, + .async_size = sizeof(struct io_async_rw), + .prep = io_prep_rw, + .issue = io_write, + }, + [IORING_OP_POLL_ADD] = { + .needs_file = 1, + .unbound_nonreg_file = 1, + .audit_skip = 1, + .prep = io_poll_add_prep, + .issue = io_poll_add, + }, + [IORING_OP_POLL_REMOVE] = { + .audit_skip = 1, + .prep = io_poll_remove_prep, + .issue = io_poll_remove, + }, + [IORING_OP_SYNC_FILE_RANGE] = { + .needs_file = 1, + .audit_skip = 1, + .prep = io_sfr_prep, + .issue = io_sync_file_range, + }, + [IORING_OP_SENDMSG] = { + .needs_file = 1, + .unbound_nonreg_file = 1, + .pollout = 1, + .needs_async_setup = 1, + .ioprio = 1, + .async_size = sizeof(struct io_async_msghdr), + .prep = io_sendmsg_prep, + .issue = io_sendmsg, + }, + [IORING_OP_RECVMSG] = { + .needs_file = 1, + .unbound_nonreg_file = 1, + .pollin = 1, + .buffer_select = 1, + .needs_async_setup = 1, + .ioprio = 1, + .async_size = sizeof(struct io_async_msghdr), + .prep = io_recvmsg_prep, + .issue = io_recvmsg, + }, + [IORING_OP_TIMEOUT] = { + .audit_skip = 1, + .async_size = sizeof(struct io_timeout_data), + .prep = io_timeout_prep, + .issue = io_timeout, + }, + [IORING_OP_TIMEOUT_REMOVE] = { + /* used by timeout updates' prep() */ + .audit_skip = 1, + .prep = io_timeout_remove_prep, + .issue = io_timeout_remove, + }, + [IORING_OP_ACCEPT] = { + .needs_file = 1, + .unbound_nonreg_file = 1, + .pollin = 1, + .poll_exclusive = 1, + .ioprio = 1, /* used for flags */ + .prep = io_accept_prep, + .issue = io_accept, + }, + [IORING_OP_ASYNC_CANCEL] = { + .audit_skip = 1, + .prep = io_async_cancel_prep, + .issue = io_async_cancel, + }, + [IORING_OP_LINK_TIMEOUT] = { + .audit_skip = 1, + .async_size = sizeof(struct io_timeout_data), + .prep = io_link_timeout_prep, + .issue = io_no_issue, + }, + [IORING_OP_CONNECT] = { + .needs_file = 1, + .unbound_nonreg_file = 1, + .pollout = 1, + .needs_async_setup = 1, + .async_size = sizeof(struct io_async_connect), + .prep = io_connect_prep, + .issue = io_connect, + }, + [IORING_OP_FALLOCATE] = { + .needs_file = 1, + .prep = io_fallocate_prep, + .issue = io_fallocate, + }, + [IORING_OP_OPENAT] = { + .prep = io_openat_prep, + .issue = io_openat, + }, + [IORING_OP_CLOSE] = { + .prep = io_close_prep, + .issue = io_close, + }, + [IORING_OP_FILES_UPDATE] = { + .audit_skip = 1, + .iopoll = 1, + .prep = io_files_update_prep, + .issue = io_files_update, + }, + [IORING_OP_STATX] = { + .audit_skip = 1, + .prep = io_statx_prep, + .issue = io_statx, + }, + [IORING_OP_READ] = { + .needs_file = 1, + .unbound_nonreg_file = 1, + .pollin = 1, + .buffer_select = 1, + .plug = 1, + .audit_skip = 1, + .ioprio = 1, + .iopoll = 1, + .async_size = sizeof(struct io_async_rw), + .prep = io_prep_rw, + .issue = io_read, + }, + [IORING_OP_WRITE] = { + .needs_file = 1, + .hash_reg_file = 1, + .unbound_nonreg_file = 1, + .pollout = 1, + .plug = 1, + .audit_skip = 1, + .ioprio = 1, + .iopoll = 1, + .async_size = sizeof(struct io_async_rw), + .prep = io_prep_rw, + .issue = io_write, + }, + [IORING_OP_FADVISE] = { + .needs_file = 1, + .audit_skip = 1, + .prep = io_fadvise_prep, + .issue = io_fadvise, + }, + [IORING_OP_MADVISE] = { + .prep = io_madvise_prep, + .issue = io_madvise, + }, + [IORING_OP_SEND] = { + .needs_file = 1, + .unbound_nonreg_file = 1, + .pollout = 1, + .audit_skip = 1, + .ioprio = 1, + .prep = io_sendmsg_prep, + .issue = io_send, + }, + [IORING_OP_RECV] = { + .needs_file = 1, + .unbound_nonreg_file = 1, + .pollin = 1, + .buffer_select = 1, + .audit_skip = 1, + .ioprio = 1, + .prep = io_recvmsg_prep, + .issue = io_recv, + }, + [IORING_OP_OPENAT2] = { + .prep = io_openat2_prep, + .issue = io_openat2, + }, + [IORING_OP_EPOLL_CTL] = { + .unbound_nonreg_file = 1, + .audit_skip = 1, + .prep = io_epoll_ctl_prep, + .issue = io_epoll_ctl, + }, + [IORING_OP_SPLICE] = { + .needs_file = 1, + .hash_reg_file = 1, + .unbound_nonreg_file = 1, + .audit_skip = 1, + .prep = io_splice_prep, + .issue = io_splice, + }, + [IORING_OP_PROVIDE_BUFFERS] = { + .audit_skip = 1, + .iopoll = 1, + .prep = io_provide_buffers_prep, + .issue = io_provide_buffers, + }, + [IORING_OP_REMOVE_BUFFERS] = { + .audit_skip = 1, + .iopoll = 1, + .prep = io_remove_buffers_prep, + .issue = io_remove_buffers, + }, + [IORING_OP_TEE] = { + .needs_file = 1, + .hash_reg_file = 1, + .unbound_nonreg_file = 1, + .audit_skip = 1, + .prep = io_tee_prep, + .issue = io_tee, + }, + [IORING_OP_SHUTDOWN] = { + .needs_file = 1, + .prep = io_shutdown_prep, + .issue = io_shutdown, + }, + [IORING_OP_RENAMEAT] = { + .prep = io_renameat_prep, + .issue = io_renameat, + }, + [IORING_OP_UNLINKAT] = { + .prep = io_unlinkat_prep, + .issue = io_unlinkat, + }, + [IORING_OP_MKDIRAT] = { + .prep = io_mkdirat_prep, + .issue = io_mkdirat, + }, + [IORING_OP_SYMLINKAT] = { + .prep = io_symlinkat_prep, + .issue = io_symlinkat, + }, + [IORING_OP_LINKAT] = { + .prep = io_linkat_prep, + .issue = io_linkat, + }, + [IORING_OP_MSG_RING] = { + .needs_file = 1, + .iopoll = 1, + .prep = io_msg_ring_prep, + .issue = io_msg_ring, + }, + [IORING_OP_FSETXATTR] = { + .needs_file = 1, + .prep = io_fsetxattr_prep, + .issue = io_fsetxattr, + }, + [IORING_OP_SETXATTR] = { + .prep = io_setxattr_prep, + .issue = io_setxattr, + }, + [IORING_OP_FGETXATTR] = { + .needs_file = 1, + .prep = io_fgetxattr_prep, + .issue = io_fgetxattr, + }, + [IORING_OP_GETXATTR] = { + .prep = io_getxattr_prep, + .issue = io_getxattr, + }, + [IORING_OP_SOCKET] = { + .audit_skip = 1, + .prep = io_socket_prep, + .issue = io_socket, + }, + [IORING_OP_URING_CMD] = { + .needs_file = 1, + .plug = 1, + .needs_async_setup = 1, + .async_size = uring_cmd_pdu_size(1), + .prep = io_uring_cmd_prep, + .issue = io_uring_cmd, + }, +}; + static int __init io_uring_init(void) { + int i; + #define __BUILD_BUG_VERIFY_ELEMENT(stype, eoffset, etype, ename) do { \ BUILD_BUG_ON(offsetof(stype, ename) != eoffset); \ BUILD_BUG_ON(sizeof(etype) != sizeof_field(stype, ename)); \ @@ -13266,6 +13153,11 @@ static int __init io_uring_init(void)
BUILD_BUG_ON(sizeof(struct io_uring_cmd) > 64);
+ for (i = 0; i < ARRAY_SIZE(io_op_defs); i++) { + BUG_ON(!io_op_defs[i].prep); + BUG_ON(!io_op_defs[i].issue); + } + req_cachep = KMEM_CACHE(io_kiocb, SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT); return 0;
From: Michal Koutný mkoutny@suse.com
[ Upstream commit 48904229928d941ce1db181b991948387ab463cd ]
The commit 8bb649ee1da3 ("io_uring: remove ring quiesce for io_uring_register") removed the worklow relying on reinit/resurrection of the percpu_ref, hence, initialization with that requested is a relic.
This is based on code review, this causes no real bug (and theoretically can't). Technically it's a revert of commit 214828962dea ("io_uring: initialize percpu refcounters using PERCU_REF_ALLOW_REINIT") but since the flag omission is now justified, I'm not making this a revert.
Fixes: 8bb649ee1da3 ("io_uring: remove ring quiesce for io_uring_register") Signed-off-by: Michal Koutný mkoutny@suse.com Acked-by: Roman Gushchin roman.gushchin@linux.dev Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- io_uring/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index f429b68d1fc2..27ce532c6c8d 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1701,7 +1701,7 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) ctx->dummy_ubuf->ubuf = -1UL;
if (percpu_ref_init(&ctx->refs, io_ring_ctx_ref_free, - PERCPU_REF_ALLOW_REINIT, GFP_KERNEL)) + 0, GFP_KERNEL)) goto err;
ctx->flags = p->flags;
From: YiFei Zhu zhuyifei@google.com
[ Upstream commit 3ce4b78f73e8e00fb86bad67ee7f6fe12019707e ]
clang has -Wconstant-conversion by default, and the constant 0xAAAAAAAAA (9 As) being converted to an int, which is generally 32 bits, results in the compile warning:
clang -Wl,-no-as-needed -Wall -isystem ../../../../usr/include/ -lpthread seccomp_bpf.c -lcap -o seccomp_bpf seccomp_bpf.c:812:67: warning: implicit conversion from 'long' to 'int' changes value from 45812984490 to -1431655766 [-Wconstant-conversion] int kill = kill_how == KILL_PROCESS ? SECCOMP_RET_KILL_PROCESS : 0xAAAAAAAAA; ~~~~ ^~~~~~~~~~~ 1 warning generated.
-1431655766 is the expected truncation, 0xAAAAAAAA (8 As), so use this directly in the code to avoid the warning.
Fixes: 3932fcecd962 ("selftests/seccomp: Add test for unknown SECCOMP_RET kill behavior") Signed-off-by: YiFei Zhu zhuyifei@google.com Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20220526223407.1686936-1-zhuyifei@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/seccomp/seccomp_bpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 136df5b76319..4ae6c8991307 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -809,7 +809,7 @@ void kill_thread_or_group(struct __test_metadata *_metadata, .len = (unsigned short)ARRAY_SIZE(filter_thread), .filter = filter_thread, }; - int kill = kill_how == KILL_PROCESS ? SECCOMP_RET_KILL_PROCESS : 0xAAAAAAAAA; + int kill = kill_how == KILL_PROCESS ? SECCOMP_RET_KILL_PROCESS : 0xAAAAAAAA; struct sock_filter filter_process[] = { BPF_STMT(BPF_LD|BPF_W|BPF_ABS, offsetof(struct seccomp_data, nr)),
From: Markus Mayer mmayer@broadcom.com
[ Upstream commit 0cf51bfe999524377fbb71becb583b4ca6d07cfc ]
Include sys/time.h and pthread.h in tmon.h, so that types "pthread_mutex_t" and "struct timeval tv" are known when tmon.h references them.
Without these headers, compiling tmon against musl-libc will fail with these errors:
In file included from sysfs.c:31:0: tmon.h:47:8: error: unknown type name 'pthread_mutex_t' extern pthread_mutex_t input_lock; ^~~~~~~~~~~~~~~ make[3]: *** [<builtin>: sysfs.o] Error 1 make[3]: *** Waiting for unfinished jobs.... In file included from tui.c:31:0: tmon.h:54:17: error: field 'tv' has incomplete type struct timeval tv; ^~ make[3]: *** [<builtin>: tui.o] Error 1 make[2]: *** [Makefile:83: tmon] Error 2
Signed-off-by: Markus Mayer mmayer@broadcom.com Acked-by: Florian Fainelli f.fainelli@gmail.com Reviewed-by: Sumeet Pawnikar sumeet.r.pawnikar@intel.com Acked-by: Alejandro González alejandro.gonzalez.correo@gmail.com Tested-by: Alejandro González alejandro.gonzalez.correo@gmail.com Fixes: 94f69966faf8 ("tools/thermal: Introduce tmon, a tool for thermal subsystem") Link: https://lore.kernel.org/r/20220718031040.44714-1-f.fainelli@gmail.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/thermal/tmon/tmon.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/tools/thermal/tmon/tmon.h b/tools/thermal/tmon/tmon.h index c9066ec104dd..44d16d778f04 100644 --- a/tools/thermal/tmon/tmon.h +++ b/tools/thermal/tmon/tmon.h @@ -27,6 +27,9 @@ #define NR_LINES_TZDATA 1 #define TMON_LOG_FILE "/var/tmp/tmon.log"
+#include <sys/time.h> +#include <pthread.h> + extern unsigned long ticktime; extern double time_elapsed; extern unsigned long target_temp_user;
From: Colin Ian King colin.i.king@gmail.com
[ Upstream commit 5e5fd36c58d6c820f7292ee492c3731c9a104a41 ]
Currently if a fscanf fails then an early return leaks an open file pointer. Fix this by fclosing the file before the return. Detected using static analysis with cppcheck:
tools/power/x86/turbostat/turbostat.c:2039:3: error: Resource leak: fp [resourceLeak]
Fixes: eae97e053fe3 ("tools/power turbostat: Support thermal throttle count print") Signed-off-by: Colin Ian King colin.i.king@gmail.com Acked-by: Chen Yu yu.c.chen@intel.com Reviewed-by: Tom Rix trix@redhat.com Signed-off-by: Len Brown len.brown@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/power/x86/turbostat/turbostat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index ede31a4287a0..2e9a751af260 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -2035,9 +2035,9 @@ int get_core_throt_cnt(int cpu, unsigned long long *cnt) if (!fp) return -1; ret = fscanf(fp, "%lld", &tmp); + fclose(fp); if (ret != 1) return -1; - fclose(fp); *cnt = tmp;
return 0;
From: Mike Snitzer snitzer@kernel.org
[ Upstream commit e120a5f1e78fab6223544e425015f393d90d6f0d ]
Otherwise PR ops may be issued while the broader DM device is being reconfigured, etc.
Fixes: 9c72bad1f31a ("dm: call PR reserve/unreserve on each underlying device") Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/dm.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 2b75f1ef7386..7c5d4734f109 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -3066,6 +3066,11 @@ static int dm_call_pr(struct block_device *bdev, iterate_devices_callout_fn fn, goto out; ti = dm_table_get_target(table, 0);
+ if (dm_suspended_md(md)) { + ret = -EAGAIN; + goto out; + } + ret = -EINVAL; if (!ti->type->iterate_devices) goto out;
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 20550a61880fc55e68a0d290ad195b74729c0e7b ]
Instead of explicitly using PWM_SIFIVE_PWMCMP0 + pwm->hwpwm * PWM_SIFIVE_SIZE_PWMCMP for each access to one of the PWMCMP registers, introduce a macro that takes the hwpwm id as parameter.
For the register definition using a plain 4 instead of the cpp constant PWM_SIFIVE_SIZE_PWMCMP is easier to read, so define the offset macro without the constant. The latter can then be dropped as there are no users left.
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Tested-by: Emil Renner Berthing emil.renner.berthing@canonical.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-sifive.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c index e6d05a329002..b7fc33b08d82 100644 --- a/drivers/pwm/pwm-sifive.c +++ b/drivers/pwm/pwm-sifive.c @@ -23,7 +23,7 @@ #define PWM_SIFIVE_PWMCFG 0x0 #define PWM_SIFIVE_PWMCOUNT 0x8 #define PWM_SIFIVE_PWMS 0x10 -#define PWM_SIFIVE_PWMCMP0 0x20 +#define PWM_SIFIVE_PWMCMP(i) (0x20 + 4 * (i))
/* PWMCFG fields */ #define PWM_SIFIVE_PWMCFG_SCALE GENMASK(3, 0) @@ -36,8 +36,6 @@ #define PWM_SIFIVE_PWMCFG_GANG BIT(24) #define PWM_SIFIVE_PWMCFG_IP BIT(28)
-/* PWM_SIFIVE_SIZE_PWMCMP is used to calculate offset for pwmcmpX registers */ -#define PWM_SIFIVE_SIZE_PWMCMP 4 #define PWM_SIFIVE_CMPWIDTH 16 #define PWM_SIFIVE_DEFAULT_PERIOD 10000000
@@ -112,8 +110,7 @@ static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_sifive_ddata *ddata = pwm_sifive_chip_to_ddata(chip); u32 duty, val;
- duty = readl(ddata->regs + PWM_SIFIVE_PWMCMP0 + - pwm->hwpwm * PWM_SIFIVE_SIZE_PWMCMP); + duty = readl(ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm));
state->enabled = duty > 0;
@@ -193,8 +190,7 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm, pwm_sifive_update_clock(ddata, clk_get_rate(ddata->clk)); }
- writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP0 + - pwm->hwpwm * PWM_SIFIVE_SIZE_PWMCMP); + writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm));
if (state->enabled != enabled) pwm_sifive_enable(chip, state->enabled);
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit ace41d7564e655c39f709a78c035188a460c7cbd ]
.apply() assumes the clk to be for a given PWM iff the PWM is enabled. So make sure this is the case when .probe() completes. And in .remove() disable the according number of times.
This fixes a clk enable/disable imbalance, if some PWMs are already running at probe time.
Fixes: 9e37a53eb051 (pwm: sifive: Add a driver for SiFive SoC PWM) Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Tested-by: Emil Renner Berthing emil.renner.berthing@canonical.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-sifive.c | 46 ++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 9 deletions(-)
diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c index b7fc33b08d82..3fbc1d96fcb6 100644 --- a/drivers/pwm/pwm-sifive.c +++ b/drivers/pwm/pwm-sifive.c @@ -228,6 +228,8 @@ static int pwm_sifive_probe(struct platform_device *pdev) struct pwm_sifive_ddata *ddata; struct pwm_chip *chip; int ret; + u32 val; + unsigned int enabled_pwms = 0, enabled_clks = 1;
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); if (!ddata) @@ -254,6 +256,33 @@ static int pwm_sifive_probe(struct platform_device *pdev) return ret; }
+ val = readl(ddata->regs + PWM_SIFIVE_PWMCFG); + if (val & PWM_SIFIVE_PWMCFG_EN_ALWAYS) { + unsigned int i; + + for (i = 0; i < chip->npwm; ++i) { + val = readl(ddata->regs + PWM_SIFIVE_PWMCMP(i)); + if (val > 0) + ++enabled_pwms; + } + } + + /* The clk should be on once for each running PWM. */ + if (enabled_pwms) { + while (enabled_clks < enabled_pwms) { + /* This is not expected to fail as the clk is already on */ + ret = clk_enable(ddata->clk); + if (unlikely(ret)) { + dev_err_probe(dev, ret, "Failed to enable clk\n"); + goto disable_clk; + } + ++enabled_clks; + } + } else { + clk_disable(ddata->clk); + enabled_clks = 0; + } + /* Watch for changes to underlying clock frequency */ ddata->notifier.notifier_call = pwm_sifive_clock_notifier; ret = clk_notifier_register(ddata->clk, &ddata->notifier); @@ -276,7 +305,11 @@ static int pwm_sifive_probe(struct platform_device *pdev) unregister_clk: clk_notifier_unregister(ddata->clk, &ddata->notifier); disable_clk: - clk_disable_unprepare(ddata->clk); + while (enabled_clks) { + clk_disable(ddata->clk); + --enabled_clks; + } + clk_unprepare(ddata->clk);
return ret; } @@ -284,21 +317,16 @@ static int pwm_sifive_probe(struct platform_device *pdev) static int pwm_sifive_remove(struct platform_device *dev) { struct pwm_sifive_ddata *ddata = platform_get_drvdata(dev); - bool is_enabled = false; struct pwm_device *pwm; int ch;
for (ch = 0; ch < ddata->chip.npwm; ch++) { pwm = &ddata->chip.pwms[ch]; - if (pwm->state.enabled) { - is_enabled = true; - break; - } + if (pwm->state.enabled) + clk_disable(ddata->clk); } - if (is_enabled) - clk_disable(ddata->clk);
- clk_disable_unprepare(ddata->clk); + clk_unprepare(ddata->clk); pwmchip_remove(&ddata->chip); clk_notifier_unregister(ddata->clk, &ddata->notifier);
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 2375e964d541bb09158cd2dff67b5d74e8de61cd ]
The PWMs are expected to be functional until pwmchip_remove() is called. So disable the clks only afterwards.
Fixes: 9e37a53eb051 ("pwm: sifive: Add a driver for SiFive SoC PWM") Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Tested-by: Emil Renner Berthing emil.renner.berthing@canonical.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-sifive.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c index 3fbc1d96fcb6..1b61344c7cd1 100644 --- a/drivers/pwm/pwm-sifive.c +++ b/drivers/pwm/pwm-sifive.c @@ -320,6 +320,9 @@ static int pwm_sifive_remove(struct platform_device *dev) struct pwm_device *pwm; int ch;
+ pwmchip_remove(&ddata->chip); + clk_notifier_unregister(ddata->clk, &ddata->notifier); + for (ch = 0; ch < ddata->chip.npwm; ch++) { pwm = &ddata->chip.pwms[ch]; if (pwm->state.enabled) @@ -327,8 +330,6 @@ static int pwm_sifive_remove(struct platform_device *dev) }
clk_unprepare(ddata->clk); - pwmchip_remove(&ddata->chip); - clk_notifier_unregister(ddata->clk, &ddata->notifier);
return 0; }
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 8933d30c5f468d6cc1e4bf9bb535149da35f202e ]
The calculation:
val = (u64)NSEC_PER_SEC * LPC18XX_PWM_TIMER_MAX; do_div(val, lpc18xx_pwm->clk_rate); lpc18xx_pwm->max_period_ns = val;
is bogus because with NSEC_PER_SEC = 1000000000, LPC18XX_PWM_TIMER_MAX = 0xffffffff and clk_rate < NSEC_PER_SEC this overflows the (on lpc18xx (i.e. ARM32) 32 bit wide) unsigned int .max_period_ns. This results (dependant of the actual clk rate) in an arbitrary limitation of the maximal period. E.g. for clkrate = 333333333 (Hz) we get max_period_ns = 9 instead of 12884901897.
So make .max_period_ns an u64 and pass period and duty as u64 to not discard relevant digits. And also make use of mul_u64_u64_div_u64() which prevents all overflows assuming clk_rate < NSEC_PER_SEC.
Fixes: 841e6f90bb78 ("pwm: NXP LPC18xx PWM/SCT driver") Signed-off-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/pwm-lpc18xx-sct.c | 55 +++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 16 deletions(-)
diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c index 272e0b5d01b8..0de575747782 100644 --- a/drivers/pwm/pwm-lpc18xx-sct.c +++ b/drivers/pwm/pwm-lpc18xx-sct.c @@ -98,7 +98,7 @@ struct lpc18xx_pwm_chip { unsigned long clk_rate; unsigned int period_ns; unsigned int min_period_ns; - unsigned int max_period_ns; + u64 max_period_ns; unsigned int period_event; unsigned long event_map; struct mutex res_lock; @@ -145,40 +145,48 @@ static void lpc18xx_pwm_set_conflict_res(struct lpc18xx_pwm_chip *lpc18xx_pwm, mutex_unlock(&lpc18xx_pwm->res_lock); }
-static void lpc18xx_pwm_config_period(struct pwm_chip *chip, int period_ns) +static void lpc18xx_pwm_config_period(struct pwm_chip *chip, u64 period_ns) { struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip); - u64 val; + u32 val;
- val = (u64)period_ns * lpc18xx_pwm->clk_rate; - do_div(val, NSEC_PER_SEC); + /* + * With clk_rate < NSEC_PER_SEC this cannot overflow. + * With period_ns < max_period_ns this also fits into an u32. + * As period_ns >= min_period_ns = DIV_ROUND_UP(NSEC_PER_SEC, lpc18xx_pwm->clk_rate); + * we have val >= 1. + */ + val = mul_u64_u64_div_u64(period_ns, lpc18xx_pwm->clk_rate, NSEC_PER_SEC);
lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_MATCH(lpc18xx_pwm->period_event), - (u32)val - 1); + val - 1);
lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_MATCHREL(lpc18xx_pwm->period_event), - (u32)val - 1); + val - 1); }
static void lpc18xx_pwm_config_duty(struct pwm_chip *chip, - struct pwm_device *pwm, int duty_ns) + struct pwm_device *pwm, u64 duty_ns) { struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip); struct lpc18xx_pwm_data *lpc18xx_data = &lpc18xx_pwm->channeldata[pwm->hwpwm]; - u64 val; + u32 val;
- val = (u64)duty_ns * lpc18xx_pwm->clk_rate; - do_div(val, NSEC_PER_SEC); + /* + * With clk_rate < NSEC_PER_SEC this cannot overflow. + * With duty_ns <= period_ns < max_period_ns this also fits into an u32. + */ + val = mul_u64_u64_div_u64(duty_ns, lpc18xx_pwm->clk_rate, NSEC_PER_SEC);
lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_MATCH(lpc18xx_data->duty_event), - (u32)val); + val);
lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_MATCHREL(lpc18xx_data->duty_event), - (u32)val); + val); }
static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, @@ -377,12 +385,27 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev) goto disable_pwmclk; }
+ /* + * If clkrate is too fast, the calculations in .apply() might overflow. + */ + if (lpc18xx_pwm->clk_rate > NSEC_PER_SEC) { + ret = dev_err_probe(&pdev->dev, -EINVAL, "pwm clock to fast\n"); + goto disable_pwmclk; + } + + /* + * If clkrate is too fast, the calculations in .apply() might overflow. + */ + if (lpc18xx_pwm->clk_rate > NSEC_PER_SEC) { + ret = dev_err_probe(&pdev->dev, -EINVAL, "pwm clock to fast\n"); + goto disable_pwmclk; + } + mutex_init(&lpc18xx_pwm->res_lock); mutex_init(&lpc18xx_pwm->period_lock);
- val = (u64)NSEC_PER_SEC * LPC18XX_PWM_TIMER_MAX; - do_div(val, lpc18xx_pwm->clk_rate); - lpc18xx_pwm->max_period_ns = val; + lpc18xx_pwm->max_period_ns = + mul_u64_u64_div_u64(NSEC_PER_SEC, LPC18XX_PWM_TIMER_MAX, lpc18xx_pwm->clk_rate);
lpc18xx_pwm->min_period_ns = DIV_ROUND_UP(NSEC_PER_SEC, lpc18xx_pwm->clk_rate);
From: Hongnan Li hongnan.li@linux.alibaba.com
[ Upstream commit ecce9212d0fd7a2d4a4998f0c4623a66887e14c8 ]
erofs_readdir update ctx->pos after filling a batch of dentries and it may cause dir/files duplication for NFS readdirplus which depends on ctx->pos to fill dir correctly. So update ctx->pos for every emitted dirent in erofs_fill_dentries to fix it.
Also fix the update of ctx->pos when the initial file position has exceeded nameoff.
Fixes: 3e917cc305c6 ("erofs: make filesystem exportable") Signed-off-by: Hongnan Li hongnan.li@linux.alibaba.com Signed-off-by: Jeffle Xu jefflexu@linux.alibaba.com Reviewed-by: Gao Xiang hsiangkao@linux.alibaba.com Reviewed-by: Chao Yu chao@kernel.org Link: https://lore.kernel.org/r/20220722082732.30935-1-jefflexu@linux.alibaba.com Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/erofs/dir.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/fs/erofs/dir.c b/fs/erofs/dir.c index 18e59821c597..47c85f1b80d8 100644 --- a/fs/erofs/dir.c +++ b/fs/erofs/dir.c @@ -22,10 +22,9 @@ static void debug_one_dentry(unsigned char d_type, const char *de_name, }
static int erofs_fill_dentries(struct inode *dir, struct dir_context *ctx, - void *dentry_blk, unsigned int *ofs, + void *dentry_blk, struct erofs_dirent *de, unsigned int nameoff, unsigned int maxsize) { - struct erofs_dirent *de = dentry_blk + *ofs; const struct erofs_dirent *end = dentry_blk + nameoff;
while (de < end) { @@ -59,9 +58,8 @@ static int erofs_fill_dentries(struct inode *dir, struct dir_context *ctx, /* stopped by some reason */ return 1; ++de; - *ofs += sizeof(struct erofs_dirent); + ctx->pos += sizeof(struct erofs_dirent); } - *ofs = maxsize; return 0; }
@@ -95,7 +93,7 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx) "invalid de[0].nameoff %u @ nid %llu", nameoff, EROFS_I(dir)->nid); err = -EFSCORRUPTED; - goto skip_this; + break; }
maxsize = min_t(unsigned int, @@ -106,17 +104,17 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx) initial = false;
ofs = roundup(ofs, sizeof(struct erofs_dirent)); + ctx->pos = blknr_to_addr(i) + ofs; if (ofs >= nameoff) goto skip_this; }
- err = erofs_fill_dentries(dir, ctx, de, &ofs, + err = erofs_fill_dentries(dir, ctx, de, (void *)de + ofs, nameoff, maxsize); -skip_this: - ctx->pos = blknr_to_addr(i) + ofs; - if (err) break; +skip_this: + ctx->pos = blknr_to_addr(i) + maxsize; ++i; ofs = 0; }
From: Marek Vasut marex@denx.de
[ Upstream commit 16c8d76abe83d75b578d72ee22d25a52c764e14a ]
Add missing reg and reg-names properties for both 'LDB_CTRL' and 'LVDS_CTRL' registers.
Fixes: 463db5c2ed4ae ("drm: bridge: ldb: Implement simple Freescale i.MX8MP LDB bridge") Signed-off-by: Marek Vasut marex@denx.de Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com Cc: Lucas Stach l.stach@pengutronix.de Cc: Maxime Ripard maxime@cerno.tech Cc: Peng Fan peng.fan@nxp.com Cc: Rob Herring robh+dt@kernel.org Cc: Robby Cai robby.cai@nxp.com Cc: Robert Foss robert.foss@linaro.org Cc: Sam Ravnborg sam@ravnborg.org Cc: Thomas Zimmermann tzimmermann@suse.de Cc: devicetree@vger.kernel.org To: dri-devel@lists.freedesktop.org Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220504012601.423644-1-marex@... Signed-off-by: Sasha Levin sashal@kernel.org --- .../bindings/display/bridge/fsl,ldb.yaml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml index 77f174eee424..2ebaa43eb62e 100644 --- a/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml +++ b/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml @@ -24,6 +24,15 @@ properties: clock-names: const: ldb
+ reg: + minItems: 2 + maxItems: 2 + + reg-names: + items: + - const: ldb + - const: lvds + ports: $ref: /schemas/graph.yaml#/properties/ports
@@ -56,10 +65,15 @@ examples: #include <dt-bindings/clock/imx8mp-clock.h>
blk-ctrl { - bridge { + #address-cells = <1>; + #size-cells = <1>; + + bridge@5c { compatible = "fsl,imx8mp-ldb"; clocks = <&clk IMX8MP_CLK_MEDIA_LDB>; clock-names = "ldb"; + reg = <0x5c 0x4>, <0x128 0x4>; + reg-names = "ldb", "lvds";
ports { #address-cells = <1>;
From: Jani Nikula jani.nikula@intel.com
[ Upstream commit 1b93ff4d0679190e8812cd0d0b3aebfcba1ed883 ]
There are already too many choices here, take away the unused ones.
Cc: Tvrtko Ursulin tvrtko.ursulin@linux.intel.com Signed-off-by: Jani Nikula jani.nikula@intel.com Reviewed-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20220504183716.987793-1-jani.n... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/i915_gem.h | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.h b/drivers/gpu/drm/i915/i915_gem.h index d0752e5553db..b7b257f54d2e 100644 --- a/drivers/gpu/drm/i915/i915_gem.h +++ b/drivers/gpu/drm/i915/i915_gem.h @@ -54,9 +54,7 @@ struct drm_i915_private; } while(0) #define GEM_WARN_ON(expr) WARN_ON(expr)
-#define GEM_DEBUG_DECL(var) var #define GEM_DEBUG_EXEC(expr) expr -#define GEM_DEBUG_BUG_ON(expr) GEM_BUG_ON(expr) #define GEM_DEBUG_WARN_ON(expr) GEM_WARN_ON(expr)
#else @@ -66,9 +64,7 @@ struct drm_i915_private; #define GEM_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr) #define GEM_WARN_ON(expr) ({ unlikely(!!(expr)); })
-#define GEM_DEBUG_DECL(var) #define GEM_DEBUG_EXEC(expr) do { } while (0) -#define GEM_DEBUG_BUG_ON(expr) #define GEM_DEBUG_WARN_ON(expr) ({ BUILD_BUG_ON_INVALID(expr); 0; }) #endif
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 98526c5bbe3267d447ddd076b685439e3e1396c6 ]
This error path needs an unlock before returning.
Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Sascha Hauer s.hauer@pengutronix.de Signed-off-by: Heiko Stuebner heiko@sntech.de Link: https://patchwork.freedesktop.org/patch/msgid/YnjZQRV9lpub2ET8@kili Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 26ac91db0f35..d6e831576cd2 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -1524,6 +1524,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, if (ret < 0) { drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n", vp->id, ret); + vop2_unlock(vop2); return; }
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit a9ad5822366c5065e6a65fe5ff5090295ba98986 ]
The Freescale i.MX8MP LDB bridge is only present on Freescale i.MX8MP SoCs. Hence add a dependency on ARCH_MXC, to prevent asking the user about this driver when configuring a kernel without i.MX SoC support.
Fixes: 463db5c2ed4aed01 ("drm: bridge: ldb: Implement simple Freescale i.MX8MP LDB bridge") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Marek Vasut marex@denx.de Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/449e08ca791a3ca308de5477c1bdc1... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 307b135da2f6..449b1b5a76ac 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -78,6 +78,7 @@ config DRM_DISPLAY_CONNECTOR config DRM_FSL_LDB tristate "Freescale i.MX8MP LDB bridge" depends on OF + depends on ARCH_MXC || COMPILE_TEST select DRM_KMS_HELPER select DRM_PANEL_BRIDGE help
From: Xin Ji xji@analogixsemi.com
[ Upstream commit a77c2af0994e24ee36c7ffb6dc852770bdf06fb1 ]
As V4L2_FWNODE_BUS_TYPE_PARALLEL not properly descript for DPI interface, this patch use new defined V4L2_FWNODE_BUS_TYPE_DPI for it.
Fixes: fd0310b6fe7d ("drm/bridge: anx7625: add MIPI DPI input feature") Signed-off-by: Xin Ji xji@analogixsemi.com Tested-by: Chen-Yu Tsai wenst@chromium.org Acked-by: Robert Foss robert.foss@linaro.org Reviewed-by: Robert Foss robert.foss@linaro.org Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220422084720.959271-4-xji@an... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/anx7625.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 53a5da6c49dd..01f46d9189c1 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1623,14 +1623,14 @@ static int anx7625_parse_dt(struct device *dev,
anx7625_get_swing_setting(dev, pdata);
- pdata->is_dpi = 1; /* default dpi mode */ + pdata->is_dpi = 0; /* default dsi mode */ pdata->mipi_host_node = of_graph_get_remote_node(np, 0, 0); if (!pdata->mipi_host_node) { DRM_DEV_ERROR(dev, "fail to get internal panel.\n"); return -ENODEV; }
- bus_type = V4L2_FWNODE_BUS_TYPE_PARALLEL; + bus_type = 0; mipi_lanes = MAX_LANES_SUPPORT; ep0 = of_graph_get_endpoint_by_regs(np, 0, 0); if (ep0) { @@ -1640,8 +1640,8 @@ static int anx7625_parse_dt(struct device *dev, mipi_lanes = of_property_count_u32_elems(ep0, "data-lanes"); }
- if (bus_type == V4L2_FWNODE_BUS_TYPE_PARALLEL) /* bus type is Parallel(DSI) */ - pdata->is_dpi = 0; + if (bus_type == V4L2_FWNODE_BUS_TYPE_DPI) /* bus type is DPI */ + pdata->is_dpi = 1;
pdata->mipi_lanes = mipi_lanes; if (pdata->mipi_lanes > MAX_LANES_SUPPORT || pdata->mipi_lanes <= 0)
From: Thomas Zimmermann tzimmermann@suse.de
[ Upstream commit 5913ab941d6ea782e841234c76958c6872ea752d ]
DDC operation conflicts with concurrent mode setting. Acquire the driver's I/O lock in get_modes to prevent this. This change should have been part of commit 931e3f3a0e99 ("drm/mgag200: Protect concurrent access to I/O registers with lock"), but apparently got lost somewhere.
v3: * fix commit message to say 'drm/mgag200' (Jocelyn)
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Fixes: 931e3f3a0e99 ("drm/mgag200: Protect concurrent access to I/O registers with lock") Reviewed-by: Jocelyn Falempe jfalempe@redhat.com Tested-by: Jocelyn Falempe jfalempe@redhat.com Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Jocelyn Falempe jfalempe@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@redhat.com Cc: dri-devel@lists.freedesktop.org Link: https://patchwork.freedesktop.org/patch/msgid/20220516134343.6085-2-tzimmerm... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/mgag200/mgag200_mode.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index abde7655477d..4ad8d62c5631 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -667,16 +667,26 @@ static void mgag200_disable_display(struct mga_device *mdev)
static int mga_vga_get_modes(struct drm_connector *connector) { + struct mga_device *mdev = to_mga_device(connector->dev); struct mga_connector *mga_connector = to_mga_connector(connector); struct edid *edid; int ret = 0;
+ /* + * Protect access to I/O registers from concurrent modesetting + * by acquiring the I/O-register lock. + */ + mutex_lock(&mdev->rmmio_lock); + edid = drm_get_edid(connector, &mga_connector->i2c->adapter); if (edid) { drm_connector_update_edid_property(connector, edid); ret = drm_add_edid_modes(connector, edid); kfree(edid); } + + mutex_unlock(&mdev->rmmio_lock); + return ret; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 7381076809586528e2a812a709e2758916318a99 ]
of_find_device_by_node() takes reference, we should use put_device() to release it when not need anymore. Add missing put_device() in error path to avoid refcount leak.
Fixes: 0af5e0b41110 ("drm/meson: encoder_hdmi: switch to bridge DRM_BRIDGE_ATTACH_NO_CONNECTOR") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Reviewed-by: Neil Armstrong narmstrong@baylibre.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://patchwork.freedesktop.org/patch/msgid/20220511054052.51981-1-linmq00... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/meson/meson_encoder_hdmi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c index 5e306de6f485..de87f02cd388 100644 --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -435,8 +435,10 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) cec_fill_conn_info_from_drm(&conn_info, meson_encoder_hdmi->connector);
notifier = cec_notifier_conn_register(&pdev->dev, NULL, &conn_info); - if (!notifier) + if (!notifier) { + put_device(&pdev->dev); return -ENOMEM; + }
meson_encoder_hdmi->cec_notifier = notifier; }
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 39c28cdfb719f0e306b447f0827dfd712f81858b ]
While working on the DP AUX bus code I found a few small things that should be fixed. Namely the non-devm version of of_dp_aux_populate_ep_devices() was missing an export. There was also an extra blank line in a kerneldoc and a kerneldoc that incorrectly documented a return value. Fix these.
Fixes: aeb33699fc2c ("drm: Introduce the DP AUX bus") Signed-off-by: Douglas Anderson dianders@chromium.org Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220510122726.v3.1.Ia91f4849a... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/display/drm_dp_aux_bus.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c index dccf3e2ea323..552f949cff59 100644 --- a/drivers/gpu/drm/display/drm_dp_aux_bus.c +++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c @@ -66,7 +66,6 @@ static int dp_aux_ep_probe(struct device *dev) * @dev: The device to remove. * * Calls through to the endpoint driver remove. - * */ static void dp_aux_ep_remove(struct device *dev) { @@ -120,8 +119,6 @@ ATTRIBUTE_GROUPS(dp_aux_ep_dev); /** * dp_aux_ep_dev_release() - Free memory for the dp_aux_ep device * @dev: The device to free. - * - * Return: 0 if no error or negative error code. */ static void dp_aux_ep_dev_release(struct device *dev) { @@ -256,6 +253,7 @@ int of_dp_aux_populate_ep_devices(struct drm_dp_aux *aux)
return 0; } +EXPORT_SYMBOL_GPL(of_dp_aux_populate_ep_devices);
static void of_dp_aux_depopulate_ep_devices_void(void *data) {
From: Marek Vasut marex@denx.de
[ Upstream commit 0d662350928e6787d29ab205e47e5aa6f1f792f9 ]
Handle empty data-lanes = < >; property, which translates to dsi_lanes = 0 as invalid.
Reviewed-by: Andrzej Hajda andrzej.hajda@intel.com Reviewed-by: Lucas Stach l.stach@pengutronix.de Fixes: bbfd3190b6562 ("drm/bridge: tc358767: Add DSI-to-DPI mode support") Signed-off-by: Marek Vasut marex@denx.de Cc: Jonas Karlman jonas@kwiboo.se Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Lucas Stach l.stach@pengutronix.de Cc: Marek Vasut marex@denx.de Cc: Maxime Ripard maxime@cerno.tech Cc: Neil Armstrong narmstrong@baylibre.com Cc: Robert Foss robert.foss@linaro.org Cc: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/20220519095137.11896-1-marex@d... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358767.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 485717c8f0b4..466b8fc9836a 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -1871,7 +1871,7 @@ static int tc_mipi_dsi_host_attach(struct tc_data *tc) of_node_put(host_node); of_node_put(endpoint);
- if (dsi_lanes < 0 || dsi_lanes > 4) + if (dsi_lanes <= 0 || dsi_lanes > 4) return -EINVAL;
if (!host)
From: Marek Vasut marex@denx.de
[ Upstream commit 0b4c48f3e315d172e4cc06e10f2c8ba180788baf ]
The Refclk may be supplied by SoC clock output instead of crystal oscillator, make sure the clock are enabled before any other action is performed with the bridge chip, otherwise it may either fail to operate at all, or miss reset GPIO toggle.
Reviewed-by: Lucas Stach l.stach@pengutronix.de Fixes: 7caff0fc4296e ("drm/bridge: tc358767: Add DPI to eDP bridge driver") Signed-off-by: Marek Vasut marex@denx.de Cc: Jonas Karlman jonas@kwiboo.se Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Lucas Stach l.stach@pengutronix.de Cc: Marek Vasut marex@denx.de Cc: Maxime Ripard maxime@cerno.tech Cc: Neil Armstrong narmstrong@baylibre.com Cc: Robert Foss robert.foss@linaro.org Cc: Sam Ravnborg sam@ravnborg.org Reviewed-by: Maxime Ripard maxime@cerno.tech Link: https://patchwork.freedesktop.org/patch/msgid/20220520121543.11550-1-marex@d... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358767.c | 32 ++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 466b8fc9836a..16affb42086a 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -2004,6 +2004,13 @@ static int tc_probe_bridge_endpoint(struct tc_data *tc) return -EINVAL; }
+static void tc_clk_disable(void *data) +{ + struct clk *refclk = data; + + clk_disable_unprepare(refclk); +} + static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; @@ -2020,6 +2027,24 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id) if (ret) return ret;
+ tc->refclk = devm_clk_get(dev, "ref"); + if (IS_ERR(tc->refclk)) { + ret = PTR_ERR(tc->refclk); + dev_err(dev, "Failed to get refclk: %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(tc->refclk); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, tc_clk_disable, tc->refclk); + if (ret) + return ret; + + /* tRSTW = 100 cycles , at 13 MHz that is ~7.69 us */ + usleep_range(10, 15); + /* Shut down GPIO is optional */ tc->sd_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH); if (IS_ERR(tc->sd_gpio)) @@ -2040,13 +2065,6 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id) usleep_range(5000, 10000); }
- tc->refclk = devm_clk_get(dev, "ref"); - if (IS_ERR(tc->refclk)) { - ret = PTR_ERR(tc->refclk); - dev_err(dev, "Failed to get refclk: %d\n", ret); - return ret; - } - tc->regmap = devm_regmap_init_i2c(client, &tc_regmap_config); if (IS_ERR(tc->regmap)) { ret = PTR_ERR(tc->regmap);
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 1ee6c5abebd3cacf2ac4378d0ed4f57fd4850421 ]
Interrupt line can be configured on different hardware in different way, even inverted. Therefore driver should not enforce specific trigger type - edge rising - but instead rely on Devicetree to configure it.
All Qualcomm DTSI with WCN3990 define the interrupt type as level high, so the mismatch between DTSI and driver causes rebind issues:
$ echo 18800000.wifi > /sys/bus/platform/drivers/ath10k_snoc/unbind $ echo 18800000.wifi > /sys/bus/platform/drivers/ath10k_snoc/bind [ 44.763114] irq: type mismatch, failed to map hwirq-446 for interrupt-controller@17a00000! [ 44.763130] ath10k_snoc 18800000.wifi: error -ENXIO: IRQ index 0 not found [ 44.763140] ath10k_snoc 18800000.wifi: failed to initialize resource: -6
Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.2.0.c8-00009-QCAHLSWSC8180XMTPLZ-1 Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.2.0-01387-QCAHLSWMTPLZ-1
Fixes: c963a683e701 ("ath10k: add resource init and deinit for WCN3990") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Tested-by: Steev Klimaszewski steev@kali.org Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220513151516.357549-1-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/snoc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index 607e8164bf98..5576ad9fd116 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -1249,13 +1249,12 @@ static void ath10k_snoc_init_napi(struct ath10k *ar) static int ath10k_snoc_request_irq(struct ath10k *ar) { struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); - int irqflags = IRQF_TRIGGER_RISING; int ret, id;
for (id = 0; id < CE_COUNT_MAX; id++) { ret = request_irq(ar_snoc->ce_irqs[id].irq_line, - ath10k_snoc_per_engine_handler, - irqflags, ce_name[id], ar); + ath10k_snoc_per_engine_handler, 0, + ce_name[id], ar); if (ret) { ath10k_err(ar, "failed to register IRQ handler for CE %d: %d\n",
From: Baochen Qiang quic_bqiang@quicinc.com
[ Upstream commit 77bbbd5e0ed3b5998a353b0948584faa4f565f0e ]
We are seeing below warning: warn: variable dereferenced before check 'sar'
Fix it by moving ahead pointer check on 'sar'.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
Fixes: 652f69ed9c1b ("ath11k: Add support for SAR") Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Baochen Qiang quic_bqiang@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220517004844.2412660-1-quic_bqiang@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/mac.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index ee1590b16eff..7d574ad67e59 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -8297,11 +8297,15 @@ static int ath11k_mac_op_set_bios_sar_specs(struct ieee80211_hw *hw, const struct cfg80211_sar_specs *sar) { struct ath11k *ar = hw->priv; - const struct cfg80211_sar_sub_specs *sspec = sar->sub_specs; + const struct cfg80211_sar_sub_specs *sspec; int ret, index; u8 *sar_tbl; u32 i;
+ if (!sar || sar->type != NL80211_SAR_TYPE_POWER || + sar->num_sub_specs == 0) + return -EINVAL; + mutex_lock(&ar->conf_mutex);
if (!test_bit(WMI_TLV_SERVICE_BIOS_SAR_SUPPORT, ar->ab->wmi_ab.svc_map) || @@ -8310,12 +8314,6 @@ static int ath11k_mac_op_set_bios_sar_specs(struct ieee80211_hw *hw, goto exit; }
- if (!sar || sar->type != NL80211_SAR_TYPE_POWER || - sar->num_sub_specs == 0) { - ret = -EINVAL; - goto exit; - } - ret = ath11k_wmi_pdev_set_bios_geo_table_param(ar); if (ret) { ath11k_warn(ar->ab, "failed to set geo table: %d\n", ret); @@ -8328,6 +8326,7 @@ static int ath11k_mac_op_set_bios_sar_specs(struct ieee80211_hw *hw, goto exit; }
+ sspec = sar->sub_specs; for (i = 0; i < sar->num_sub_specs; i++) { if (sspec->freq_range_index >= (BIOS_SAR_TABLE_LEN >> 1)) { ath11k_warn(ar->ab, "Ignore bad frequency index %u, max allowed %u\n",
From: Manikanta Pubbisetty quic_mpubbise@quicinc.com
[ Upstream commit bebcfd2534a63ab7e7325f5337662bc84ca038b6 ]
As part of adding the support of WCN6750 to ath11k, bus_params were moved to hw_params and this regressed the initialization of WCN6750. By the time AHB resources are setup for WCN6750, hw_params will not be initialized and therefore initialization for WCN6750 will fail. This is applicable only for WCN6750, no other device is impacted.
Fix this by moving the initialization of hw_params before setting up AHB resources.
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1
Fixes: 00402f49d26f ("ath11k: Add support for WCN6750 device") Signed-off-by: Manikanta Pubbisetty quic_mpubbise@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220517055241.15885-1-quic_mpubbise@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/ahb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index fa11807f48a9..d7d33d5cdfc5 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -976,11 +976,11 @@ static int ath11k_ahb_probe(struct platform_device *pdev) ab->hw_rev = hw_rev; platform_set_drvdata(pdev, ab);
- ret = ath11k_ahb_setup_resources(ab); + ret = ath11k_core_pre_init(ab); if (ret) goto err_core_free;
- ret = ath11k_core_pre_init(ab); + ret = ath11k_ahb_setup_resources(ab); if (ret) goto err_core_free;
From: Jani Nikula jani.nikula@intel.com
[ Upstream commit d10f7117aa43b0b0d1c4b878afafb6d151da441d ]
If a NULL edid gets passed to drm_add_edid_modes(), we should probably also reset the display info.
Cc: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jani Nikula jani.nikula@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/2ac1c55f94a08d5e72c0b518d956a1... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_edid.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index bc43e1b32092..1dea0e2f0cab 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -5697,6 +5697,7 @@ static int drm_edid_connector_update(struct drm_connector *connector, u32 quirks;
if (edid == NULL) { + drm_reset_display_info(connector); clear_eld(connector); return 0; }
From: John Stultz jstultz@google.com
[ Upstream commit 649eb3828fb22e829e222ebd83f4e11dc503a565 ]
In commit 19cf41b64e3b ("lontium-lt9611: check a different register bit for HDMI sensing"), the bit flag used to detect HDMI cable connect was switched from BIT(2) to BIT(0) to improve compatibility with some monitors that didn't seem to set BIT(2).
However, with that change, I've seen occasional issues where the detection failed, because BIT(2) was set, but not BIT(0).
Unfortunately, as I understand it, the bits and their function was never clearly documented. So lets instead check both (BIT(2) | BIT(0)) when checking the register.
Cc: Yongqin Liu yongqin.liu@linaro.org Cc: Amit Pundir amit.pundir@linaro.org Cc: Peter Collingbourne pcc@google.com Cc: Vinod Koul vkoul@kernel.org Cc: Bjorn Andersson bjorn.andersson@linaro.org Cc: Robert Foss robert.foss@linaro.org Cc: kernel-team@android.com Fixes: 19cf41b64e3b ("lontium-lt9611: check a different register bit for HDMI sensing") Signed-off-by: John Stultz jstultz@google.com Reviewed-by: Robert Foss robert.foss@linaro.org Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220511012612.3297577-2-jstul... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/lontium-lt9611.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 7ef8fe5abc12..c0b182d1374e 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -586,7 +586,7 @@ lt9611_connector_detect(struct drm_connector *connector, bool force) int connected = 0;
regmap_read(lt9611->regmap, 0x825e, ®_val); - connected = (reg_val & BIT(0)); + connected = (reg_val & (BIT(2) | BIT(0)));
lt9611->status = connected ? connector_status_connected : connector_status_disconnected;
From: Javier Martinez Canillas javierm@redhat.com
[ Upstream commit 9ad6f181ad9a19a26bda73a7b199df44ccfcdaba ]
The SPI core always reports a "MODALIAS=spi:<foo>", even if the device was registered via OF. This means that the st7735r.ko module won't autoload if a DT has a node with a compatible "okaya,rh128128t" string.
In that case, kmod expects a "MODALIAS=of:N*T*Cokaya,rh128128t" uevent but instead will get a "MODALIAS=spi:rh128128t", which is not present in the list of aliases:
$ modinfo drivers/gpu/drm/tiny/st7735r.ko | grep alias alias: of:N*T*Cokaya,rh128128tC* alias: of:N*T*Cokaya,rh128128t alias: of:N*T*Cjianda,jd-t18003-t01C* alias: of:N*T*Cjianda,jd-t18003-t01 alias: spi:jd-t18003-t01
To workaround this issue, add in the SPI table an entry for that device.
Fixes: d1d511d516f7 ("drm: tiny: st7735r: Add support for Okaya RH128128T") Signed-off-by: Javier Martinez Canillas javierm@redhat.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Acked-by: David Lechner david@lechnology.com Link: https://patchwork.freedesktop.org/patch/msgid/20220520091602.179078-1-javier... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/tiny/st7735r.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c index 29d618093e94..e0f02d367d88 100644 --- a/drivers/gpu/drm/tiny/st7735r.c +++ b/drivers/gpu/drm/tiny/st7735r.c @@ -174,6 +174,7 @@ MODULE_DEVICE_TABLE(of, st7735r_of_match);
static const struct spi_device_id st7735r_id[] = { { "jd-t18003-t01", (uintptr_t)&jd_t18003_t01_cfg }, + { "rh128128t", (uintptr_t)&rh128128t_cfg }, { }, }; MODULE_DEVICE_TABLE(spi, st7735r_id);
From: Gao Chao gaochao49@huawei.com
[ Upstream commit a67664860f7833015a683ea295f7c79ac2901332 ]
If CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=y && CONFIG_DRM_DISPLAY_HELPER=m, bulding fails:
drivers/gpu/drm/panel/panel-samsung-atna33xc20.o: In function `atana33xc20_probe': panel-samsung-atna33xc20.c:(.text+0x744): undefined reference to `drm_panel_dp_aux_backlight' make: *** [vmlinux] Error 1
Let CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 select DRM_DISPLAY_DP_HELPER and CONFIG_DRM_DISPLAY_HELPER to fix this error.
Fixes: 32ce3b320343 ("drm/panel: atna33xc20: Introduce the Samsung ATNA33XC20 panel") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Gao Chao gaochao49@huawei.com Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Douglas Anderson dianders@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20220524024551.539-1-gaochao49... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 38799effd00a..4f1f004b3c54 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -438,6 +438,8 @@ config DRM_PANEL_SAMSUNG_ATNA33XC20 depends on OF depends on BACKLIGHT_CLASS_DEVICE depends on PM + select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_HELPER select DRM_DP_AUX_BUS help DRM panel driver for the Samsung ATNA33XC20 panel. This panel can't
From: Fabio Estevam festevam@gmail.com
[ Upstream commit 91776af1d8deb8f36cbec6bf2bf24b661b2b5cbb ]
ADV7511_REG_CEC_RX_FRAME_HDR[] and ADV7511_REG_CEC_RX_FRAME_LEN[] are only used inside adv7511_cec.c.
Move their definitions to this file to avoid the following build warnings when CONFIG_DRM_I2C_ADV7511_CEC is not selected:
drivers/gpu/drm/bridge/adv7511/adv7511.h:229:17: warning: 'ADV7511_REG_CEC_RX_FRAME_HDR' defined but not used [-Wunused-const-variable=] drivers/gpu/drm/bridge/adv7511/adv7511.h:235:17: warning: 'ADV7511_REG_CEC_RX_FRAME_LEN' defined but not used [-Wunused-const-variable=]
Reported-by: kernel test robot lkp@intel.com Fixes: ab0af093bf90 ("drm: bridge: adv7511: use non-legacy mode for CEC RX") Signed-off-by: Fabio Estevam festevam@gmail.com Reviewed-by: Alvin Šipraga alsi@bang-olufsen.dk Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220525215316.1133057-1-feste... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 12 ------------ drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 9e3bb8a8ee40..a031a0cd1f18 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -226,18 +226,6 @@ #define ADV7511_REG_CEC_CLK_DIV 0x4e #define ADV7511_REG_CEC_SOFT_RESET 0x50
-static const u8 ADV7511_REG_CEC_RX_FRAME_HDR[] = { - ADV7511_REG_CEC_RX1_FRAME_HDR, - ADV7511_REG_CEC_RX2_FRAME_HDR, - ADV7511_REG_CEC_RX3_FRAME_HDR, -}; - -static const u8 ADV7511_REG_CEC_RX_FRAME_LEN[] = { - ADV7511_REG_CEC_RX1_FRAME_LEN, - ADV7511_REG_CEC_RX2_FRAME_LEN, - ADV7511_REG_CEC_RX3_FRAME_LEN, -}; - #define ADV7533_REG_CEC_OFFSET 0x70
enum adv7511_input_clock { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c index 399f625a50c8..0b266f28f150 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c @@ -15,6 +15,18 @@
#include "adv7511.h"
+static const u8 ADV7511_REG_CEC_RX_FRAME_HDR[] = { + ADV7511_REG_CEC_RX1_FRAME_HDR, + ADV7511_REG_CEC_RX2_FRAME_HDR, + ADV7511_REG_CEC_RX3_FRAME_HDR, +}; + +static const u8 ADV7511_REG_CEC_RX_FRAME_LEN[] = { + ADV7511_REG_CEC_RX1_FRAME_LEN, + ADV7511_REG_CEC_RX2_FRAME_LEN, + ADV7511_REG_CEC_RX3_FRAME_LEN, +}; + #define ADV7511_INT1_CEC_MASK \ (ADV7511_INT1_CEC_TX_READY | ADV7511_INT1_CEC_TX_ARBIT_LOST | \ ADV7511_INT1_CEC_TX_RETRY_TIMEOUT | ADV7511_INT1_CEC_RX_READY1 | \
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit b88d28146c30a8e14f0f012d56ebf19b68a348f4 ]
If the copy_from_user() fails or the user gives invalid date then the correct thing to do is to return a negative error code. (Currently it returns success).
I made a copy additional related cleanups: 1) There is no need to check "buffer" for NULL. That's handled by copy_from_user(). 2) The "h2c_len" variable cannot be negative because it is unsigned and because sscanf() does not return negative error codes.
Fixes: 610247f46feb ("rtlwifi: Improve debugging by using debugfs") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/YoOLnDkHgVltyXK7@kili Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtlwifi/debug.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c index 901cdfe3723c..0b1bc04cb6ad 100644 --- a/drivers/net/wireless/realtek/rtlwifi/debug.c +++ b/drivers/net/wireless/realtek/rtlwifi/debug.c @@ -329,8 +329,8 @@ static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
- if (!buffer || copy_from_user(tmp, buffer, tmp_len)) - return count; + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT;
tmp[tmp_len] = '\0';
@@ -340,8 +340,8 @@ static ssize_t rtl_debugfs_set_write_h2c(struct file *filp, &h2c_data[4], &h2c_data[5], &h2c_data[6], &h2c_data[7]);
- if (h2c_len <= 0) - return count; + if (h2c_len == 0) + return -EINVAL;
for (i = 0; i < h2c_len; i++) h2c_data_packed[i] = (u8)h2c_data[i];
From: Ajay Singh ajay.kathat@microchip.com
[ Upstream commit fcf690b0b47494df51d214db5c5a714a400b0257 ]
For power-up sequence, WILC expects RESET set to high 5ms after making chip_en(enable) so corrected chip power-up sequence by making RESET high. For Power-Down sequence, the correct sequence make RESET and CHIP_EN low without any extra delay.
Fixes: ec031ac4792c ("wilc1000: Add reset/enable GPIO support to SPI driver") Signed-off-by: Ajay Singh ajay.kathat@microchip.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220524120606.9675-1-ajay.kathat@microchip.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/microchip/wilc1000/spi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 18420e954402..2ae8dd3411ac 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -191,11 +191,11 @@ static void wilc_wlan_power(struct wilc *wilc, bool on) /* assert ENABLE: */ gpiod_set_value(gpios->enable, 1); mdelay(5); - /* deassert RESET: */ - gpiod_set_value(gpios->reset, 0); - } else { /* assert RESET: */ gpiod_set_value(gpios->reset, 1); + } else { + /* deassert RESET: */ + gpiod_set_value(gpios->reset, 0); /* deassert ENABLE: */ gpiod_set_value(gpios->enable, 0); }
From: Johan Hovold johan+linaro@kernel.org
[ Upstream commit d4ba1ff87b17e81686ada8f429300876f55f95ad ]
Make sure to allocate resources needed before registering the device.
This specifically avoids having a racing open() trigger a BUG_ON() in mod_timer() when ath11k_mac_op_start() is called before the mon_reap_timer as been set up.
I did not see this issue with next-20220310, but I hit it on every probe with next-20220511. Perhaps some timing changed in between.
Here's the backtrace:
[ 51.346947] kernel BUG at kernel/time/timer.c:990! [ 51.346958] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ... [ 51.578225] Call trace: [ 51.583293] __mod_timer+0x298/0x390 [ 51.589518] mod_timer+0x14/0x20 [ 51.595368] ath11k_mac_op_start+0x41c/0x4a0 [ath11k] [ 51.603165] drv_start+0x38/0x60 [mac80211] [ 51.610110] ieee80211_do_open+0x29c/0x7d0 [mac80211] [ 51.617945] ieee80211_open+0x60/0xb0 [mac80211] [ 51.625311] __dev_open+0x100/0x1c0 [ 51.631420] __dev_change_flags+0x194/0x210 [ 51.638214] dev_change_flags+0x24/0x70 [ 51.644646] do_setlink+0x228/0xdb0 [ 51.650723] __rtnl_newlink+0x460/0x830 [ 51.657162] rtnl_newlink+0x4c/0x80 [ 51.663229] rtnetlink_rcv_msg+0x124/0x390 [ 51.669917] netlink_rcv_skb+0x58/0x130 [ 51.676314] rtnetlink_rcv+0x18/0x30 [ 51.682460] netlink_unicast+0x250/0x310 [ 51.688960] netlink_sendmsg+0x19c/0x3e0 [ 51.695458] ____sys_sendmsg+0x220/0x290 [ 51.701938] ___sys_sendmsg+0x7c/0xc0 [ 51.708148] __sys_sendmsg+0x68/0xd0 [ 51.714254] __arm64_sys_sendmsg+0x28/0x40 [ 51.720900] invoke_syscall+0x48/0x120
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Fixes: 840c36fa727a ("ath11k: dp: stop rx pktlog before suspend") Signed-off-by: Johan Hovold johan+linaro@kernel.org Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220517103436.15867-1-johan+linaro@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/core.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 1e98ff9ff288..c8e0bc935838 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1225,23 +1225,23 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab) return ret; }
- ret = ath11k_mac_register(ab); + ret = ath11k_dp_pdev_alloc(ab); if (ret) { - ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret); + ath11k_err(ab, "failed to attach DP pdev: %d\n", ret); goto err_pdev_debug; }
- ret = ath11k_dp_pdev_alloc(ab); + ret = ath11k_mac_register(ab); if (ret) { - ath11k_err(ab, "failed to attach DP pdev: %d\n", ret); - goto err_mac_unregister; + ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret); + goto err_dp_pdev_free; }
ret = ath11k_thermal_register(ab); if (ret) { ath11k_err(ab, "could not register thermal device: %d\n", ret); - goto err_dp_pdev_free; + goto err_mac_unregister; }
ret = ath11k_spectral_init(ab); @@ -1254,10 +1254,10 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab)
err_thermal_unregister: ath11k_thermal_unregister(ab); -err_dp_pdev_free: - ath11k_dp_pdev_free(ab); err_mac_unregister: ath11k_mac_unregister(ab); +err_dp_pdev_free: + ath11k_dp_pdev_free(ab); err_pdev_debug: ath11k_debugfs_pdev_destroy(ab);
From: Johan Hovold johan+linaro@kernel.org
[ Upstream commit 3bd0c69653ac636eae8872aacdcd4156f772f928 ]
Make sure to clear the IRQ affinity hint also on shutdown to avoid triggering a WARN_ON_ONCE() in __free_irq() when stopping MHI while using a single MSI vector.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
Fixes: e94b07493da3 ("ath11k: Set IRQ affinity to CPU0 in case of one MSI vector") Signed-off-by: Johan Hovold johan+linaro@kernel.org Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220523143258.24818-1-johan+linaro@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/pci.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index dedf1b88ddf6..487a303b3077 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -920,7 +920,9 @@ static void ath11k_pci_remove(struct pci_dev *pdev) static void ath11k_pci_shutdown(struct pci_dev *pdev) { struct ath11k_base *ab = pci_get_drvdata(pdev); + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+ ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); ath11k_pci_power_down(ab); }
From: Yunhao Tian t123yh.xyz@gmail.com
[ Upstream commit 435c249008cba04ed6a7975e9411f3b934620204 ]
In __spi_validate, there's a validation that no partial transfers are accepted (xfer->len % w_size must be zero). When max_chunk is not a multiple of bpw (e.g. max_chunk = 65535, bpw = 16), the transfer will be rejected.
This patch aligns max_chunk to 2 bytes (the maximum value of bpw is 16), so that no partial transfer will occur.
Fixes: d23d4d4dac01 ("drm/tinydrm: Move tinydrm_spi_transfer()")
Signed-off-by: Yunhao Tian t123yh.xyz@gmail.com Signed-off-by: Noralf Trønnes noralf@tronnes.org Link: https://patchwork.freedesktop.org/patch/msgid/20220510030219.2486687-1-t123y... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_mipi_dbi.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index 9314f2ead79f..09e4edb5a992 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -1199,6 +1199,13 @@ int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz, size_t chunk; int ret;
+ /* In __spi_validate, there's a validation that no partial transfers + * are accepted (xfer->len % w_size must be zero). + * Here we align max_chunk to multiple of 2 (16bits), + * to prevent transfers from being rejected. + */ + max_chunk = ALIGN_DOWN(max_chunk, 2); + spi_message_init_with_transfers(&m, &tr, 1);
while (len) {
From: Javier Martinez Canillas javierm@redhat.com
[ Upstream commit 01ece65132e2980ece4eca91105dfc9eed504881 ]
The kernel test robot reports a compile warning due the ssd130x_spi_table variable being defined but not used. This happen when ssd130x-spi driver is built-in instead of being built as a module, i.e:
CC drivers/gpu/drm/solomon/ssd130x-spi.o AR drivers/base/firmware_loader/built-in.a AR drivers/base/built-in.a CC kernel/trace/trace.o drivers/gpu/drm/solomon/ssd130x-spi.c:155:35: warning: ‘ssd130x_spi_table’ defined but not used [-Wunused-const-variable=] 155 | static const struct spi_device_id ssd130x_spi_table[] = { | ^~~~~~~~~~~~~~~~~
The driver shouldn't need a SPI device ID table and only have an OF device ID table, but the former is needed to workaround an issue in the SPI core. This always reports a MODALIAS of the form "spi:<device>" even for devices registered through Device Trees.
But the table is only needed when the driver built as a module to populate the .ko alias info. It's not needed when the driver is built-in the kernel.
Fixes: 74373977d2ca ("drm/solomon: Add SSD130x OLED displays SPI support") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Javier Martinez Canillas javierm@redhat.com Reviewed-by: Nathan Chancellor nathan@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20220530140246.742469-1-javier... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/solomon/ssd130x-spi.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c index 43722adab1f8..07802907e39a 100644 --- a/drivers/gpu/drm/solomon/ssd130x-spi.c +++ b/drivers/gpu/drm/solomon/ssd130x-spi.c @@ -143,6 +143,7 @@ static const struct of_device_id ssd130x_of_match[] = { }; MODULE_DEVICE_TABLE(of, ssd130x_of_match);
+#if IS_MODULE(CONFIG_DRM_SSD130X_SPI) /* * The SPI core always reports a MODALIAS uevent of the form "spi:<dev>", even * if the device was registered via OF. This means that the module will not be @@ -160,6 +161,7 @@ static const struct spi_device_id ssd130x_spi_table[] = { { /* sentinel */ } }; MODULE_DEVICE_TABLE(spi, ssd130x_spi_table); +#endif
static struct spi_driver ssd130x_spi_driver = { .driver = {
From: Yuntao Wang ytcoode@gmail.com
[ Upstream commit eb7b36ce47f830a01ad9405e673b563cc3638d5d ]
In the commit da00d2f117a0 ("bpf: Add test ops for BPF_PROG_TYPE_TRACING"), the bpf_fentry_test1 function was moved into bpf_prog_test_run_tracing(), which is the test_run function of the tracing BPF programs.
Thus calling 'bpf_prog_test_run_opts(filter_fd, &topts)' will not trigger bpf_fentry_test1 function as filter_fd is a sk_filter BPF program.
Fix it by replacing filter_fd with fexit_fd in the bpf_prog_test_run_opts() function.
Fixes: da00d2f117a0 ("bpf: Add test ops for BPF_PROG_TYPE_TRACING") Signed-off-by: Yuntao Wang ytcoode@gmail.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20220521151329.648013-1-ytcoode@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../selftests/bpf/prog_tests/fexit_stress.c | 32 +++---------------- 1 file changed, 4 insertions(+), 28 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_stress.c b/tools/testing/selftests/bpf/prog_tests/fexit_stress.c index a7e74297f15f..5a7e6011f6bf 100644 --- a/tools/testing/selftests/bpf/prog_tests/fexit_stress.c +++ b/tools/testing/selftests/bpf/prog_tests/fexit_stress.c @@ -7,11 +7,9 @@
void serial_test_fexit_stress(void) { - char test_skb[128] = {}; int fexit_fd[CNT] = {}; int link_fd[CNT] = {}; - char error[4096]; - int err, i, filter_fd; + int err, i;
const struct bpf_insn trace_program[] = { BPF_MOV64_IMM(BPF_REG_0, 0), @@ -20,25 +18,9 @@ void serial_test_fexit_stress(void)
LIBBPF_OPTS(bpf_prog_load_opts, trace_opts, .expected_attach_type = BPF_TRACE_FEXIT, - .log_buf = error, - .log_size = sizeof(error), );
- const struct bpf_insn skb_program[] = { - BPF_MOV64_IMM(BPF_REG_0, 0), - BPF_EXIT_INSN(), - }; - - LIBBPF_OPTS(bpf_prog_load_opts, skb_opts, - .log_buf = error, - .log_size = sizeof(error), - ); - - LIBBPF_OPTS(bpf_test_run_opts, topts, - .data_in = test_skb, - .data_size_in = sizeof(test_skb), - .repeat = 1, - ); + LIBBPF_OPTS(bpf_test_run_opts, topts);
err = libbpf_find_vmlinux_btf_id("bpf_fentry_test1", trace_opts.expected_attach_type); @@ -58,15 +40,9 @@ void serial_test_fexit_stress(void) goto out; }
- filter_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", - skb_program, sizeof(skb_program) / sizeof(struct bpf_insn), - &skb_opts); - if (!ASSERT_GE(filter_fd, 0, "test_program_loaded")) - goto out; + err = bpf_prog_test_run_opts(fexit_fd[0], &topts); + ASSERT_OK(err, "bpf_prog_test_run_opts");
- err = bpf_prog_test_run_opts(filter_fd, &topts); - close(filter_fd); - CHECK_FAIL(err); out: for (i = 0; i < CNT; i++) { if (link_fd[i])
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 200a89e3e88786b52bc1dd5f26a310c097f4c6a7 ]
Forward the packet to the kernel if the gw router mac address is missing in to trigger ARP discovery.
Fixes: 85bf1f51691c ("samples: bpf: Convert xdp_router_ipv4 to XDP samples helper") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/60bde5496d108089080504f58199bcf1143ea938.1653471... Signed-off-by: Sasha Levin sashal@kernel.org --- samples/bpf/xdp_router_ipv4.bpf.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/samples/bpf/xdp_router_ipv4.bpf.c b/samples/bpf/xdp_router_ipv4.bpf.c index 248119ca7938..0643330d1d2e 100644 --- a/samples/bpf/xdp_router_ipv4.bpf.c +++ b/samples/bpf/xdp_router_ipv4.bpf.c @@ -150,6 +150,15 @@ int xdp_router_ipv4_prog(struct xdp_md *ctx)
dest_mac = bpf_map_lookup_elem(&arp_table, &prefix_value->gw); + if (!dest_mac) { + /* Forward the packet to the kernel in + * order to trigger ARP discovery for + * the default gw. + */ + if (rec) + NO_TEAR_INC(rec->xdp_pass); + return XDP_PASS; + } } }
From: Martin KaFai Lau kafai@fb.com
[ Upstream commit e6ff92f41b65fce07365f1066fb13b5e42aca08d ]
tc_redirect_dtime was reported flaky from time to time. It always fails at the udp test and complains about the bpf@tc-ingress got a skb->tstamp when handling udp packet. It is unexpected because the skb->tstamp should have been cleared when crossing different netns.
The most likely cause is that the skb is actually a tcp packet from the earlier tcp test. It could be the final TCP_FIN handling.
This patch tightens the skb->tstamp check in the bpf prog. It ensures the skb is the current testing traffic. First, it checks that skb matches the IPPROTO of the running test (i.e. tcp vs udp). Second, it checks the server port (dst_ns_port). The server port is unique for each test (50000 + test_enum).
Also fixed a typo in test_udp_dtime(): s/P100/P101/
Fixes: c803475fd8dd ("bpf: selftests: test skb->tstamp in redirect_neigh") Reported-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Martin KaFai Lau kafai@fb.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Song Liu songliubraving@fb.com Link: https://lore.kernel.org/bpf/20220601234050.2572671-1-kafai@fb.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../selftests/bpf/prog_tests/tc_redirect.c | 8 +-- .../selftests/bpf/progs/test_tc_dtime.c | 53 ++++++++++++++++++- 2 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c index 958dae769c52..cb6a53b3e023 100644 --- a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c +++ b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c @@ -646,7 +646,7 @@ static void test_tcp_clear_dtime(struct test_tc_dtime *skel) __u32 *errs = skel->bss->errs[t];
skel->bss->test = t; - test_inet_dtime(AF_INET6, SOCK_STREAM, IP6_DST, 0); + test_inet_dtime(AF_INET6, SOCK_STREAM, IP6_DST, 50000 + t);
ASSERT_EQ(dtimes[INGRESS_FWDNS_P100], 0, dtime_cnt_str(t, INGRESS_FWDNS_P100)); @@ -683,7 +683,7 @@ static void test_tcp_dtime(struct test_tc_dtime *skel, int family, bool bpf_fwd) errs = skel->bss->errs[t];
skel->bss->test = t; - test_inet_dtime(family, SOCK_STREAM, addr, 0); + test_inet_dtime(family, SOCK_STREAM, addr, 50000 + t);
/* fwdns_prio100 prog does not read delivery_time_type, so * kernel puts the (rcv) timetamp in __sk_buff->tstamp @@ -715,13 +715,13 @@ static void test_udp_dtime(struct test_tc_dtime *skel, int family, bool bpf_fwd) errs = skel->bss->errs[t];
skel->bss->test = t; - test_inet_dtime(family, SOCK_DGRAM, addr, 0); + test_inet_dtime(family, SOCK_DGRAM, addr, 50000 + t);
ASSERT_EQ(dtimes[INGRESS_FWDNS_P100], 0, dtime_cnt_str(t, INGRESS_FWDNS_P100)); /* non mono delivery time is not forwarded */ ASSERT_EQ(dtimes[INGRESS_FWDNS_P101], 0, - dtime_cnt_str(t, INGRESS_FWDNS_P100)); + dtime_cnt_str(t, INGRESS_FWDNS_P101)); for (i = EGRESS_FWDNS_P100; i < SET_DTIME; i++) ASSERT_GT(dtimes[i], 0, dtime_cnt_str(t, i));
diff --git a/tools/testing/selftests/bpf/progs/test_tc_dtime.c b/tools/testing/selftests/bpf/progs/test_tc_dtime.c index 06f300d06dbd..b596479a9ebe 100644 --- a/tools/testing/selftests/bpf/progs/test_tc_dtime.c +++ b/tools/testing/selftests/bpf/progs/test_tc_dtime.c @@ -11,6 +11,8 @@ #include <linux/in.h> #include <linux/ip.h> #include <linux/ipv6.h> +#include <linux/tcp.h> +#include <linux/udp.h> #include <bpf/bpf_helpers.h> #include <bpf/bpf_endian.h> #include <sys/socket.h> @@ -115,6 +117,19 @@ static bool bpf_fwd(void) return test < TCP_IP4_RT_FWD; }
+static __u8 get_proto(void) +{ + switch (test) { + case UDP_IP4: + case UDP_IP6: + case UDP_IP4_RT_FWD: + case UDP_IP6_RT_FWD: + return IPPROTO_UDP; + default: + return IPPROTO_TCP; + } +} + /* -1: parse error: TC_ACT_SHOT * 0: not testing traffic: TC_ACT_OK * >0: first byte is the inet_proto, second byte has the netns @@ -122,11 +137,16 @@ static bool bpf_fwd(void) */ static int skb_get_type(struct __sk_buff *skb) { + __u16 dst_ns_port = __bpf_htons(50000 + test); void *data_end = ctx_ptr(skb->data_end); void *data = ctx_ptr(skb->data); __u8 inet_proto = 0, ns = 0; struct ipv6hdr *ip6h; + __u16 sport, dport; struct iphdr *iph; + struct tcphdr *th; + struct udphdr *uh; + void *trans;
switch (skb->protocol) { case __bpf_htons(ETH_P_IP): @@ -138,6 +158,7 @@ static int skb_get_type(struct __sk_buff *skb) else if (iph->saddr == ip4_dst) ns = DST_NS; inet_proto = iph->protocol; + trans = iph + 1; break; case __bpf_htons(ETH_P_IPV6): ip6h = data + sizeof(struct ethhdr); @@ -148,15 +169,43 @@ static int skb_get_type(struct __sk_buff *skb) else if (v6_equal(ip6h->saddr, (struct in6_addr)ip6_dst)) ns = DST_NS; inet_proto = ip6h->nexthdr; + trans = ip6h + 1; break; default: return 0; }
- if ((inet_proto != IPPROTO_TCP && inet_proto != IPPROTO_UDP) || !ns) + /* skb is not from src_ns or dst_ns. + * skb is not the testing IPPROTO. + */ + if (!ns || inet_proto != get_proto()) return 0;
- return (ns << 8 | inet_proto); + switch (inet_proto) { + case IPPROTO_TCP: + th = trans; + if (th + 1 > data_end) + return -1; + sport = th->source; + dport = th->dest; + break; + case IPPROTO_UDP: + uh = trans; + if (uh + 1 > data_end) + return -1; + sport = uh->source; + dport = uh->dest; + break; + default: + return 0; + } + + /* The skb is the testing traffic */ + if ((ns == SRC_NS && dport == dst_ns_port) || + (ns == DST_NS && sport == dst_ns_port)) + return (ns << 8 | inet_proto); + + return 0; }
/* format: direction@iface@netns
From: Yuze Chi chiyuze@google.com
[ Upstream commit 611edf1bacc51355ccb497915695db7f869cb382 ]
Move the correct definition from linker.c into libbpf_internal.h.
Fixes: 0087a681fa8c ("libbpf: Automatically fix up BPF_MAP_TYPE_RINGBUF size, if necessary") Reported-by: Yuze Chi chiyuze@google.com Signed-off-by: Yuze Chi chiyuze@google.com Signed-off-by: Ian Rogers irogers@google.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20220603055156.2830463-1-irogers@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 5 ----- tools/lib/bpf/libbpf_internal.h | 5 +++++ tools/lib/bpf/linker.c | 5 ----- 3 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index e89cc9c885b3..526bd6cd84a0 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -4943,11 +4943,6 @@ bpf_object__populate_internal_map(struct bpf_object *obj, struct bpf_map *map)
static void bpf_map__destroy(struct bpf_map *map);
-static bool is_pow_of_2(size_t x) -{ - return x && (x & (x - 1)); -} - static size_t adjust_ringbuf_sz(size_t sz) { __u32 page_sz = sysconf(_SC_PAGE_SIZE); diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index 4abdbe2fea9d..ef5d975078e5 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -580,4 +580,9 @@ struct bpf_link * usdt_manager_attach_usdt(struct usdt_manager *man, const char *usdt_provider, const char *usdt_name, __u64 usdt_cookie);
+static inline bool is_pow_of_2(size_t x) +{ + return x && (x & (x - 1)) == 0; +} + #endif /* __LIBBPF_LIBBPF_INTERNAL_H */ diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c index 9aa016fb55aa..85c0fddf55d1 100644 --- a/tools/lib/bpf/linker.c +++ b/tools/lib/bpf/linker.c @@ -697,11 +697,6 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, return err; }
-static bool is_pow_of_2(size_t x) -{ - return x && (x & (x - 1)) == 0; -} - static int linker_sanity_check_elf(struct src_obj *obj) { struct src_sec *sec;
From: Christian 'Ansuel' Marangi ansuelsmth@gmail.com
[ Upstream commit e5646fe3b7ef739c392e59da7db6adf5e1fdef42 ]
On htc_tx_completion error the skb is not dropped. This is wrong since the completion_handler logic expect the skb to be consumed anyway even when an error is triggered. Not freeing the skb on error is a memory leak since the skb won't be freed anywere else. Correctly free the packet on eid >= ATH11K_HTC_EP_COUNT before returning.
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
Fixes: f951380a6022 ("ath11k: Disabling credit flow for WMI path") Signed-off-by: Christian 'Ansuel' Marangi ansuelsmth@gmail.com Reviewed-by: Jeff Johnson quic_jjohnson@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220528142516.20819-2-ansuelsmth@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/htc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath11k/htc.c b/drivers/net/wireless/ath/ath11k/htc.c index 069c29a4fac7..ca3aedc0252d 100644 --- a/drivers/net/wireless/ath/ath11k/htc.c +++ b/drivers/net/wireless/ath/ath11k/htc.c @@ -258,8 +258,10 @@ void ath11k_htc_tx_completion_handler(struct ath11k_base *ab, u8 eid;
eid = ATH11K_SKB_CB(skb)->eid; - if (eid >= ATH11K_HTC_EP_COUNT) + if (eid >= ATH11K_HTC_EP_COUNT) { + dev_kfree_skb_any(skb); return; + }
ep = &htc->endpoint[eid]; spin_lock_bh(&htc->tx_lock);
From: Manikanta Pubbisetty quic_mpubbise@quicinc.com
[ Upstream commit 9331f7d3c54a263bede5055e106e40b28d0bd937 ]
Currently a couple of debug_mask entries are mapped to the same value, this could enable unintended driver logging. If enabling DP_TX logs was the intention, then this could also enable PCI logs flooding the dmesg buffer or vice versa. Fix this by correctly assigning the debug masks.
Found during code review.
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1
Fixes: aa2092a9bab3f ("ath11k: add raw mode and software crypto support") Signed-off-by: Manikanta Pubbisetty quic_mpubbise@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220602115621.15339-1-quic_mpubbise@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/debug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/debug.h b/drivers/net/wireless/ath/ath11k/debug.h index fbbd5fe02aa8..91545640c47b 100644 --- a/drivers/net/wireless/ath/ath11k/debug.h +++ b/drivers/net/wireless/ath/ath11k/debug.h @@ -23,8 +23,8 @@ enum ath11k_debug_mask { ATH11K_DBG_TESTMODE = 0x00000400, ATH11k_DBG_HAL = 0x00000800, ATH11K_DBG_PCI = 0x00001000, - ATH11K_DBG_DP_TX = 0x00001000, - ATH11K_DBG_DP_RX = 0x00002000, + ATH11K_DBG_DP_TX = 0x00002000, + ATH11K_DBG_DP_RX = 0x00004000, ATH11K_DBG_ANY = 0xffffffff, };
From: Manikanta Pubbisetty quic_mpubbise@quicinc.com
[ Upstream commit 0ab52b2bd7be8fd49c8ade7703c1faa15359c6c5 ]
Currently when firmware recovery is in progress, we do not queue REO commands to the firmware, instead -ESHUTDOWN will be returned to the caller leading to a failure print on the console. The REO command in the problem scenario is sent for all tids of a peer in which case we will have 16 failure prints on the console for a single peer. For an AP usecase, this count would be even higher in a worst case scenario. Since these commands are bound to fail during firmware recovery, it is better to avoid printing these failures and thereby avoid message flooding on the console.
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1
Fixes: 8ee8d38ca472 ("ath11k: Fix crash during firmware recovery on reo cmd ring access") Signed-off-by: Manikanta Pubbisetty quic_mpubbise@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220602122929.18896-1-quic_mpubbise@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/dp_rx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 049774cc158c..b3e133add1ce 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -835,8 +835,9 @@ void ath11k_peer_rx_tid_delete(struct ath11k *ar, HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, ath11k_dp_rx_tid_del_func); if (ret) { - ath11k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", - tid, ret); + if (ret != -ESHUTDOWN) + ath11k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", + tid, ret); dma_unmap_single(ar->ab->dev, rx_tid->paddr, rx_tid->size, DMA_BIDIRECTIONAL); kfree(rx_tid->vaddr);
From: Alexey Kodanev aleksei.kodanev@bell-sw.com
[ Upstream commit 136f614931a2bb73616b292cf542da3a18daefd5 ]
The last case label can write two buffers 'mc_reg_address[j]' and 'mc_data[j]' with 'j' offset equal to SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE since there are no checks for this value in both case labels after the last 'j++'.
Instead of changing '>' to '>=' there, add the bounds check at the start of the second 'case' (the first one already has it).
Also, remove redundant last checks for 'j' index bigger than array size. The expression is always false. Moreover, before or after the patch 'table->last' can be equal to SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE and it seems it can be a valid value.
Detected using the static analysis tool - Svace. Fixes: 69e0b57a91ad ("drm/radeon/kms: add dpm support for cayman (v5)") Signed-off-by: Alexey Kodanev aleksei.kodanev@bell-sw.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/radeon/ni_dpm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 769f666335ac..672d2239293e 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -2741,10 +2741,10 @@ static int ni_set_mc_special_registers(struct radeon_device *rdev, table->mc_reg_table_entry[k].mc_data[j] |= 0x100; } j++; - if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE) - return -EINVAL; break; case MC_SEQ_RESERVE_M >> 2: + if (j >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE) + return -EINVAL; temp_reg = RREG32(MC_PMG_CMD_MRS1); table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2; table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2; @@ -2753,8 +2753,6 @@ static int ni_set_mc_special_registers(struct radeon_device *rdev, (temp_reg & 0xffff0000) | (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); j++; - if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE) - return -EINVAL; break; default: break;
From: Xinlei Lee xinlei.lee@mediatek.com
[ Upstream commit 7f6335c6a258edf4d5ff1b904bc033188dc7b48b ]
Because .enable & .disable are deprecated. Use .atomic_enable & .atomic_disable instead.
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/1653012007-11854-2... Signed-off-by: Jitao Shi jitao.shi@mediatek.com Signed-off-by: Xinlei Lee xinlei.lee@mediatek.com Reviewed-by: Rex-BC Chen rex-bc.chen@mediatek.com Signed-off-by: Chun-Kuang Hu chunkuang.hu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/mediatek/mtk_dsi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index d9f10a33e6fa..6e7793f935da 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -763,14 +763,16 @@ static void mtk_dsi_bridge_mode_set(struct drm_bridge *bridge, drm_display_mode_to_videomode(adjusted, &dsi->vm); }
-static void mtk_dsi_bridge_disable(struct drm_bridge *bridge) +static void mtk_dsi_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct mtk_dsi *dsi = bridge_to_dsi(bridge);
mtk_output_dsi_disable(dsi); }
-static void mtk_dsi_bridge_enable(struct drm_bridge *bridge) +static void mtk_dsi_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct mtk_dsi *dsi = bridge_to_dsi(bridge);
@@ -779,8 +781,8 @@ static void mtk_dsi_bridge_enable(struct drm_bridge *bridge)
static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = { .attach = mtk_dsi_bridge_attach, - .disable = mtk_dsi_bridge_disable, - .enable = mtk_dsi_bridge_enable, + .atomic_disable = mtk_dsi_bridge_atomic_disable, + .atomic_enable = mtk_dsi_bridge_atomic_enable, .mode_set = mtk_dsi_bridge_mode_set, };
From: Jitao Shi jitao.shi@mediatek.com
[ Upstream commit cde7e2e35c2866d22a3a012e72a41052dfcc255d ]
In order to match the changes of "Use the drm_panel_bridge API", the poweron/poweroff of dsi is extracted from enable/disable and defined as new funcs (atomic_pre_enable/atomic_post_disable).
Since dsi_poweron is moved from dsi_enable to pre_enable function, in order to avoid poweron failure, the operation of dsi register fails to cause bus hang. Therefore, the protection mechanism is added to the dsi_enable function.
Fixes: 2dd8075d2185 ("drm/mediatek: mtk_dsi: Use the drm_panel_bridge API")
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/1653012007-11854-3... Signed-off-by: Jitao Shi jitao.shi@mediatek.com Signed-off-by: Xinlei Lee xinlei.lee@mediatek.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Rex-BC Chen rex-bc.chen@mediatek.com Signed-off-by: Chun-Kuang Hu chunkuang.hu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/mediatek/mtk_dsi.c | 53 +++++++++++++++++++----------- 1 file changed, 34 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 6e7793f935da..966a4729bb41 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -691,16 +691,6 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi) if (--dsi->refcount != 0) return;
- /* - * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since - * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(), - * which needs irq for vblank, and mtk_dsi_stop() will disable irq. - * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(), - * after dsi is fully set. - */ - mtk_dsi_stop(dsi); - - mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500); mtk_dsi_reset_engine(dsi); mtk_dsi_lane0_ulp_mode_enter(dsi); mtk_dsi_clk_ulp_mode_enter(dsi); @@ -715,17 +705,9 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
static void mtk_output_dsi_enable(struct mtk_dsi *dsi) { - int ret; - if (dsi->enabled) return;
- ret = mtk_dsi_poweron(dsi); - if (ret < 0) { - DRM_ERROR("failed to power on dsi\n"); - return; - } - mtk_dsi_set_mode(dsi); mtk_dsi_clk_hs_mode(dsi, 1);
@@ -739,7 +721,16 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi) if (!dsi->enabled) return;
- mtk_dsi_poweroff(dsi); + /* + * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since + * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(), + * which needs irq for vblank, and mtk_dsi_stop() will disable irq. + * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(), + * after dsi is fully set. + */ + mtk_dsi_stop(dsi); + + mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
dsi->enabled = false; } @@ -776,13 +767,37 @@ static void mtk_dsi_bridge_atomic_enable(struct drm_bridge *bridge, { struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+ if (dsi->refcount == 0) + return; + mtk_output_dsi_enable(dsi); }
+static void mtk_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) +{ + struct mtk_dsi *dsi = bridge_to_dsi(bridge); + int ret; + + ret = mtk_dsi_poweron(dsi); + if (ret < 0) + DRM_ERROR("failed to power on dsi\n"); +} + +static void mtk_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) +{ + struct mtk_dsi *dsi = bridge_to_dsi(bridge); + + mtk_dsi_poweroff(dsi); +} + static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = { .attach = mtk_dsi_bridge_attach, .atomic_disable = mtk_dsi_bridge_atomic_disable, .atomic_enable = mtk_dsi_bridge_atomic_enable, + .atomic_pre_enable = mtk_dsi_bridge_atomic_pre_enable, + .atomic_post_disable = mtk_dsi_bridge_atomic_post_disable, .mode_set = mtk_dsi_bridge_mode_set, };
From: Xinlei Lee xinlei.lee@mediatek.com
[ Upstream commit fa5d0a0205c34734c5b8daa77e39ac2817f63a10 ]
In the dsi_enable function, mtk_dsi_rxtx_control is to pull up the MIPI signal operation. Before dsi_disable, MIPI should also be pulled down by writing a register instead of disabling dsi.
If disable dsi without pulling the mipi signal low, the value of the register will still maintain the setting of the mipi signal being pulled high. After resume, even if the mipi signal is not pulled high, it will still be in the high state.
Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver")
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/1653012007-11854-5... Signed-off-by: Jitao Shi jitao.shi@mediatek.com Signed-off-by: Xinlei Lee xinlei.lee@mediatek.com Reviewed-by: Rex-BC Chen rex-bc.chen@mediatek.com Signed-off-by: Chun-Kuang Hu chunkuang.hu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/mediatek/mtk_dsi.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 966a4729bb41..e9764c2e0262 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -694,6 +694,8 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi) mtk_dsi_reset_engine(dsi); mtk_dsi_lane0_ulp_mode_enter(dsi); mtk_dsi_clk_ulp_mode_enter(dsi); + /* set the lane number as 0 to pull down mipi */ + writel(0, dsi->regs + DSI_TXRX_CTRL);
mtk_dsi_disable(dsi);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 7d255ddbbf679aa47e041cbf68520fd985ed2279 ]
of_graph_get_remote_node() returns remote device nodepointer with refcount incremented, we should use of_node_put() on it when done. Add missing of_node_put() to avoid refcount leak.
Fixes: 318ba02cd8a8 ("drm/meson: encoder_cvbs: switch to bridge with ATTACH_NO_CONNECTOR") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://patchwork.freedesktop.org/patch/msgid/20220601033927.47814-2-linmq00... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/meson/meson_encoder_cvbs.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c index fd8db97ba8ba..8110a6e39320 100644 --- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c @@ -238,6 +238,7 @@ int meson_encoder_cvbs_init(struct meson_drm *priv) }
meson_encoder_cvbs->next_bridge = of_drm_find_bridge(remote); + of_node_put(remote); if (!meson_encoder_cvbs->next_bridge) { dev_err(priv->dev, "Failed to find CVBS Connector bridge\n"); return -EPROBE_DEFER;
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit d82a5a4aae9d0203234737caed1bf470aa317568 ]
of_graph_get_remote_node() returns remote device nodepointer with refcount incremented, we should use of_node_put() on it when done. Add missing of_node_put() to avoid refcount leak.
Fixes: e67f6037ae1b ("drm/meson: split out encoder from meson_dw_hdmi") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://patchwork.freedesktop.org/patch/msgid/20220601033927.47814-3-linmq00... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/meson/meson_encoder_hdmi.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c index de87f02cd388..a7692584487c 100644 --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -365,7 +365,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) meson_encoder_hdmi->next_bridge = of_drm_find_bridge(remote); if (!meson_encoder_hdmi->next_bridge) { dev_err(priv->dev, "Failed to find HDMI transceiver bridge\n"); - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto err_put_node; }
/* HDMI Encoder Bridge */ @@ -383,7 +384,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) DRM_MODE_ENCODER_TMDS); if (ret) { dev_err(priv->dev, "Failed to init HDMI encoder: %d\n", ret); - return ret; + goto err_put_node; }
meson_encoder_hdmi->encoder.possible_crtcs = BIT(0); @@ -393,7 +394,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) DRM_BRIDGE_ATTACH_NO_CONNECTOR); if (ret) { dev_err(priv->dev, "Failed to attach bridge: %d\n", ret); - return ret; + goto err_put_node; }
/* Initialize & attach Bridge Connector */ @@ -401,7 +402,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) &meson_encoder_hdmi->encoder); if (IS_ERR(meson_encoder_hdmi->connector)) { dev_err(priv->dev, "Unable to create HDMI bridge connector\n"); - return PTR_ERR(meson_encoder_hdmi->connector); + ret = PTR_ERR(meson_encoder_hdmi->connector); + goto err_put_node; } drm_connector_attach_encoder(meson_encoder_hdmi->connector, &meson_encoder_hdmi->encoder); @@ -428,6 +430,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) meson_encoder_hdmi->connector->ycbcr_420_allowed = true;
pdev = of_find_device_by_node(remote); + of_node_put(remote); if (pdev) { struct cec_connector_info conn_info; struct cec_notifier *notifier; @@ -446,4 +449,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv) dev_dbg(priv->dev, "HDMI encoder initialized\n");
return 0; + +err_put_node: + of_node_put(remote); + return ret; }
From: Bjorn Andersson bjorn.andersson@linaro.org
[ Upstream commit dfa687bffc8a4a21ed929c7dececf01b8f1f52ee ]
During device remove care needs to be taken that no work is pending before it removes the underlying DRM bridge etc, but this can be done on the specific work rather than waiting for the flush of the system-wide workqueue.
Fixes: bc6fa8676ebb ("drm/bridge/lontium-lt9611uxc: move HPD notification out of IRQ handler") Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Reviewed-by: Neil Armstrong narmstrong@baylibre.com Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220601233818.1877963-1-bjorn... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 3d62e6bf6892..310b3b194491 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -982,7 +982,7 @@ static int lt9611uxc_remove(struct i2c_client *client) struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client);
disable_irq(client->irq); - flush_scheduled_work(); + cancel_work_sync(<9611uxc->work); lt9611uxc_audio_exit(lt9611uxc); drm_bridge_remove(<9611uxc->bridge);
From: ZhenGuo Yin zhenguo.yin@amd.com
[ Upstream commit 851dd8625320fb626b6ab6399b2402fd84abcdfb ]
The scratch register should be accessed through MMIO instead of RLCG in SRIOV, since it being used in RLCG register access function.
Fixes: d54762cc3e6a ("drm/amdgpu: nuke dynamic gfx scratch reg allocation") Signed-off-by: ZhenGuo Yin zhenguo.yin@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index c5f46d264b23..ecbaf92759b7 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -3780,11 +3780,12 @@ static void gfx_v10_0_wait_reg_mem(struct amdgpu_ring *ring, int eng_sel, static int gfx_v10_0_ring_test_ring(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; + uint32_t scratch = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG0); uint32_t tmp = 0; unsigned i; int r;
- WREG32_SOC15(GC, 0, mmSCRATCH_REG0, 0xCAFEDEAD); + WREG32(scratch, 0xCAFEDEAD); r = amdgpu_ring_alloc(ring, 3); if (r) { DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", @@ -3793,13 +3794,13 @@ static int gfx_v10_0_ring_test_ring(struct amdgpu_ring *ring) }
amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); - amdgpu_ring_write(ring, SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG0) - + amdgpu_ring_write(ring, scratch - PACKET3_SET_UCONFIG_REG_START); amdgpu_ring_write(ring, 0xDEADBEEF); amdgpu_ring_commit(ring);
for (i = 0; i < adev->usec_timeout; i++) { - tmp = RREG32_SOC15(GC, 0, mmSCRATCH_REG0); + tmp = RREG32(scratch); if (tmp == 0xDEADBEEF) break; if (amdgpu_emu_mode == 1)
From: Leung, Martin Martin.Leung@amd.com
[ Upstream commit a820190204aef0739aa3a067d00273d117f9367c ]
why: lut pipeline will be hooked up differently in some asics need to add new interfaces
how: add them
Reviewed-by: Krunoslav Kovac Krunoslav.Kovac@amd.com Acked-by: Jasdeep Dhillon jdhillon@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Martin martin.leung@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 + drivers/gpu/drm/amd/display/dc/core/dc_link.c | 17 +++++- .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 52 +++++++++++-------- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../display/dc/dce110/dce110_hw_sequencer.c | 23 ++++++-- .../gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c | 13 +++-- .../gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h | 2 +- drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 4 +- drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 5 ++ .../amd/display/dc/inc/hw_sequencer_private.h | 2 + 10 files changed, 83 insertions(+), 38 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 3087dd1a1856..d055d3c7eed6 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1563,6 +1563,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) DRM_INFO("Seamless boot condition check passed\n"); }
+ init_data.flags.enable_mipi_converter_optimization = true; + INIT_LIST_HEAD(&adev->dm.da_list);
retrieve_dmi_info(&adev->dm); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index a789ea8af27f..55a8f58ee239 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -235,7 +235,8 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type)
if (link->connector_signal == SIGNAL_TYPE_EDP) { /*in case it is not on*/ - link->dc->hwss.edp_power_control(link, true); + if (!link->dc->config.edp_no_power_sequencing) + link->dc->hwss.edp_power_control(link, true); link->dc->hwss.edp_wait_for_hpd_ready(link, true); }
@@ -1016,6 +1017,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, bool same_edid = false; enum dc_edid_status edid_status; struct dc_context *dc_ctx = link->ctx; + struct dc *dc = dc_ctx->dc; struct dc_sink *sink = NULL; struct dc_sink *prev_sink = NULL; struct dpcd_caps prev_dpcd_caps; @@ -1095,6 +1097,16 @@ static bool detect_link_and_local_sink(struct dc_link *link,
detect_edp_sink_caps(link); read_current_link_settings_on_detect(link); + + /* Disable power sequence on MIPI panel + converter + */ + if (dc->config.enable_mipi_converter_optimization && + dc_ctx->dce_version == DCN_VERSION_3_01 && + link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_0022B9 && + memcmp(&link->dpcd_caps.branch_dev_name, DP_SINK_BRANCH_DEV_NAME_7580, + sizeof(link->dpcd_caps.branch_dev_name)) == 0) + dc->config.edp_no_power_sequencing = true; + sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX; sink_caps.signal = SIGNAL_TYPE_EDP; break; @@ -1993,7 +2005,8 @@ static enum dc_status enable_link_dp(struct dc_state *state,
if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) { /*in case it is not on*/ - link->dc->hwss.edp_power_control(link, true); + if (!link->dc->config.edp_no_power_sequencing) + link->dc->hwss.edp_power_control(link, true); link->dc->hwss.edp_wait_for_hpd_ready(link, true); }
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index d8eee89e63ce..a4fc9a6c850e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -2074,7 +2074,8 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence( uint32_t wait_time = 0; union lane_align_status_updated dpcd_lane_status_updated = {0}; union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0}; - enum link_training_result status = LINK_TRAINING_SUCCESS; + enum dc_status status = DC_OK; + enum link_training_result result = LINK_TRAINING_SUCCESS; union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
/* Transmit 128b/132b_TPS1 over Main-Link */ @@ -2099,22 +2100,24 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence( lt_settings->pattern_for_eq, DPRX);
/* poll for channel EQ done */ - while (status == LINK_TRAINING_SUCCESS) { + while (result == LINK_TRAINING_SUCCESS) { dp_wait_for_training_aux_rd_interval(link, aux_rd_interval); wait_time += aux_rd_interval; - dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status, + status = dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status, &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX); dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval); - if (dp_is_ch_eq_done(lt_settings->link_settings.lane_count, + if (status != DC_OK) { + result = LINK_TRAINING_ABORT; + } else if (dp_is_ch_eq_done(lt_settings->link_settings.lane_count, dpcd_lane_status)) { /* pass */ break; } else if (loop_count >= lt_settings->eq_loop_count_limit) { - status = DP_128b_132b_MAX_LOOP_COUNT_REACHED; + result = DP_128b_132b_MAX_LOOP_COUNT_REACHED; } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) { - status = DP_128b_132b_LT_FAILED; + result = DP_128b_132b_LT_FAILED; } else { dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX); dpcd_set_lane_settings(link, lt_settings, DPRX); @@ -2123,24 +2126,26 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence( }
/* poll for EQ interlane align done */ - while (status == LINK_TRAINING_SUCCESS) { - if (dpcd_lane_status_updated.bits.EQ_INTERLANE_ALIGN_DONE_128b_132b) { + while (result == LINK_TRAINING_SUCCESS) { + if (status != DC_OK) { + result = LINK_TRAINING_ABORT; + } else if (dpcd_lane_status_updated.bits.EQ_INTERLANE_ALIGN_DONE_128b_132b) { /* pass */ break; } else if (wait_time >= lt_settings->eq_wait_time_limit) { - status = DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT; + result = DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT; } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) { - status = DP_128b_132b_LT_FAILED; + result = DP_128b_132b_LT_FAILED; } else { dp_wait_for_training_aux_rd_interval(link, lt_settings->eq_pattern_time); wait_time += lt_settings->eq_pattern_time; - dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status, + status = dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status, &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX); } }
- return status; + return result; }
static enum link_training_result dp_perform_128b_132b_cds_done_sequence( @@ -2149,7 +2154,8 @@ static enum link_training_result dp_perform_128b_132b_cds_done_sequence( struct link_training_settings *lt_settings) { /* Assumption: assume hardware has transmitted eq pattern */ - enum link_training_result status = LINK_TRAINING_SUCCESS; + enum dc_status status = DC_OK; + enum link_training_result result = LINK_TRAINING_SUCCESS; union lane_align_status_updated dpcd_lane_status_updated = {0}; union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0}; union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } }; @@ -2159,24 +2165,26 @@ static enum link_training_result dp_perform_128b_132b_cds_done_sequence( dpcd_set_training_pattern(link, lt_settings->pattern_for_cds);
/* poll for CDS interlane align done and symbol lock */ - while (status == LINK_TRAINING_SUCCESS) { + while (result == LINK_TRAINING_SUCCESS) { dp_wait_for_training_aux_rd_interval(link, lt_settings->cds_pattern_time); wait_time += lt_settings->cds_pattern_time; - dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status, + status = dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status, &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX); - if (dp_is_symbol_locked(lt_settings->link_settings.lane_count, dpcd_lane_status) && + if (status != DC_OK) { + result = LINK_TRAINING_ABORT; + } else if (dp_is_symbol_locked(lt_settings->link_settings.lane_count, dpcd_lane_status) && dpcd_lane_status_updated.bits.CDS_INTERLANE_ALIGN_DONE_128b_132b) { /* pass */ break; } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) { - status = DP_128b_132b_LT_FAILED; + result = DP_128b_132b_LT_FAILED; } else if (wait_time >= lt_settings->cds_wait_time_limit) { - status = DP_128b_132b_CDS_DONE_TIMEOUT; + result = DP_128b_132b_CDS_DONE_TIMEOUT; } }
- return status; + return result; }
static enum link_training_result dp_perform_8b_10b_link_training( @@ -7099,7 +7107,8 @@ void dp_enable_link_phy( unsigned int i;
if (link->connector_signal == SIGNAL_TYPE_EDP) { - link->dc->hwss.edp_power_control(link, true); + if (!link->dc->config.edp_no_power_sequencing) + link->dc->hwss.edp_power_control(link, true); link->dc->hwss.edp_wait_for_hpd_ready(link, true); }
@@ -7226,7 +7235,8 @@ void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_ link->dc->hwss.edp_backlight_control(link, false); if (link_hwss->ext.disable_dp_link_output) link_hwss->ext.disable_dp_link_output(link, link_res, signal); - link->dc->hwss.edp_power_control(link, false); + if (!link->dc->config.edp_no_power_sequencing) + link->dc->hwss.edp_power_control(link, false); } else { if (dmcu != NULL && dmcu->funcs->lock_phy) dmcu->funcs->lock_phy(dmcu); diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 817028d3c4a0..11b02a98cf0f 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -337,6 +337,7 @@ struct dc_config { bool is_single_rank_dimm; bool use_pipe_ctx_sync_logic; bool ignore_dpref_ss; + bool enable_mipi_converter_optimization; };
enum visual_confirm { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 5f2afa5b4814..aee31c785aa9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1245,8 +1245,18 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx) * has changed or they enter protection state and hang. */ msleep(60); - } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) - edp_receiver_ready_T9(link); + } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) { + if (!link->dc->config.edp_no_power_sequencing) { + /* + * Sometimes, DP receiver chip power-controlled externally by an + * Embedded Controller could be treated and used as eDP, + * if it drives mobile display. In this case, + * we shouldn't be doing power-sequencing, hence we can skip + * waiting for T9-ready. + */ + edp_receiver_ready_T9(link); + } + } }
} @@ -2161,15 +2171,18 @@ static void dce110_setup_audio_dto( build_audio_output(context, pipe_ctx, &audio_output);
if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) { - /* disable audio DTBCLK DTO */ - dc->res_pool->dccg->funcs->set_audio_dtbclk_dto( - dc->res_pool->dccg, 0); + struct dtbclk_dto_params dto_params = {0};
pipe_ctx->stream_res.audio->funcs->wall_dto_setup( pipe_ctx->stream_res.audio, pipe_ctx->stream->signal, &audio_output.crtc_info, &audio_output.pll_info); + + dc->res_pool->dccg->funcs->set_audio_dtbclk_dto( + dc->res_pool->dccg, + &dto_params); + } else pipe_ctx->stream_res.audio->funcs->wall_dto_setup( pipe_ctx->stream_res.audio, diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c index bbc58d167c63..4519ecef2e7b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c @@ -513,7 +513,7 @@ void dccg31_set_physymclk( /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */ static void dccg31_set_dtbclk_dto( struct dccg *dccg, - struct dtbclk_dto_params *params) + const struct dtbclk_dto_params *params) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); int req_dtbclk_khz = params->pixclk_khz; @@ -579,18 +579,17 @@ static void dccg31_set_dtbclk_dto(
void dccg31_set_audio_dtbclk_dto( struct dccg *dccg, - uint32_t req_audio_dtbclk_khz) + const struct dtbclk_dto_params *params) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
- if (dccg->ref_dtbclk_khz && req_audio_dtbclk_khz) { + if (params->ref_dtbclk_khz && params->req_audio_dtbclk_khz) { uint32_t modulo, phase;
// phase / modulo = dtbclk / dtbclk ref - modulo = dccg->ref_dtbclk_khz * 1000; - phase = div_u64((((unsigned long long)modulo * req_audio_dtbclk_khz) + dccg->ref_dtbclk_khz - 1), - dccg->ref_dtbclk_khz); - + modulo = params->ref_dtbclk_khz * 1000; + phase = div_u64((((unsigned long long)modulo * params->req_audio_dtbclk_khz) + params->ref_dtbclk_khz - 1), + params->ref_dtbclk_khz);
REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, modulo); REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, phase); diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h index 269cabbea72a..f158c1ea214b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h @@ -192,7 +192,7 @@ void dccg31_set_physymclk(
void dccg31_set_audio_dtbclk_dto( struct dccg *dccg, - uint32_t req_audio_dtbclk_khz); + const struct dtbclk_dto_params *params);
void dccg31_set_hdmistreamclk( struct dccg *dccg, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h index c7021915bac8..c1023cc84f55 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -120,11 +120,11 @@ struct dccg_funcs {
void (*set_dtbclk_dto)( struct dccg *dccg, - struct dtbclk_dto_params *dto_params); + const struct dtbclk_dto_params *params);
void (*set_audio_dtbclk_dto)( struct dccg *dccg, - uint32_t req_audio_dtbclk_khz); + const struct dtbclk_dto_params *params);
void (*set_dispclk_change_mode)( struct dccg *dccg, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h index f5fd2a067323..5097037e3962 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h @@ -346,6 +346,11 @@ struct mpc_funcs { int mpcc_id, const struct mpc_grph_gamut_adjustment *adjust);
+ bool (*program_1dlut)( + struct mpc *mpc, + const struct pwl_params *params, + uint32_t rmu_idx); + bool (*program_shaper)( struct mpc *mpc, const struct pwl_params *params, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h index 8c2f190c4712..d2cb0e794500 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h @@ -140,6 +140,8 @@ struct hwseq_private_funcs { const struct dc_plane_state *plane_state); bool (*set_shaper_3dlut)(struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state); + bool (*set_mcm_luts)(struct pipe_ctx *pipe_ctx, + const struct dc_plane_state *plane_state); void (*PLAT_58856_wa)(struct dc_state *context, struct pipe_ctx *pipe_ctx); void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable);
From: Tali Perry tali.perry1@gmail.com
[ Upstream commit 47d506d1a28fd10a9fb1f33df5622d88fae72095 ]
NPCM can support up to 10 own slave addresses. In practice, only one address is actually being used. In order to access addresses 2 and above, need to switch register banks. The switch needs spinlock. To avoid using spinlock for this useless feature removed support of SA >= 2. Also fix returned slave event enum.
Remove some comment since the bank selection is not required. The bank selection is not required since the supported slave addresses are reduced.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver") Signed-off-by: Tali Perry tali.perry1@gmail.com Signed-off-by: Tyrone Ting kfting@nuvoton.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-npcm7xx.c | 41 +++++++++++++------------------- 1 file changed, 16 insertions(+), 25 deletions(-)
diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index aede9d551130..f3177cff9591 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -123,11 +123,11 @@ enum i2c_addr { * Since the addr regs are sprinkled all over the address space, * use this array to get the address or each register. */ -#define I2C_NUM_OWN_ADDR 10 +#define I2C_NUM_OWN_ADDR 2 +#define I2C_NUM_OWN_ADDR_SUPPORTED 2 + static const int npcm_i2caddr[I2C_NUM_OWN_ADDR] = { - NPCM_I2CADDR1, NPCM_I2CADDR2, NPCM_I2CADDR3, NPCM_I2CADDR4, - NPCM_I2CADDR5, NPCM_I2CADDR6, NPCM_I2CADDR7, NPCM_I2CADDR8, - NPCM_I2CADDR9, NPCM_I2CADDR10, + NPCM_I2CADDR1, NPCM_I2CADDR2, }; #endif
@@ -392,14 +392,10 @@ static void npcm_i2c_disable(struct npcm_i2c *bus) #if IS_ENABLED(CONFIG_I2C_SLAVE) int i;
- /* select bank 0 for I2C addresses */ - npcm_i2c_select_bank(bus, I2C_BANK_0); - /* Slave addresses removal */ - for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR; i++) + for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR_SUPPORTED; i++) iowrite8(0, bus->reg + npcm_i2caddr[i]);
- npcm_i2c_select_bank(bus, I2C_BANK_1); #endif /* Disable module */ i2cctl2 = ioread8(bus->reg + NPCM_I2CCTL2); @@ -604,8 +600,7 @@ static int npcm_i2c_slave_enable(struct npcm_i2c *bus, enum i2c_addr addr_type, i2cctl1 &= ~NPCM_I2CCTL1_GCMEN; iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1); return 0; - } - if (addr_type == I2C_ARP_ADDR) { + } else if (addr_type == I2C_ARP_ADDR) { i2cctl3 = ioread8(bus->reg + NPCM_I2CCTL3); if (enable) i2cctl3 |= I2CCTL3_ARPMEN; @@ -614,16 +609,16 @@ static int npcm_i2c_slave_enable(struct npcm_i2c *bus, enum i2c_addr addr_type, iowrite8(i2cctl3, bus->reg + NPCM_I2CCTL3); return 0; } + if (addr_type > I2C_SLAVE_ADDR2 && addr_type <= I2C_SLAVE_ADDR10) + dev_err(bus->dev, "try to enable more than 2 SA not supported\n"); + if (addr_type >= I2C_ARP_ADDR) return -EFAULT; - /* select bank 0 for address 3 to 10 */ - if (addr_type > I2C_SLAVE_ADDR2) - npcm_i2c_select_bank(bus, I2C_BANK_0); + /* Set and enable the address */ iowrite8(sa_reg, bus->reg + npcm_i2caddr[addr_type]); npcm_i2c_slave_int_enable(bus, enable); - if (addr_type > I2C_SLAVE_ADDR2) - npcm_i2c_select_bank(bus, I2C_BANK_1); + return 0; } #endif @@ -846,15 +841,11 @@ static u8 npcm_i2c_get_slave_addr(struct npcm_i2c *bus, enum i2c_addr addr_type) { u8 slave_add;
- /* select bank 0 for address 3 to 10 */ - if (addr_type > I2C_SLAVE_ADDR2) - npcm_i2c_select_bank(bus, I2C_BANK_0); + if (addr_type > I2C_SLAVE_ADDR2 && addr_type <= I2C_SLAVE_ADDR10) + dev_err(bus->dev, "get slave: try to use more than 2 SA not supported\n");
slave_add = ioread8(bus->reg + npcm_i2caddr[(int)addr_type]);
- if (addr_type > I2C_SLAVE_ADDR2) - npcm_i2c_select_bank(bus, I2C_BANK_1); - return slave_add; }
@@ -864,12 +855,12 @@ static int npcm_i2c_remove_slave_addr(struct npcm_i2c *bus, u8 slave_add)
/* Set the enable bit */ slave_add |= 0x80; - npcm_i2c_select_bank(bus, I2C_BANK_0); - for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR; i++) { + + for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR_SUPPORTED; i++) { if (ioread8(bus->reg + npcm_i2caddr[i]) == slave_add) iowrite8(0, bus->reg + npcm_i2caddr[i]); } - npcm_i2c_select_bank(bus, I2C_BANK_1); + return 0; }
From: Tali Perry tali.perry1@gmail.com
[ Upstream commit d7aa1b149b8fc04d802879cf4662010aa4a42deb ]
Correct the slave transaction logic to be compatible with the generic slave backend driver.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver") Signed-off-by: Tali Perry tali.perry1@gmail.com Signed-off-by: Tyrone Ting kfting@nuvoton.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-npcm7xx.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index f3177cff9591..7b112be5e35c 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -915,11 +915,15 @@ static int npcm_i2c_slave_get_wr_buf(struct npcm_i2c *bus) for (i = 0; i < I2C_HW_FIFO_SIZE; i++) { if (bus->slv_wr_size >= I2C_HW_FIFO_SIZE) break; - i2c_slave_event(bus->slave, I2C_SLAVE_READ_REQUESTED, &value); + if (bus->state == I2C_SLAVE_MATCH) { + i2c_slave_event(bus->slave, I2C_SLAVE_READ_REQUESTED, &value); + bus->state = I2C_OPER_STARTED; + } else { + i2c_slave_event(bus->slave, I2C_SLAVE_READ_PROCESSED, &value); + } ind = (bus->slv_wr_ind + bus->slv_wr_size) % I2C_HW_FIFO_SIZE; bus->slv_wr_buf[ind] = value; bus->slv_wr_size++; - i2c_slave_event(bus->slave, I2C_SLAVE_READ_PROCESSED, &value); } return I2C_HW_FIFO_SIZE - ret; } @@ -967,7 +971,6 @@ static void npcm_i2c_slave_xmit(struct npcm_i2c *bus, u16 nwrite, if (nwrite == 0) return;
- bus->state = I2C_OPER_STARTED; bus->operation = I2C_WRITE_OPER;
/* get the next buffer */
From: Fabio Estevam festevam@gmail.com
[ Upstream commit 3d43273d7d1e1a5374d531e901d3c537b4c97bbf ]
Change the of_device_get_match_data() cast to (uintptr_t) to silence the following clang warning:
drivers/i2c/busses/i2c-mxs.c:802:18: warning: cast to smaller integer type 'enum mxs_i2c_devtype' from 'const void *' [-Wvoid-pointer-to-enum-cast]
Reported-by: kernel test robot lkp@intel.com Fixes: c32abd8b5691 ("i2c: mxs: Remove unneeded platform_device_id") Signed-off-by: Fabio Estevam festevam@gmail.com Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-mxs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 864a3f1bd4e1..68f67d084c63 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -799,7 +799,7 @@ static int mxs_i2c_probe(struct platform_device *pdev) if (!i2c) return -ENOMEM;
- i2c->dev_type = (enum mxs_i2c_devtype)of_device_get_match_data(&pdev->dev); + i2c->dev_type = (uintptr_t)of_device_get_match_data(&pdev->dev);
i2c->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(i2c->regs))
From: Xiaomeng Tong xiam0nd.tong@gmail.com
[ Upstream commit bd63f11f4c3c46afec07d821f74736161ff6e526 ]
'cache_ent' could be set NULL inside virtio_gpu_cmd_get_capset() and it will lead to a NULL dereference by a lately use of it (i.e., ptr = cache_ent->caps_cache). Fix it with a NULL check.
Fixes: 62fb7a5e10962 ("virtio-gpu: add 3d/virgl support") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Reviewed-by: Chia-I Wu olvaffe@gmail.com Link: http://patchwork.freedesktop.org/patch/msgid/20220327050945.1614-1-xiam0nd.t...
[ kraxel: minor codestyle fixup ]
Signed-off-by: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index f8d83358d2a0..9b2702116f93 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -580,8 +580,10 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev, spin_unlock(&vgdev->display_info_lock);
/* not in cache - need to talk to hw */ - virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver, - &cache_ent); + ret = virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver, + &cache_ent); + if (ret) + return ret; virtio_gpu_notify(vgdev);
copy_exit:
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit c24968734abfed81c8f93dc5f44a7b7a9aecadfa ]
Since drm_prime_pages_to_sg() function return error pointers. The drm_gem_shmem_get_sg_table() function returns error pointers too. Using IS_ERR() to check the return value to fix this.
Fixes: 2f2aa13724d5 ("drm/virtio: move virtio_gpu_mem_entry initialization to new function") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: http://patchwork.freedesktop.org/patch/msgid/20220602104223.54527-1-linmq006... Signed-off-by: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/virtio/virtgpu_object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index f293e6ad52da..1cc8f3fc8e4b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -168,9 +168,9 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, * since virtio_gpu doesn't support dma-buf import from other devices. */ shmem->pages = drm_gem_shmem_get_sg_table(&bo->base); - if (!shmem->pages) { + if (IS_ERR(shmem->pages)) { drm_gem_shmem_unpin(&bo->base); - return -EINVAL; + return PTR_ERR(shmem->pages); }
if (use_dma_api) {
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit fe92833524e368e59bba9c57e00f7359f133667f ]
Fix libbpf's bpf_program__attach_uprobe() logic of determining function's *file offset* (which is what kernel is actually expecting) when attaching uprobe/uretprobe by function name. Previously calculation was determining virtual address offset relative to base load address, which (offset) is not always the same as file offset (though very frequently it is which is why this went unnoticed for a while).
Fixes: 433966e3ae04 ("libbpf: Support function name-based attach uprobes") Signed-off-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Cc: Riham Selim rihams@fb.com Cc: Alan Maguire alan.maguire@oracle.com Link: https://lore.kernel.org/bpf/20220606220143.3796908-1-andrii@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 63 +++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 41 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 526bd6cd84a0..b9245bf688fa 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -10983,43 +10983,6 @@ static int perf_event_uprobe_open_legacy(const char *probe_name, bool retprobe, return pfd; }
-/* uprobes deal in relative offsets; subtract the base address associated with - * the mapped binary. See Documentation/trace/uprobetracer.rst for more - * details. - */ -static long elf_find_relative_offset(const char *filename, Elf *elf, long addr) -{ - size_t n; - int i; - - if (elf_getphdrnum(elf, &n)) { - pr_warn("elf: failed to find program headers for '%s': %s\n", filename, - elf_errmsg(-1)); - return -ENOENT; - } - - for (i = 0; i < n; i++) { - int seg_start, seg_end, seg_offset; - GElf_Phdr phdr; - - if (!gelf_getphdr(elf, i, &phdr)) { - pr_warn("elf: failed to get program header %d from '%s': %s\n", i, filename, - elf_errmsg(-1)); - return -ENOENT; - } - if (phdr.p_type != PT_LOAD || !(phdr.p_flags & PF_X)) - continue; - - seg_start = phdr.p_vaddr; - seg_end = seg_start + phdr.p_memsz; - seg_offset = phdr.p_offset; - if (addr >= seg_start && addr < seg_end) - return addr - seg_start + seg_offset; - } - pr_warn("elf: failed to find prog header containing 0x%lx in '%s'\n", addr, filename); - return -ENOENT; -} - /* Return next ELF section of sh_type after scn, or first of that type if scn is NULL. */ static Elf_Scn *elf_find_next_scn_by_type(Elf *elf, int sh_type, Elf_Scn *scn) { @@ -11106,6 +11069,8 @@ static long elf_find_func_offset(const char *binary_path, const char *name) for (idx = 0; idx < nr_syms; idx++) { int curr_bind; GElf_Sym sym; + Elf_Scn *sym_scn; + GElf_Shdr sym_sh;
if (!gelf_getsym(symbols, idx, &sym)) continue; @@ -11143,12 +11108,28 @@ static long elf_find_func_offset(const char *binary_path, const char *name) continue; } } - ret = sym.st_value; + + /* Transform symbol's virtual address (absolute for + * binaries and relative for shared libs) into file + * offset, which is what kernel is expecting for + * uprobe/uretprobe attachment. + * See Documentation/trace/uprobetracer.rst for more + * details. + * This is done by looking up symbol's containing + * section's header and using it's virtual address + * (sh_addr) and corresponding file offset (sh_offset) + * to transform sym.st_value (virtual address) into + * desired final file offset. + */ + sym_scn = elf_getscn(elf, sym.st_shndx); + if (!sym_scn) + continue; + if (!gelf_getshdr(sym_scn, &sym_sh)) + continue; + + ret = sym.st_value - sym_sh.sh_addr + sym_sh.sh_offset; last_bind = curr_bind; } - /* For binaries that are not shared libraries, we need relative offset */ - if (ret > 0 && !is_shared_lib) - ret = elf_find_relative_offset(binary_path, elf, ret); if (ret > 0) break; }
From: Antonio Borneo antonio.borneo@foss.st.com
[ Upstream commit 9cc4853e4781bf0dd0f35355dc92d97c9da02f5d ]
Commit 680532c50bca ("drm: adv7511: Add support for i2c_new_secondary_device") allows a device tree node to override the default addresses of the secondary i2c devices. This is useful for solving address conflicts on the i2c bus.
In adv7511_init_cec_regmap() the new i2c address of cec device is read from device tree and immediately accessed, well before it is written in the proper register to override the default address. This can cause an i2c error during probe and a consequent probe failure.
Once the new i2c address is read from the device tree, override the default address before any attempt to access the cec.
Tested with adv7533 and stm32mp157f.
Signed-off-by: Antonio Borneo antonio.borneo@foss.st.com Fixes: 680532c50bca ("drm: adv7511: Add support for i2c_new_secondary_device") Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220607213144.427177-1-antoni... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 5bb9300040dd..074c2e650cae 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1065,6 +1065,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv) ADV7511_CEC_I2C_ADDR_DEFAULT); if (IS_ERR(adv->i2c_cec)) return PTR_ERR(adv->i2c_cec); + + regmap_write(adv->regmap, ADV7511_REG_CEC_I2C_ADDR, + adv->i2c_cec->addr << 1); + i2c_set_clientdata(adv->i2c_cec, adv);
adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec, @@ -1271,9 +1275,6 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) if (ret) goto err_i2c_unregister_packet;
- regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, - adv7511->i2c_cec->addr << 1); - INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work);
if (i2c->irq) {
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit d2765e1b9ac4b2d5a5d5bf17f468c9b3566c3770 ]
These failure paths should return -ENOMEM. Currently they return success.
Fixes: 359e893e8af4 ("crypto: sun8i-ss - rework handling of IV") Fixes: 8eec4563f152 ("crypto: sun8i-ss - do not allocate memory when handling hash requests") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Corentin Labbe clabbe.montjoie@gmail.com Tested-by: Corentin Labbe clabbe.montjoie@gmail.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- .../crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c index 98593a0cff69..ac2329e2b0e5 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c @@ -528,25 +528,33 @@ static int allocate_flows(struct sun8i_ss_dev *ss)
ss->flows[i].biv = devm_kmalloc(ss->dev, AES_BLOCK_SIZE, GFP_KERNEL | GFP_DMA); - if (!ss->flows[i].biv) + if (!ss->flows[i].biv) { + err = -ENOMEM; goto error_engine; + }
for (j = 0; j < MAX_SG; j++) { ss->flows[i].iv[j] = devm_kmalloc(ss->dev, AES_BLOCK_SIZE, GFP_KERNEL | GFP_DMA); - if (!ss->flows[i].iv[j]) + if (!ss->flows[i].iv[j]) { + err = -ENOMEM; goto error_engine; + } }
/* the padding could be up to two block. */ ss->flows[i].pad = devm_kmalloc(ss->dev, MAX_PAD_SIZE, GFP_KERNEL | GFP_DMA); - if (!ss->flows[i].pad) + if (!ss->flows[i].pad) { + err = -ENOMEM; goto error_engine; + } ss->flows[i].result = devm_kmalloc(ss->dev, SHA256_DIGEST_SIZE, GFP_KERNEL | GFP_DMA); - if (!ss->flows[i].result) + if (!ss->flows[i].result) { + err = -ENOMEM; goto error_engine; + }
ss->flows[i].engine = crypto_engine_alloc_init(ss->dev, true); if (!ss->flows[i].engine) {
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 6cb3f9b25c55928b95a02b9ed8e87ed653b3cce8 ]
If there is a dma_mapping_error() then return negative error codes. Currently this code returns success.
Fixes: 801b7d572c0a ("crypto: sun8i-ss - add hmac(sha1)") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Corentin Labbe clabbe.montjoie@gmail.com Tested-by: Corentin Labbe clabbe.montjoie@gmail.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c index ac417a6b39e5..845019bd9591 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c @@ -586,7 +586,8 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq) rctx->t_dst[k + 1].len = rctx->t_dst[k].len; } addr_xpad = dma_map_single(ss->dev, tfmctx->ipad, bs, DMA_TO_DEVICE); - if (dma_mapping_error(ss->dev, addr_xpad)) { + err = dma_mapping_error(ss->dev, addr_xpad); + if (err) { dev_err(ss->dev, "Fail to create DMA mapping of ipad\n"); goto err_dma_xpad; } @@ -612,7 +613,8 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq) goto err_dma_result; } addr_xpad = dma_map_single(ss->dev, tfmctx->opad, bs, DMA_TO_DEVICE); - if (dma_mapping_error(ss->dev, addr_xpad)) { + err = dma_mapping_error(ss->dev, addr_xpad); + if (err) { dev_err(ss->dev, "Fail to create DMA mapping of opad\n"); goto err_dma_xpad; }
From: Peng Wu wupeng58@huawei.com
[ Upstream commit 7e8df1fc2d669d04c1f8a9e2d61d7afba1b43df4 ]
The crypto_alloc_shash() function never returns NULL. It returns error pointers.
Fixes: 801b7d572c0a ("crypto: sun8i-ss - add hmac(sha1)") Signed-off-by: Peng Wu wupeng58@huawei.com Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c index 845019bd9591..36a82b22953c 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c @@ -30,8 +30,8 @@ static int sun8i_ss_hashkey(struct sun8i_ss_hash_tfm_ctx *tfmctx, const u8 *key, int ret = 0;
xtfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_NEED_FALLBACK); - if (!xtfm) - return -ENOMEM; + if (IS_ERR(xtfm)) + return PTR_ERR(xtfm);
len = sizeof(*sdesc) + crypto_shash_descsize(xtfm); sdesc = kmalloc(len, GFP_KERNEL);
From: Eric Dumazet edumazet@google.com
[ Upstream commit 7c80b038d23e1f4c7fcc311f43f83b8c60e7fb80 ]
If sk->sk_forward_alloc is 150000, and we need to schedule 150001 bytes, we want to allocate 1 byte more (rounded up to one page), instead of 150001 :/
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet edumazet@google.com Reviewed-by: Shakeel Butt shakeelb@google.com Acked-by: Soheil Hassas Yeganeh soheil@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/sock.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h index 7a48991cdb19..13944ceea7ed 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1552,19 +1552,23 @@ static inline bool sk_has_account(struct sock *sk)
static inline bool sk_wmem_schedule(struct sock *sk, int size) { + int delta; + if (!sk_has_account(sk)) return true; - return size <= sk->sk_forward_alloc || - __sk_mem_schedule(sk, size, SK_MEM_SEND); + delta = size - sk->sk_forward_alloc; + return delta <= 0 || __sk_mem_schedule(sk, delta, SK_MEM_SEND); }
static inline bool sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size) { + int delta; + if (!sk_has_account(sk)) return true; - return size <= sk->sk_forward_alloc || - __sk_mem_schedule(sk, size, SK_MEM_RECV) || + delta = size - sk->sk_forward_alloc; + return delta <= 0 || __sk_mem_schedule(sk, delta, SK_MEM_RECV) || skb_pfmemalloc(skb); }
From: Marc Kleine-Budde mkl@pengutronix.de
[ Upstream commit 7e193a42c37cf40eba8ac5af2d5e8eeb8b9506f9 ]
Usually CAN devices support configurable bit rates. The limits are defined by struct can_priv::bittiming_const. Another way is to implement the struct can_priv::do_set_bittiming callback.
If the bit rate is configured via netlink, the can_changelink() function checks that either can_priv::bittiming_const or struct can_priv::do_set_bittiming is implemented.
In commit 431af779256c ("can: dev: add CAN interface API for fixed bitrates") an API for configuring bit rates on CAN interfaces that only support fixed bit rates was added. The supported bit rates are defined by struct can_priv::bitrate_const.
However the above mentioned commit forgot to add the struct can_priv::bitrate_const to the check in can_changelink().
In order to avoid to implement a no-op can_priv::do_set_bittiming callback on devices with fixed bit rates, extend the check in can_changelink() accordingly.
Link: https://lore.kernel.org/all/20220611144248.3924903-1-mkl@pengutronix.de Fixes: 431af779256c ("can: dev: add CAN interface API for fixed bitrates") Reported-by: Max Staudt max@enpas.org Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/dev/netlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c index 7633d98e3912..667ddd28fcdc 100644 --- a/drivers/net/can/dev/netlink.c +++ b/drivers/net/can/dev/netlink.c @@ -176,7 +176,8 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], * directly via do_set_bitrate(). Bail out if neither * is given. */ - if (!priv->bittiming_const && !priv->do_set_bittiming) + if (!priv->bittiming_const && !priv->do_set_bittiming && + !priv->bitrate_const) return -EOPNOTSUPP;
memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
From: Tales Lelo da Aparecida tales.aparecida@gmail.com
[ Upstream commit 24f6fe3226c6f9f1b8406311a96b59c6e650b707 ]
Fix a copypasta error. The caller of compose_plane() already checks primary_composer->map. In contrast, plane_composer->map is never verified here before handling.
Fixes: 7938f4218168 ("dma-buf-map: Rename to iosys-map") Reviewed-by: André Almeida andrealmeid@riseup.net Signed-off-by: Tales Lelo da Aparecida tales.aparecida@gmail.com Signed-off-by: Melissa Wen melissa.srw@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20220415111300.61013-2-tales.a... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vkms/vkms_composer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index c6a1036bf2ea..b47ac170108c 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -157,7 +157,7 @@ static void compose_plane(struct vkms_composer *primary_composer, void *vaddr; void (*pixel_blend)(const u8 *p_src, u8 *p_dst);
- if (WARN_ON(iosys_map_is_null(&primary_composer->map[0]))) + if (WARN_ON(iosys_map_is_null(&plane_composer->map[0]))) return;
vaddr = plane_composer->map[0].vaddr;
From: Marc Kleine-Budde mkl@pengutronix.de
[ Upstream commit ec30c109391c5eac9b1d689a61e4bfed88148947 ]
This patch is similar to 7e193a42c37c ("can: netlink: allow configuring of fixed bit rates without need for do_set_bittiming callback") but for data bit rates instead of bit rates.
Usually CAN devices support configurable data bit rates. The limits are defined by struct can_priv::data_bittiming_const. Another way is to implement the struct can_priv::do_set_data_bittiming callback.
If the bit rate is configured via netlink, the can_changelink() function checks that either can_priv::data_bittiming_const or struct can_priv::do_set_data_bittiming is implemented.
In commit 431af779256c ("can: dev: add CAN interface API for fixed bitrates") an API for configuring bit rates on CAN interfaces that only support fixed bit rates was added. The supported bit rates are defined by struct can_priv::bitrate_const.
However the above mentioned commit forgot to add the struct can_priv::data_bitrate_const to the check in can_changelink().
In order to avoid to implement a no-op can_priv::do_set_data_bittiming callback on devices with fixed data bit rates, extend the check in can_changelink() accordingly.
Link: https://lore.kernel.org/all/20220613143633.4151884-1-mkl@pengutronix.de Fixes: 431af779256c ("can: dev: add CAN interface API for fixed bitrates") Acked-by: Max Staudt max@enpas.org Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/dev/netlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c index 667ddd28fcdc..037824011266 100644 --- a/drivers/net/can/dev/netlink.c +++ b/drivers/net/can/dev/netlink.c @@ -279,7 +279,8 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], * directly via do_set_bitrate(). Bail out if neither * is given. */ - if (!priv->data_bittiming_const && !priv->do_set_data_bittiming) + if (!priv->data_bittiming_const && !priv->do_set_data_bittiming && + !priv->data_bitrate_const) return -EOPNOTSUPP;
memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
From: Nícolas F. R. A. Prado nfraprado@collabora.com
[ Upstream commit 3f49f7591e7150c502aa8d04354941ec2394153f ]
While parsing the DT, the anx7625 driver checks for the presence of a panel bridge on endpoint 1. If it is missing, pdata->panel_bridge stores the error pointer and the function returns successfully without first cleaning that variable. This is an issue since other functions later check for the presence of a panel bridge by testing the trueness of that variable.
In order to ensure proper behavior, zero out pdata->panel_bridge before returning when no panel bridge is found.
Fixes: 9e82ea0fb1df ("drm/bridge: anx7625: switch to devm_drm_of_get_bridge") Signed-off-by: Nícolas F. R. A. Prado nfraprado@collabora.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220613163705.1531721-1-nfrap... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/anx7625.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 01f46d9189c1..0117fd8c62ae 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1657,8 +1657,10 @@ static int anx7625_parse_dt(struct device *dev,
pdata->panel_bridge = devm_drm_of_get_bridge(dev, np, 1, 0); if (IS_ERR(pdata->panel_bridge)) { - if (PTR_ERR(pdata->panel_bridge) == -ENODEV) + if (PTR_ERR(pdata->panel_bridge) == -ENODEV) { + pdata->panel_bridge = NULL; return 0; + }
return PTR_ERR(pdata->panel_bridge); }
From: Zheng Bin zhengbin13@huawei.com
[ Upstream commit abf0ba5a34eae0d7359228f4319a6659676fbd0a ]
The driver uses crypto hash functions so it needs to select CRYPTO_HASH. This fixes build errors:
drivers/gpu/drm/bridge/ite-it6505.o: in function `it6505_hdcp_wait_ksv_list': ite-it6505.c:(.text+0x4c26): undefined reference to `crypto_alloc_shash' ite-it6505.c:(.text+0x4c6d): undefined reference to `crypto_shash_digest' ite-it6505.c:(.text+0x4c7d): undefined reference to `crypto_destroy_tfm' ite-it6505.c:(.text+0x4d69): undefined reference to `crypto_destroy_tfm'
Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver") Signed-off-by: Zheng Bin zhengbin13@huawei.com Reviewed-by: Robert Foss robert.foss@linaro.org Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220613150653.1310029-1-zheng... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 449b1b5a76ac..745c68735dd2 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -94,6 +94,8 @@ config DRM_ITE_IT6505 select DRM_KMS_HELPER select DRM_DP_HELPER select EXTCON + select CRYPTO + select CRYPTO_HASH help ITE IT6505 DisplayPort bridge chip driver.
From: Xu Wang vulab@iscas.ac.cn
[ Upstream commit e4c72c06c367758a14f227c847f9d623f1994ecf ]
Free the adap structure only after we are done using it. This patch just moves the put_device() down a bit to avoid the use after free.
Fixes: 611e12ea0f12 ("i2c: core: manage i2c bus device refcount in i2c_[get|put]_adapter") Signed-off-by: Xu Wang vulab@iscas.ac.cn [wsa: added comment to the code, added Fixes tag] Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/i2c-core-base.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index d43db2c3876e..19a317fdcf5b 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -2467,8 +2467,9 @@ void i2c_put_adapter(struct i2c_adapter *adap) if (!adap) return;
- put_device(&adap->dev); module_put(adap->owner); + /* Should be last, otherwise we risk use-after-free with 'adap' */ + put_device(&adap->dev); } EXPORT_SYMBOL(i2c_put_adapter);
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit 3e6fe5ce4d4860c3a111c246fddc6f31492f4fb0 ]
Perform the same virtual address to file offset translation that libbpf is doing for executable ELF binaries also for shared libraries. Currently libbpf is making a simplifying and sometimes wrong assumption that for shared libraries relative virtual addresses inside ELF are always equal to file offsets.
Unfortunately, this is not always the case with LLVM's lld linker, which now by default generates quite more complicated ELF segments layout. E.g., for liburandom_read.so from selftests/bpf, here's an excerpt from readelf output listing ELF segments (a.k.a. program headers):
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x0001f8 0x0001f8 R 0x8 LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0005e4 0x0005e4 R 0x1000 LOAD 0x0005f0 0x00000000000015f0 0x00000000000015f0 0x000160 0x000160 R E 0x1000 LOAD 0x000750 0x0000000000002750 0x0000000000002750 0x000210 0x000210 RW 0x1000 LOAD 0x000960 0x0000000000003960 0x0000000000003960 0x000028 0x000029 RW 0x1000
Compare that to what is generated by GNU ld (or LLVM lld's with extra -znoseparate-code argument which disables this cleverness in the name of file size reduction):
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000550 0x000550 R 0x1000 LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000131 0x000131 R E 0x1000 LOAD 0x002000 0x0000000000002000 0x0000000000002000 0x0000ac 0x0000ac R 0x1000 LOAD 0x002dc0 0x0000000000003dc0 0x0000000000003dc0 0x000262 0x000268 RW 0x1000
You can see from the first example above that for executable (Flg == "R E") PT_LOAD segment (LOAD #2), Offset doesn't match VirtAddr columns. And it does in the second case (GNU ld output).
This is important because all the addresses, including USDT specs, operate in a virtual address space, while kernel is expecting file offsets when performing uprobe attach. So such mismatches have to be properly taken care of and compensated by libbpf, which is what this patch is fixing.
Also patch clarifies few function and variable names, as well as updates comments to reflect this important distinction (virtaddr vs file offset) and to ephasize that shared libraries are not all that different from executables in this regard.
This patch also changes selftests/bpf Makefile to force urand_read and liburand_read.so to be built with Clang and LLVM's lld (and explicitly request this ELF file size optimization through -znoseparate-code linker parameter) to validate libbpf logic and ensure regressions don't happen in the future. I've bundled these selftests changes together with libbpf changes to keep the above description tied with both libbpf and selftests changes.
Fixes: 74cc6311cec9 ("libbpf: Add USDT notes parsing and resolution logic") Signed-off-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20220616055543.3285835-1-andrii@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/usdt.c | 123 ++++++++++++++------------- tools/testing/selftests/bpf/Makefile | 14 +-- 2 files changed, 72 insertions(+), 65 deletions(-)
diff --git a/tools/lib/bpf/usdt.c b/tools/lib/bpf/usdt.c index f1c9339cfbbc..5159207cbfd9 100644 --- a/tools/lib/bpf/usdt.c +++ b/tools/lib/bpf/usdt.c @@ -441,7 +441,7 @@ static int parse_elf_segs(Elf *elf, const char *path, struct elf_seg **segs, siz return 0; }
-static int parse_lib_segs(int pid, const char *lib_path, struct elf_seg **segs, size_t *seg_cnt) +static int parse_vma_segs(int pid, const char *lib_path, struct elf_seg **segs, size_t *seg_cnt) { char path[PATH_MAX], line[PATH_MAX], mode[16]; size_t seg_start, seg_end, seg_off; @@ -531,35 +531,40 @@ static int parse_lib_segs(int pid, const char *lib_path, struct elf_seg **segs, return err; }
-static struct elf_seg *find_elf_seg(struct elf_seg *segs, size_t seg_cnt, long addr, bool relative) +static struct elf_seg *find_elf_seg(struct elf_seg *segs, size_t seg_cnt, long virtaddr) { struct elf_seg *seg; int i;
- if (relative) { - /* for shared libraries, address is relative offset and thus - * should be fall within logical offset-based range of - * [offset_start, offset_end) - */ - for (i = 0, seg = segs; i < seg_cnt; i++, seg++) { - if (seg->offset <= addr && addr < seg->offset + (seg->end - seg->start)) - return seg; - } - } else { - /* for binaries, address is absolute and thus should be within - * absolute address range of [seg_start, seg_end) - */ - for (i = 0, seg = segs; i < seg_cnt; i++, seg++) { - if (seg->start <= addr && addr < seg->end) - return seg; - } + /* for ELF binaries (both executables and shared libraries), we are + * given virtual address (absolute for executables, relative for + * libraries) which should match address range of [seg_start, seg_end) + */ + for (i = 0, seg = segs; i < seg_cnt; i++, seg++) { + if (seg->start <= virtaddr && virtaddr < seg->end) + return seg; } + return NULL; +}
+static struct elf_seg *find_vma_seg(struct elf_seg *segs, size_t seg_cnt, long offset) +{ + struct elf_seg *seg; + int i; + + /* for VMA segments from /proc/<pid>/maps file, provided "address" is + * actually a file offset, so should be fall within logical + * offset-based range of [offset_start, offset_end) + */ + for (i = 0, seg = segs; i < seg_cnt; i++, seg++) { + if (seg->offset <= offset && offset < seg->offset + (seg->end - seg->start)) + return seg; + } return NULL; }
-static int parse_usdt_note(Elf *elf, const char *path, long base_addr, - GElf_Nhdr *nhdr, const char *data, size_t name_off, size_t desc_off, +static int parse_usdt_note(Elf *elf, const char *path, GElf_Nhdr *nhdr, + const char *data, size_t name_off, size_t desc_off, struct usdt_note *usdt_note);
static int parse_usdt_spec(struct usdt_spec *spec, const struct usdt_note *note, __u64 usdt_cookie); @@ -568,8 +573,8 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char * const char *usdt_provider, const char *usdt_name, __u64 usdt_cookie, struct usdt_target **out_targets, size_t *out_target_cnt) { - size_t off, name_off, desc_off, seg_cnt = 0, lib_seg_cnt = 0, target_cnt = 0; - struct elf_seg *segs = NULL, *lib_segs = NULL; + size_t off, name_off, desc_off, seg_cnt = 0, vma_seg_cnt = 0, target_cnt = 0; + struct elf_seg *segs = NULL, *vma_segs = NULL; struct usdt_target *targets = NULL, *target; long base_addr = 0; Elf_Scn *notes_scn, *base_scn; @@ -613,8 +618,7 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char * struct elf_seg *seg = NULL; void *tmp;
- err = parse_usdt_note(elf, path, base_addr, &nhdr, - data->d_buf, name_off, desc_off, ¬e); + err = parse_usdt_note(elf, path, &nhdr, data->d_buf, name_off, desc_off, ¬e); if (err) goto err_out;
@@ -654,30 +658,29 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char * usdt_rel_ip += base_addr - note.base_addr; }
- if (ehdr.e_type == ET_EXEC) { - /* When attaching uprobes (which what USDTs basically - * are) kernel expects a relative IP to be specified, - * so if we are attaching to an executable ELF binary - * (i.e., not a shared library), we need to calculate - * proper relative IP based on ELF's load address - */ - seg = find_elf_seg(segs, seg_cnt, usdt_abs_ip, false /* relative */); - if (!seg) { - err = -ESRCH; - pr_warn("usdt: failed to find ELF program segment for '%s:%s' in '%s' at IP 0x%lx\n", - usdt_provider, usdt_name, path, usdt_abs_ip); - goto err_out; - } - if (!seg->is_exec) { - err = -ESRCH; - pr_warn("usdt: matched ELF binary '%s' segment [0x%lx, 0x%lx) for '%s:%s' at IP 0x%lx is not executable\n", - path, seg->start, seg->end, usdt_provider, usdt_name, - usdt_abs_ip); - goto err_out; - } + /* When attaching uprobes (which is what USDTs basically are) + * kernel expects file offset to be specified, not a relative + * virtual address, so we need to translate virtual address to + * file offset, for both ET_EXEC and ET_DYN binaries. + */ + seg = find_elf_seg(segs, seg_cnt, usdt_abs_ip); + if (!seg) { + err = -ESRCH; + pr_warn("usdt: failed to find ELF program segment for '%s:%s' in '%s' at IP 0x%lx\n", + usdt_provider, usdt_name, path, usdt_abs_ip); + goto err_out; + } + if (!seg->is_exec) { + err = -ESRCH; + pr_warn("usdt: matched ELF binary '%s' segment [0x%lx, 0x%lx) for '%s:%s' at IP 0x%lx is not executable\n", + path, seg->start, seg->end, usdt_provider, usdt_name, + usdt_abs_ip); + goto err_out; + } + /* translate from virtual address to file offset */ + usdt_rel_ip = usdt_abs_ip - seg->start + seg->offset;
- usdt_rel_ip = usdt_abs_ip - (seg->start - seg->offset); - } else if (!man->has_bpf_cookie) { /* ehdr.e_type == ET_DYN */ + if (ehdr.e_type == ET_DYN && !man->has_bpf_cookie) { /* If we don't have BPF cookie support but need to * attach to a shared library, we'll need to know and * record absolute addresses of attach points due to @@ -697,9 +700,9 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char * goto err_out; }
- /* lib_segs are lazily initialized only if necessary */ - if (lib_seg_cnt == 0) { - err = parse_lib_segs(pid, path, &lib_segs, &lib_seg_cnt); + /* vma_segs are lazily initialized only if necessary */ + if (vma_seg_cnt == 0) { + err = parse_vma_segs(pid, path, &vma_segs, &vma_seg_cnt); if (err) { pr_warn("usdt: failed to get memory segments in PID %d for shared library '%s': %d\n", pid, path, err); @@ -707,7 +710,7 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char * } }
- seg = find_elf_seg(lib_segs, lib_seg_cnt, usdt_rel_ip, true /* relative */); + seg = find_vma_seg(vma_segs, vma_seg_cnt, usdt_rel_ip); if (!seg) { err = -ESRCH; pr_warn("usdt: failed to find shared lib memory segment for '%s:%s' in '%s' at relative IP 0x%lx\n", @@ -715,7 +718,7 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char * goto err_out; }
- usdt_abs_ip = seg->start + (usdt_rel_ip - seg->offset); + usdt_abs_ip = seg->start - seg->offset + usdt_rel_ip; }
pr_debug("usdt: probe for '%s:%s' in %s '%s': addr 0x%lx base 0x%lx (resolved abs_ip 0x%lx rel_ip 0x%lx) args '%s' in segment [0x%lx, 0x%lx) at offset 0x%lx\n", @@ -723,7 +726,7 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char * note.loc_addr, note.base_addr, usdt_abs_ip, usdt_rel_ip, note.args, seg ? seg->start : 0, seg ? seg->end : 0, seg ? seg->offset : 0);
- /* Adjust semaphore address to be a relative offset */ + /* Adjust semaphore address to be a file offset */ if (note.sema_addr) { if (!man->has_sema_refcnt) { pr_warn("usdt: kernel doesn't support USDT semaphore refcounting for '%s:%s' in '%s'\n", @@ -732,7 +735,7 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char * goto err_out; }
- seg = find_elf_seg(segs, seg_cnt, note.sema_addr, false /* relative */); + seg = find_elf_seg(segs, seg_cnt, note.sema_addr); if (!seg) { err = -ESRCH; pr_warn("usdt: failed to find ELF loadable segment with semaphore of '%s:%s' in '%s' at 0x%lx\n", @@ -747,7 +750,7 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char * goto err_out; }
- usdt_sema_off = note.sema_addr - (seg->start - seg->offset); + usdt_sema_off = note.sema_addr - seg->start + seg->offset;
pr_debug("usdt: sema for '%s:%s' in %s '%s': addr 0x%lx base 0x%lx (resolved 0x%lx) in segment [0x%lx, 0x%lx] at offset 0x%lx\n", usdt_provider, usdt_name, ehdr.e_type == ET_EXEC ? "exec" : "lib ", @@ -770,7 +773,7 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char * target->rel_ip = usdt_rel_ip; target->sema_off = usdt_sema_off;
- /* notes->args references strings from Elf itself, so they can + /* notes.args references strings from Elf itself, so they can * be referenced safely until elf_end() call */ target->spec_str = note.args; @@ -788,7 +791,7 @@ static int collect_usdt_targets(struct usdt_manager *man, Elf *elf, const char *
err_out: free(segs); - free(lib_segs); + free(vma_segs); if (err < 0) free(targets); return err; @@ -1089,8 +1092,8 @@ struct bpf_link *usdt_manager_attach_usdt(struct usdt_manager *man, const struct /* Parse out USDT ELF note from '.note.stapsdt' section. * Logic inspired by perf's code. */ -static int parse_usdt_note(Elf *elf, const char *path, long base_addr, - GElf_Nhdr *nhdr, const char *data, size_t name_off, size_t desc_off, +static int parse_usdt_note(Elf *elf, const char *path, GElf_Nhdr *nhdr, + const char *data, size_t name_off, size_t desc_off, struct usdt_note *note) { const char *provider, *name, *args; diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 2d3c8c8f558a..19ad83d306e0 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -172,13 +172,15 @@ $(OUTPUT)/%:%.c # do not fail. Static builds leave urandom_read relying on system-wide shared libraries. $(OUTPUT)/liburandom_read.so: urandom_read_lib1.c urandom_read_lib2.c $(call msg,LIB,,$@) - $(Q)$(CC) $(filter-out -static,$(CFLAGS) $(LDFLAGS)) $^ $(LDLIBS) -fPIC -shared -o $@ + $(Q)$(CLANG) $(filter-out -static,$(CFLAGS) $(LDFLAGS)) $^ $(LDLIBS) \ + -fuse-ld=lld -Wl,-znoseparate-code -fPIC -shared -o $@
$(OUTPUT)/urandom_read: urandom_read.c urandom_read_aux.c $(OUTPUT)/liburandom_read.so $(call msg,BINARY,,$@) - $(Q)$(CC) $(filter-out -static,$(CFLAGS) $(LDFLAGS)) $(filter %.c,$^) \ - liburandom_read.so $(LDLIBS) \ - -Wl,-rpath=. -Wl,--build-id=sha1 -o $@ + $(Q)$(CLANG) $(filter-out -static,$(CFLAGS) $(LDFLAGS)) $(filter %.c,$^) \ + liburandom_read.so $(LDLIBS) \ + -fuse-ld=lld -Wl,-znoseparate-code \ + -Wl,-rpath=. -Wl,--build-id=sha1 -o $@
$(OUTPUT)/bpf_testmod.ko: $(VMLINUX_BTF) $(wildcard bpf_testmod/Makefile bpf_testmod/*.[ch]) $(call msg,MOD,,$@) @@ -578,6 +580,8 @@ $(OUTPUT)/bench: $(OUTPUT)/bench.o \ EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \ prog_tests/tests.h map_tests/tests.h verifier/tests.h \ feature bpftool \ - $(addprefix $(OUTPUT)/,*.o *.skel.h *.lskel.h *.subskel.h no_alu32 bpf_gcc bpf_testmod.ko) + $(addprefix $(OUTPUT)/,*.o *.skel.h *.lskel.h *.subskel.h \ + no_alu32 bpf_gcc bpf_testmod.ko \ + liburandom_read.so)
.PHONY: docs docs-clean
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit 08c79c9cd67fffd0d5538ddbd3a97b0a865b5eb5 ]
LLVM's lld linker doesn't have a universal architecture support (e.g., it definitely doesn't work on s390x), so be safe and force lld for urandom_read and liburandom_read.so only on x86 architectures.
This should fix s390x CI runs.
Fixes: 3e6fe5ce4d48 ("libbpf: Fix internal USDT address translation logic for shared libraries") Signed-off-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20220617045512.1339795-1-andrii@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/Makefile | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 19ad83d306e0..21be936dd1af 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -168,18 +168,25 @@ $(OUTPUT)/%:%.c $(call msg,BINARY,,$@) $(Q)$(LINK.c) $^ $(LDLIBS) -o $@
+# LLVM's ld.lld doesn't support all the architectures, so use it only on x86 +ifeq ($(SRCARCH),x86) +LLD := lld +else +LLD := ld +endif + # Filter out -static for liburandom_read.so and its dependent targets so that static builds # do not fail. Static builds leave urandom_read relying on system-wide shared libraries. $(OUTPUT)/liburandom_read.so: urandom_read_lib1.c urandom_read_lib2.c $(call msg,LIB,,$@) $(Q)$(CLANG) $(filter-out -static,$(CFLAGS) $(LDFLAGS)) $^ $(LDLIBS) \ - -fuse-ld=lld -Wl,-znoseparate-code -fPIC -shared -o $@ + -fuse-ld=$(LLD) -Wl,-znoseparate-code -fPIC -shared -o $@
$(OUTPUT)/urandom_read: urandom_read.c urandom_read_aux.c $(OUTPUT)/liburandom_read.so $(call msg,BINARY,,$@) $(Q)$(CLANG) $(filter-out -static,$(CFLAGS) $(LDFLAGS)) $(filter %.c,$^) \ liburandom_read.so $(LDLIBS) \ - -fuse-ld=lld -Wl,-znoseparate-code \ + -fuse-ld=$(LLD) -Wl,-znoseparate-code \ -Wl,-rpath=. -Wl,--build-id=sha1 -o $@
$(OUTPUT)/bpf_testmod.ko: $(VMLINUX_BTF) $(wildcard bpf_testmod/Makefile bpf_testmod/*.[ch])
From: Eric Dumazet edumazet@google.com
[ Upstream commit 849b425cd091e1804af964b771761cfbefbafb43 ]
Blamed commit only dealt with applications issuing small writes.
Issue here is that we allow to force memory schedule for the sk_buff allocation, but we have no guarantee that sendmsg() is able to copy some payload in it.
In this patch, I make sure the socket can use up to tcp_wmem[0] bytes.
For example, if we consider tcp_wmem[0] = 4096 (default on x86), and initial skb->truesize being 1280, tcp_sendmsg() is able to copy up to 2816 bytes under memory pressure.
Before this patch a sendmsg() sending more than 2816 bytes would either block forever (if persistent memory pressure), or return -EAGAIN.
For bigger MTU networks, it is advised to increase tcp_wmem[0] to avoid sending too small packets.
v2: deal with zero copy paths.
Fixes: 8e4d980ac215 ("tcp: fix behavior for epoll edge trigger") Signed-off-by: Eric Dumazet edumazet@google.com Acked-by: Soheil Hassas Yeganeh soheil@google.com Reviewed-by: Wei Wang weiwan@google.com Reviewed-by: Shakeel Butt shakeelb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 766881775abb..3ae2ea048883 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -952,6 +952,23 @@ static int tcp_downgrade_zcopy_pure(struct sock *sk, struct sk_buff *skb) return 0; }
+static int tcp_wmem_schedule(struct sock *sk, int copy) +{ + int left; + + if (likely(sk_wmem_schedule(sk, copy))) + return copy; + + /* We could be in trouble if we have nothing queued. + * Use whatever is left in sk->sk_forward_alloc and tcp_wmem[0] + * to guarantee some progress. + */ + left = sock_net(sk)->ipv4.sysctl_tcp_wmem[0] - sk->sk_wmem_queued; + if (left > 0) + sk_forced_mem_schedule(sk, min(left, copy)); + return min(copy, sk->sk_forward_alloc); +} + static struct sk_buff *tcp_build_frag(struct sock *sk, int size_goal, int flags, struct page *page, int offset, size_t *size) { @@ -987,7 +1004,11 @@ static struct sk_buff *tcp_build_frag(struct sock *sk, int size_goal, int flags, tcp_mark_push(tp, skb); goto new_segment; } - if (tcp_downgrade_zcopy_pure(sk, skb) || !sk_wmem_schedule(sk, copy)) + if (tcp_downgrade_zcopy_pure(sk, skb)) + return NULL; + + copy = tcp_wmem_schedule(sk, copy); + if (!copy) return NULL;
if (can_coalesce) { @@ -1336,8 +1357,11 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
copy = min_t(int, copy, pfrag->size - pfrag->offset);
- if (tcp_downgrade_zcopy_pure(sk, skb) || - !sk_wmem_schedule(sk, copy)) + if (tcp_downgrade_zcopy_pure(sk, skb)) + goto wait_for_space; + + copy = tcp_wmem_schedule(sk, copy); + if (!copy) goto wait_for_space;
err = skb_copy_to_page_nocache(sk, &msg->msg_iter, skb, @@ -1364,7 +1388,8 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) skb_shinfo(skb)->flags |= SKBFL_PURE_ZEROCOPY;
if (!skb_zcopy_pure(skb)) { - if (!sk_wmem_schedule(sk, copy)) + copy = tcp_wmem_schedule(sk, copy); + if (!copy) goto wait_for_space; }
From: Alexey Khoroshilov khoroshilov@ispras.ru
[ Upstream commit d61a7b3decf7f0cf4121a7204303deefd2c7151b ]
There is no i decrement in while (i >= 0) loop.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Alexey Khoroshilov khoroshilov@ispras.ru Fixes: 359e893e8af4 ("crypto: sun8i-ss - rework handling of IV") Acked-by: Corentin Labbe clabbe.montjoie@gmail.com Tested-by: Corentin Labbe clabbe.montjoie@gmail.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c index 5bb950182026..910d6751644c 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c @@ -170,6 +170,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq) while (i >= 0) { dma_unmap_single(ss->dev, rctx->p_iv[i], ivsize, DMA_TO_DEVICE); memzero_explicit(sf->iv[i], ivsize); + i--; } return err; }
From: Oleksij Rempel o.rempel@pengutronix.de
[ Upstream commit 225b0ed27e6ac523e5e98e7395392446859c7f20 ]
Current kernel will compile this driver with warnings. This patch will fix it.
drivers/net/ethernet/atheros/ag71xx.c: In function 'ag71xx_fast_reset': drivers/net/ethernet/atheros/ag71xx.c:996:31: warning: passing argument 2 of 'ag71xx_hw_set _macaddr' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] 996 | ag71xx_hw_set_macaddr(ag, dev->dev_addr); | ~~~^~~~~~~~~~ drivers/net/ethernet/atheros/ag71xx.c:951:69: note: expected 'unsigned char *' but argument is of type 'const unsigned char *' 951 | static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) | ~~~~~~~~~~~~~~~^~~ drivers/net/ethernet/atheros/ag71xx.c: In function 'ag71xx_open': drivers/net/ethernet/atheros/ag71xx.c:1441:32: warning: passing argument 2 of 'ag71xx_hw_se t_macaddr' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] 1441 | ag71xx_hw_set_macaddr(ag, ndev->dev_addr); | ~~~~^~~~~~~~~~ drivers/net/ethernet/atheros/ag71xx.c:951:69: note: expected 'unsigned char *' but argument is of type 'const unsigned char *' 951 | static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) | ~~~~~~~~~~~~~~~^~~
Fixes: adeef3e32146 ("net: constify netdev->dev_addr") Signed-off-by: Oleksij Rempel o.rempel@pengutronix.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/atheros/ag71xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c index cac509708e9d..1c6ea6766aa1 100644 --- a/drivers/net/ethernet/atheros/ag71xx.c +++ b/drivers/net/ethernet/atheros/ag71xx.c @@ -946,7 +946,7 @@ static unsigned int ag71xx_max_frame_len(unsigned int mtu) return ETH_HLEN + VLAN_HLEN + mtu + ETH_FCS_LEN; }
-static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) +static void ag71xx_hw_set_macaddr(struct ag71xx *ag, const unsigned char *mac) { u32 t;
From: Eric Dumazet edumazet@google.com
[ Upstream commit dbca1596bbb08318f5e3b3b99f8ca0a0d3830a65 ]
Using rwlock in networking code is extremely risky. writers can starve if enough readers are constantly grabing the rwlock.
I thought rwlock were at fault and sent this patch:
https://lkml.org/lkml/2022/6/17/272
But Peter and Linus essentially told me rwlock had to be unfair.
We need to get rid of rwlock in networking code.
Fixes: c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP socket kind") 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/ping.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-)
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 3c6101def7d6..b83c2bd9d722 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -50,7 +50,7 @@
struct ping_table { struct hlist_nulls_head hash[PING_HTABLE_SIZE]; - rwlock_t lock; + spinlock_t lock; };
static struct ping_table ping_table; @@ -82,7 +82,7 @@ int ping_get_port(struct sock *sk, unsigned short ident) struct sock *sk2 = NULL;
isk = inet_sk(sk); - write_lock_bh(&ping_table.lock); + spin_lock(&ping_table.lock); if (ident == 0) { u32 i; u16 result = ping_port_rover + 1; @@ -128,14 +128,15 @@ int ping_get_port(struct sock *sk, unsigned short ident) if (sk_unhashed(sk)) { pr_debug("was not hashed\n"); sock_hold(sk); - hlist_nulls_add_head(&sk->sk_nulls_node, hlist); + sock_set_flag(sk, SOCK_RCU_FREE); + hlist_nulls_add_head_rcu(&sk->sk_nulls_node, hlist); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); } - write_unlock_bh(&ping_table.lock); + spin_unlock(&ping_table.lock); return 0;
fail: - write_unlock_bh(&ping_table.lock); + spin_unlock(&ping_table.lock); return 1; } EXPORT_SYMBOL_GPL(ping_get_port); @@ -153,19 +154,19 @@ void ping_unhash(struct sock *sk) struct inet_sock *isk = inet_sk(sk);
pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num); - write_lock_bh(&ping_table.lock); + spin_lock(&ping_table.lock); if (sk_hashed(sk)) { - hlist_nulls_del(&sk->sk_nulls_node); - sk_nulls_node_init(&sk->sk_nulls_node); + hlist_nulls_del_init_rcu(&sk->sk_nulls_node); sock_put(sk); isk->inet_num = 0; isk->inet_sport = 0; sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); } - write_unlock_bh(&ping_table.lock); + spin_unlock(&ping_table.lock); } EXPORT_SYMBOL_GPL(ping_unhash);
+/* Called under rcu_read_lock() */ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) { struct hlist_nulls_head *hslot = ping_hashslot(&ping_table, net, ident); @@ -190,8 +191,6 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) return NULL; }
- read_lock_bh(&ping_table.lock); - ping_portaddr_for_each_entry(sk, hnode, hslot) { isk = inet_sk(sk);
@@ -230,13 +229,11 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) sk->sk_bound_dev_if != sdif) continue;
- sock_hold(sk); goto exit; }
sk = NULL; exit: - read_unlock_bh(&ping_table.lock);
return sk; } @@ -592,7 +589,7 @@ void ping_err(struct sk_buff *skb, int offset, u32 info) sk->sk_err = err; sk_error_report(sk); out: - sock_put(sk); + return; } EXPORT_SYMBOL_GPL(ping_err);
@@ -998,7 +995,6 @@ enum skb_drop_reason ping_rcv(struct sk_buff *skb) reason = __ping_queue_rcv_skb(sk, skb2); else reason = SKB_DROP_REASON_NOMEM; - sock_put(sk); }
if (reason) @@ -1084,13 +1080,13 @@ static struct sock *ping_get_idx(struct seq_file *seq, loff_t pos) }
void *ping_seq_start(struct seq_file *seq, loff_t *pos, sa_family_t family) - __acquires(ping_table.lock) + __acquires(RCU) { struct ping_iter_state *state = seq->private; state->bucket = 0; state->family = family;
- read_lock_bh(&ping_table.lock); + rcu_read_lock();
return *pos ? ping_get_idx(seq, *pos-1) : SEQ_START_TOKEN; } @@ -1116,9 +1112,9 @@ void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos) EXPORT_SYMBOL_GPL(ping_seq_next);
void ping_seq_stop(struct seq_file *seq, void *v) - __releases(ping_table.lock) + __releases(RCU) { - read_unlock_bh(&ping_table.lock); + rcu_read_unlock(); } EXPORT_SYMBOL_GPL(ping_seq_stop);
@@ -1202,5 +1198,5 @@ void __init ping_init(void)
for (i = 0; i < PING_HTABLE_SIZE; i++) INIT_HLIST_NULLS_HEAD(&ping_table.hash[i], i); - rwlock_init(&ping_table.lock); + spin_lock_init(&ping_table.lock); }
From: Eric Dumazet edumazet@google.com
[ Upstream commit ba44f8182ec299c5d1c8a72fc0fde4ec127b5a6d ]
In order to prepare the following patch, I change raw v4 & v6 code to use more conventional iterators.
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 --- include/net/raw.h | 5 +-- include/net/rawv6.h | 6 +-- net/ipv4/raw.c | 93 ++++++++++++++------------------------- net/ipv4/raw_diag.c | 33 +++++++------- net/ipv6/raw.c | 105 ++++++++++++++++---------------------------- 5 files changed, 92 insertions(+), 150 deletions(-)
diff --git a/include/net/raw.h b/include/net/raw.h index c51a635671a7..6324965779ec 100644 --- a/include/net/raw.h +++ b/include/net/raw.h @@ -20,9 +20,8 @@ extern struct proto raw_prot;
extern struct raw_hashinfo raw_v4_hashinfo; -struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, - unsigned short num, __be32 raddr, - __be32 laddr, int dif, int sdif); +bool raw_v4_match(struct net *net, struct sock *sk, unsigned short num, + __be32 raddr, __be32 laddr, int dif, int sdif);
int raw_abort(struct sock *sk, int err); void raw_icmp_error(struct sk_buff *, int, u32); diff --git a/include/net/rawv6.h b/include/net/rawv6.h index 53d86b6055e8..c48c1298699a 100644 --- a/include/net/rawv6.h +++ b/include/net/rawv6.h @@ -5,9 +5,9 @@ #include <net/protocol.h>
extern struct raw_hashinfo raw_v6_hashinfo; -struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, - unsigned short num, const struct in6_addr *loc_addr, - const struct in6_addr *rmt_addr, int dif, int sdif); +bool raw_v6_match(struct net *net, struct sock *sk, unsigned short num, + const struct in6_addr *loc_addr, + const struct in6_addr *rmt_addr, int dif, int sdif);
int raw_abort(struct sock *sk, int err);
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index bbd717805b10..05e0de4a7c7f 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -117,24 +117,19 @@ void raw_unhash_sk(struct sock *sk) } EXPORT_SYMBOL_GPL(raw_unhash_sk);
-struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, - unsigned short num, __be32 raddr, __be32 laddr, - int dif, int sdif) +bool raw_v4_match(struct net *net, struct sock *sk, unsigned short num, + __be32 raddr, __be32 laddr, int dif, int sdif) { - sk_for_each_from(sk) { - struct inet_sock *inet = inet_sk(sk); - - if (net_eq(sock_net(sk), net) && inet->inet_num == num && - !(inet->inet_daddr && inet->inet_daddr != raddr) && - !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) && - raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) - goto found; /* gotcha */ - } - sk = NULL; -found: - return sk; + struct inet_sock *inet = inet_sk(sk); + + if (net_eq(sock_net(sk), net) && inet->inet_num == num && + !(inet->inet_daddr && inet->inet_daddr != raddr) && + !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) && + raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) + return true; + return false; } -EXPORT_SYMBOL_GPL(__raw_v4_lookup); +EXPORT_SYMBOL_GPL(raw_v4_match);
/* * 0 - deliver @@ -168,23 +163,21 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb) */ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) { + struct net *net = dev_net(skb->dev); int sdif = inet_sdif(skb); int dif = inet_iif(skb); - struct sock *sk; struct hlist_head *head; int delivered = 0; - struct net *net; + struct sock *sk;
- read_lock(&raw_v4_hashinfo.lock); head = &raw_v4_hashinfo.ht[hash]; if (hlist_empty(head)) - goto out; - - net = dev_net(skb->dev); - sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol, - iph->saddr, iph->daddr, dif, sdif); - - while (sk) { + return 0; + read_lock(&raw_v4_hashinfo.lock); + sk_for_each(sk, head) { + if (!raw_v4_match(net, sk, iph->protocol, + iph->saddr, iph->daddr, dif, sdif)) + continue; delivered = 1; if ((iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) && ip_mc_sf_allow(sk, iph->daddr, iph->saddr, @@ -195,31 +188,16 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) if (clone) raw_rcv(sk, clone); } - sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol, - iph->saddr, iph->daddr, - dif, sdif); } -out: read_unlock(&raw_v4_hashinfo.lock); return delivered; }
int raw_local_deliver(struct sk_buff *skb, int protocol) { - int hash; - struct sock *raw_sk; - - hash = protocol & (RAW_HTABLE_SIZE - 1); - raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]); - - /* If there maybe a raw socket we must check - if not we - * don't care less - */ - if (raw_sk && !raw_v4_input(skb, ip_hdr(skb), hash)) - raw_sk = NULL; - - return raw_sk != NULL; + int hash = protocol & (RAW_HTABLE_SIZE - 1);
+ return raw_v4_input(skb, ip_hdr(skb), hash); }
static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info) @@ -286,29 +264,24 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info) { - int hash; - struct sock *raw_sk; + struct net *net = dev_net(skb->dev);; + int dif = skb->dev->ifindex; + int sdif = inet_sdif(skb); + struct hlist_head *head; const struct iphdr *iph; - struct net *net; + struct sock *sk; + int hash;
hash = protocol & (RAW_HTABLE_SIZE - 1); + head = &raw_v4_hashinfo.ht[hash];
read_lock(&raw_v4_hashinfo.lock); - raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]); - if (raw_sk) { - int dif = skb->dev->ifindex; - int sdif = inet_sdif(skb); - + sk_for_each(sk, head) { iph = (const struct iphdr *)skb->data; - net = dev_net(skb->dev); - - while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol, - iph->daddr, iph->saddr, - dif, sdif)) != NULL) { - raw_err(raw_sk, skb, info); - raw_sk = sk_next(raw_sk); - iph = (const struct iphdr *)skb->data; - } + if (!raw_v4_match(net, sk, iph->protocol, + iph->saddr, iph->daddr, dif, sdif)) + continue; + raw_err(sk, skb, info); } read_unlock(&raw_v4_hashinfo.lock); } diff --git a/net/ipv4/raw_diag.c b/net/ipv4/raw_diag.c index ccacbde30a2c..b6d92dc7b051 100644 --- a/net/ipv4/raw_diag.c +++ b/net/ipv4/raw_diag.c @@ -34,31 +34,30 @@ raw_get_hashinfo(const struct inet_diag_req_v2 *r) * use helper to figure it out. */
-static struct sock *raw_lookup(struct net *net, struct sock *from, - const struct inet_diag_req_v2 *req) +static bool raw_lookup(struct net *net, struct sock *sk, + const struct inet_diag_req_v2 *req) { struct inet_diag_req_raw *r = (void *)req; - struct sock *sk = NULL;
if (r->sdiag_family == AF_INET) - sk = __raw_v4_lookup(net, from, r->sdiag_raw_protocol, - r->id.idiag_dst[0], - r->id.idiag_src[0], - r->id.idiag_if, 0); + return raw_v4_match(net, sk, r->sdiag_raw_protocol, + r->id.idiag_dst[0], + r->id.idiag_src[0], + r->id.idiag_if, 0); #if IS_ENABLED(CONFIG_IPV6) else - sk = __raw_v6_lookup(net, from, r->sdiag_raw_protocol, - (const struct in6_addr *)r->id.idiag_src, - (const struct in6_addr *)r->id.idiag_dst, - r->id.idiag_if, 0); + return raw_v6_match(net, sk, r->sdiag_raw_protocol, + (const struct in6_addr *)r->id.idiag_src, + (const struct in6_addr *)r->id.idiag_dst, + r->id.idiag_if, 0); #endif - return sk; + return false; }
static struct sock *raw_sock_get(struct net *net, const struct inet_diag_req_v2 *r) { struct raw_hashinfo *hashinfo = raw_get_hashinfo(r); - struct sock *sk = NULL, *s; + struct sock *sk; int slot;
if (IS_ERR(hashinfo)) @@ -66,9 +65,8 @@ static struct sock *raw_sock_get(struct net *net, const struct inet_diag_req_v2
read_lock(&hashinfo->lock); for (slot = 0; slot < RAW_HTABLE_SIZE; slot++) { - sk_for_each(s, &hashinfo->ht[slot]) { - sk = raw_lookup(net, s, r); - if (sk) { + sk_for_each(sk, &hashinfo->ht[slot]) { + if (raw_lookup(net, sk, r)) { /* * Grab it and keep until we fill * diag meaage to be reported, so @@ -81,10 +79,11 @@ static struct sock *raw_sock_get(struct net *net, const struct inet_diag_req_v2 } } } + sk = ERR_PTR(-ENOENT); out_unlock: read_unlock(&hashinfo->lock);
- return sk ? sk : ERR_PTR(-ENOENT); + return sk; }
static int raw_diag_dump_one(struct netlink_callback *cb, diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 3b7cbd522b54..c0f2e3475984 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -66,41 +66,27 @@ struct raw_hashinfo raw_v6_hashinfo = { }; EXPORT_SYMBOL_GPL(raw_v6_hashinfo);
-struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, - unsigned short num, const struct in6_addr *loc_addr, - const struct in6_addr *rmt_addr, int dif, int sdif) +bool raw_v6_match(struct net *net, struct sock *sk, unsigned short num, + const struct in6_addr *loc_addr, + const struct in6_addr *rmt_addr, int dif, int sdif) { - bool is_multicast = ipv6_addr_is_multicast(loc_addr); - - sk_for_each_from(sk) - if (inet_sk(sk)->inet_num == num) { - - if (!net_eq(sock_net(sk), net)) - continue; - - if (!ipv6_addr_any(&sk->sk_v6_daddr) && - !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) - continue; - - if (!raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if, - dif, sdif)) - continue; - - if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { - if (ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr)) - goto found; - if (is_multicast && - inet6_mc_check(sk, loc_addr, rmt_addr)) - goto found; - continue; - } - goto found; - } - sk = NULL; -found: - return sk; + if (inet_sk(sk)->inet_num != num || + !net_eq(sock_net(sk), net) || + (!ipv6_addr_any(&sk->sk_v6_daddr) && + !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) || + !raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if, + dif, sdif)) + return false; + + if (ipv6_addr_any(&sk->sk_v6_rcv_saddr) || + ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr) || + (ipv6_addr_is_multicast(loc_addr) && + inet6_mc_check(sk, loc_addr, rmt_addr))) + return true; + + return false; } -EXPORT_SYMBOL_GPL(__raw_v6_lookup); +EXPORT_SYMBOL_GPL(raw_v6_match);
/* * 0 - deliver @@ -156,31 +142,28 @@ EXPORT_SYMBOL(rawv6_mh_filter_unregister); */ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) { + struct net *net = dev_net(skb->dev); const struct in6_addr *saddr; const struct in6_addr *daddr; + struct hlist_head *head; struct sock *sk; bool delivered = false; __u8 hash; - struct net *net;
saddr = &ipv6_hdr(skb)->saddr; daddr = saddr + 1;
hash = nexthdr & (RAW_HTABLE_SIZE - 1); - + head = &raw_v6_hashinfo.ht[hash]; + if (hlist_empty(head)) + return false; read_lock(&raw_v6_hashinfo.lock); - sk = sk_head(&raw_v6_hashinfo.ht[hash]); - - if (!sk) - goto out; - - net = dev_net(skb->dev); - sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, - inet6_iif(skb), inet6_sdif(skb)); - - while (sk) { + sk_for_each(sk, head) { int filtered;
+ if (!raw_v6_match(net, sk, nexthdr, daddr, saddr, + inet6_iif(skb), inet6_sdif(skb))) + continue; delivered = true; switch (nexthdr) { case IPPROTO_ICMPV6: @@ -219,23 +202,14 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) rawv6_rcv(sk, clone); } } - sk = __raw_v6_lookup(net, sk_next(sk), nexthdr, daddr, saddr, - inet6_iif(skb), inet6_sdif(skb)); } -out: read_unlock(&raw_v6_hashinfo.lock); return delivered; }
bool raw6_local_deliver(struct sk_buff *skb, int nexthdr) { - struct sock *raw_sk; - - raw_sk = sk_head(&raw_v6_hashinfo.ht[nexthdr & (RAW_HTABLE_SIZE - 1)]); - if (raw_sk && !ipv6_raw_deliver(skb, nexthdr)) - raw_sk = NULL; - - return raw_sk != NULL; + return ipv6_raw_deliver(skb, nexthdr); }
/* This cleans up af_inet6 a bit. -DaveM */ @@ -361,28 +335,25 @@ static void rawv6_err(struct sock *sk, struct sk_buff *skb, void raw6_icmp_error(struct sk_buff *skb, int nexthdr, u8 type, u8 code, int inner_offset, __be32 info) { + const struct in6_addr *saddr, *daddr; + struct net *net = dev_net(skb->dev); + struct hlist_head *head; struct sock *sk; int hash; - const struct in6_addr *saddr, *daddr; - struct net *net;
hash = nexthdr & (RAW_HTABLE_SIZE - 1); - + head = &raw_v6_hashinfo.ht[hash]; read_lock(&raw_v6_hashinfo.lock); - sk = sk_head(&raw_v6_hashinfo.ht[hash]); - if (sk) { + sk_for_each(sk, head) { /* Note: ipv6_hdr(skb) != skb->data */ const struct ipv6hdr *ip6h = (const struct ipv6hdr *)skb->data; saddr = &ip6h->saddr; daddr = &ip6h->daddr; - net = dev_net(skb->dev);
- while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr, - inet6_iif(skb), inet6_iif(skb)))) { - rawv6_err(sk, skb, NULL, type, code, - inner_offset, info); - sk = sk_next(sk); - } + if (!raw_v6_match(net, sk, nexthdr, &ip6h->saddr, &ip6h->daddr, + inet6_iif(skb), inet6_iif(skb))) + continue; + rawv6_err(sk, skb, NULL, type, code, inner_offset, info); } read_unlock(&raw_v6_hashinfo.lock); }
From: Eric Dumazet edumazet@google.com
[ Upstream commit 0daf07e527095e64ee8927ce297ab626643e9f51 ]
Using rwlock in networking code is extremely risky. writers can starve if enough readers are constantly grabing the rwlock.
I thought rwlock were at fault and sent this patch:
https://lkml.org/lkml/2022/6/17/272
But Peter and Linus essentially told me rwlock had to be unfair.
We need to get rid of rwlock in networking code.
Without this fix, following script triggers soft lockups:
for i in {1..48} do ping -f -n -q 127.0.0.1 & sleep 0.1 done
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") 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 --- include/net/raw.h | 11 +++++- include/net/rawv6.h | 1 + net/ipv4/af_inet.c | 2 ++ net/ipv4/raw.c | 83 +++++++++++++++++++++------------------------ net/ipv4/raw_diag.c | 22 +++++++----- net/ipv6/af_inet6.c | 3 ++ net/ipv6/raw.c | 28 +++++++-------- 7 files changed, 80 insertions(+), 70 deletions(-)
diff --git a/include/net/raw.h b/include/net/raw.h index 6324965779ec..537d9d1df890 100644 --- a/include/net/raw.h +++ b/include/net/raw.h @@ -33,9 +33,18 @@ int raw_rcv(struct sock *, struct sk_buff *);
struct raw_hashinfo { rwlock_t lock; - struct hlist_head ht[RAW_HTABLE_SIZE]; + struct hlist_nulls_head ht[RAW_HTABLE_SIZE]; };
+static inline void raw_hashinfo_init(struct raw_hashinfo *hashinfo) +{ + int i; + + rwlock_init(&hashinfo->lock); + for (i = 0; i < RAW_HTABLE_SIZE; i++) + INIT_HLIST_NULLS_HEAD(&hashinfo->ht[i], i); +} + #ifdef CONFIG_PROC_FS int raw_proc_init(void); void raw_proc_exit(void); diff --git a/include/net/rawv6.h b/include/net/rawv6.h index c48c1298699a..bc70909625f6 100644 --- a/include/net/rawv6.h +++ b/include/net/rawv6.h @@ -3,6 +3,7 @@ #define _NET_RAWV6_H
#include <net/protocol.h> +#include <net/raw.h>
extern struct raw_hashinfo raw_v6_hashinfo; bool raw_v6_match(struct net *net, struct sock *sk, unsigned short num, diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 252c8bceaba4..6f5556cb0d97 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1919,6 +1919,8 @@ static int __init inet_init(void)
sock_skb_cb_check_size(sizeof(struct inet_skb_parm));
+ raw_hashinfo_init(&raw_v4_hashinfo); + rc = proto_register(&tcp_prot, 1); if (rc) goto out; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 05e0de4a7c7f..d28bf0b901a2 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -85,20 +85,19 @@ struct raw_frag_vec { int hlen; };
-struct raw_hashinfo raw_v4_hashinfo = { - .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock), -}; +struct raw_hashinfo raw_v4_hashinfo; EXPORT_SYMBOL_GPL(raw_v4_hashinfo);
int raw_hash_sk(struct sock *sk) { struct raw_hashinfo *h = sk->sk_prot->h.raw_hash; - struct hlist_head *head; + struct hlist_nulls_head *hlist;
- head = &h->ht[inet_sk(sk)->inet_num & (RAW_HTABLE_SIZE - 1)]; + hlist = &h->ht[inet_sk(sk)->inet_num & (RAW_HTABLE_SIZE - 1)];
write_lock_bh(&h->lock); - sk_add_node(sk, head); + hlist_nulls_add_head_rcu(&sk->sk_nulls_node, hlist); + sock_set_flag(sk, SOCK_RCU_FREE); write_unlock_bh(&h->lock); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
@@ -111,7 +110,7 @@ void raw_unhash_sk(struct sock *sk) struct raw_hashinfo *h = sk->sk_prot->h.raw_hash;
write_lock_bh(&h->lock); - if (sk_del_node_init(sk)) + if (__sk_nulls_del_node_init_rcu(sk)) sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); write_unlock_bh(&h->lock); } @@ -164,17 +163,16 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb) static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) { struct net *net = dev_net(skb->dev); + struct hlist_nulls_head *hlist; + struct hlist_nulls_node *hnode; int sdif = inet_sdif(skb); int dif = inet_iif(skb); - struct hlist_head *head; int delivered = 0; struct sock *sk;
- head = &raw_v4_hashinfo.ht[hash]; - if (hlist_empty(head)) - return 0; - read_lock(&raw_v4_hashinfo.lock); - sk_for_each(sk, head) { + hlist = &raw_v4_hashinfo.ht[hash]; + rcu_read_lock(); + hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) { if (!raw_v4_match(net, sk, iph->protocol, iph->saddr, iph->daddr, dif, sdif)) continue; @@ -189,7 +187,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) raw_rcv(sk, clone); } } - read_unlock(&raw_v4_hashinfo.lock); + rcu_read_unlock(); return delivered; }
@@ -265,25 +263,26 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info) void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info) { struct net *net = dev_net(skb->dev);; + struct hlist_nulls_head *hlist; + struct hlist_nulls_node *hnode; int dif = skb->dev->ifindex; int sdif = inet_sdif(skb); - struct hlist_head *head; const struct iphdr *iph; struct sock *sk; int hash;
hash = protocol & (RAW_HTABLE_SIZE - 1); - head = &raw_v4_hashinfo.ht[hash]; + hlist = &raw_v4_hashinfo.ht[hash];
- read_lock(&raw_v4_hashinfo.lock); - sk_for_each(sk, head) { + rcu_read_lock(); + hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) { iph = (const struct iphdr *)skb->data; if (!raw_v4_match(net, sk, iph->protocol, iph->saddr, iph->daddr, dif, sdif)) continue; raw_err(sk, skb, info); } - read_unlock(&raw_v4_hashinfo.lock); + rcu_read_unlock(); }
static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb) @@ -944,44 +943,41 @@ struct proto raw_prot = { };
#ifdef CONFIG_PROC_FS -static struct sock *raw_get_first(struct seq_file *seq) +static struct sock *raw_get_first(struct seq_file *seq, int bucket) { - struct sock *sk; struct raw_hashinfo *h = pde_data(file_inode(seq->file)); struct raw_iter_state *state = raw_seq_private(seq); + struct hlist_nulls_head *hlist; + struct hlist_nulls_node *hnode; + struct sock *sk;
- for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE; + for (state->bucket = bucket; state->bucket < RAW_HTABLE_SIZE; ++state->bucket) { - sk_for_each(sk, &h->ht[state->bucket]) + hlist = &h->ht[state->bucket]; + hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) { if (sock_net(sk) == seq_file_net(seq)) - goto found; + return sk; + } } - sk = NULL; -found: - return sk; + return NULL; }
static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk) { - struct raw_hashinfo *h = pde_data(file_inode(seq->file)); struct raw_iter_state *state = raw_seq_private(seq);
do { - sk = sk_next(sk); -try_again: - ; + sk = sk_nulls_next(sk); } while (sk && sock_net(sk) != seq_file_net(seq));
- if (!sk && ++state->bucket < RAW_HTABLE_SIZE) { - sk = sk_head(&h->ht[state->bucket]); - goto try_again; - } + if (!sk) + return raw_get_first(seq, state->bucket + 1); return sk; }
static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos) { - struct sock *sk = raw_get_first(seq); + struct sock *sk = raw_get_first(seq, 0);
if (sk) while (pos && (sk = raw_get_next(seq, sk)) != NULL) @@ -990,11 +986,9 @@ static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos) }
void *raw_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(&h->lock) + __acquires(RCU) { - struct raw_hashinfo *h = pde_data(file_inode(seq->file)); - - read_lock(&h->lock); + rcu_read_lock(); return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; } EXPORT_SYMBOL_GPL(raw_seq_start); @@ -1004,7 +998,7 @@ void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos) struct sock *sk;
if (v == SEQ_START_TOKEN) - sk = raw_get_first(seq); + sk = raw_get_first(seq, 0); else sk = raw_get_next(seq, v); ++*pos; @@ -1013,11 +1007,9 @@ void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos) EXPORT_SYMBOL_GPL(raw_seq_next);
void raw_seq_stop(struct seq_file *seq, void *v) - __releases(&h->lock) + __releases(RCU) { - struct raw_hashinfo *h = pde_data(file_inode(seq->file)); - - read_unlock(&h->lock); + rcu_read_unlock(); } EXPORT_SYMBOL_GPL(raw_seq_stop);
@@ -1079,6 +1071,7 @@ static __net_initdata struct pernet_operations raw_net_ops = {
int __init raw_proc_init(void) { + return register_pernet_subsys(&raw_net_ops); }
diff --git a/net/ipv4/raw_diag.c b/net/ipv4/raw_diag.c index b6d92dc7b051..5f208e840d85 100644 --- a/net/ipv4/raw_diag.c +++ b/net/ipv4/raw_diag.c @@ -57,31 +57,32 @@ static bool raw_lookup(struct net *net, struct sock *sk, static struct sock *raw_sock_get(struct net *net, const struct inet_diag_req_v2 *r) { struct raw_hashinfo *hashinfo = raw_get_hashinfo(r); + struct hlist_nulls_head *hlist; + struct hlist_nulls_node *hnode; struct sock *sk; int slot;
if (IS_ERR(hashinfo)) return ERR_CAST(hashinfo);
- read_lock(&hashinfo->lock); + rcu_read_lock(); for (slot = 0; slot < RAW_HTABLE_SIZE; slot++) { - sk_for_each(sk, &hashinfo->ht[slot]) { + hlist = &hashinfo->ht[slot]; + hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) { if (raw_lookup(net, sk, r)) { /* * Grab it and keep until we fill - * diag meaage to be reported, so + * diag message to be reported, so * caller should call sock_put then. - * We can do that because we're keeping - * hashinfo->lock here. */ - sock_hold(sk); - goto out_unlock; + if (refcount_inc_not_zero(&sk->sk_refcnt)) + goto out_unlock; } } } sk = ERR_PTR(-ENOENT); out_unlock: - read_unlock(&hashinfo->lock); + rcu_read_unlock();
return sk; } @@ -141,6 +142,8 @@ static void raw_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, struct raw_hashinfo *hashinfo = raw_get_hashinfo(r); struct net *net = sock_net(skb->sk); struct inet_diag_dump_data *cb_data; + struct hlist_nulls_head *hlist; + struct hlist_nulls_node *hnode; int num, s_num, slot, s_slot; struct sock *sk = NULL; struct nlattr *bc; @@ -157,7 +160,8 @@ static void raw_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, for (slot = s_slot; slot < RAW_HTABLE_SIZE; s_num = 0, slot++) { num = 0;
- sk_for_each(sk, &hashinfo->ht[slot]) { + hlist = &hashinfo->ht[slot]; + hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) { struct inet_sock *inet = inet_sk(sk);
if (!net_eq(sock_net(sk), net)) diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 6f354f8be2c5..9f6f4a41245d 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -63,6 +63,7 @@ #include <net/compat.h> #include <net/xfrm.h> #include <net/ioam6.h> +#include <net/rawv6.h>
#include <linux/uaccess.h> #include <linux/mroute6.h> @@ -1073,6 +1074,8 @@ static int __init inet6_init(void) goto out; }
+ raw_hashinfo_init(&raw_v6_hashinfo); + err = proto_register(&tcpv6_prot, 1); if (err) goto out; diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index c0f2e3475984..f6119998700e 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -61,9 +61,7 @@
#define ICMPV6_HDRLEN 4 /* ICMPv6 header, RFC 4443 Section 2.1 */
-struct raw_hashinfo raw_v6_hashinfo = { - .lock = __RW_LOCK_UNLOCKED(raw_v6_hashinfo.lock), -}; +struct raw_hashinfo raw_v6_hashinfo; EXPORT_SYMBOL_GPL(raw_v6_hashinfo);
bool raw_v6_match(struct net *net, struct sock *sk, unsigned short num, @@ -143,9 +141,10 @@ EXPORT_SYMBOL(rawv6_mh_filter_unregister); static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) { struct net *net = dev_net(skb->dev); + struct hlist_nulls_head *hlist; + struct hlist_nulls_node *hnode; const struct in6_addr *saddr; const struct in6_addr *daddr; - struct hlist_head *head; struct sock *sk; bool delivered = false; __u8 hash; @@ -154,11 +153,9 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) daddr = saddr + 1;
hash = nexthdr & (RAW_HTABLE_SIZE - 1); - head = &raw_v6_hashinfo.ht[hash]; - if (hlist_empty(head)) - return false; - read_lock(&raw_v6_hashinfo.lock); - sk_for_each(sk, head) { + hlist = &raw_v6_hashinfo.ht[hash]; + rcu_read_lock(); + hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) { int filtered;
if (!raw_v6_match(net, sk, nexthdr, daddr, saddr, @@ -203,7 +200,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) } } } - read_unlock(&raw_v6_hashinfo.lock); + rcu_read_unlock(); return delivered; }
@@ -337,14 +334,15 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr, { const struct in6_addr *saddr, *daddr; struct net *net = dev_net(skb->dev); - struct hlist_head *head; + struct hlist_nulls_head *hlist; + struct hlist_nulls_node *hnode; struct sock *sk; int hash;
hash = nexthdr & (RAW_HTABLE_SIZE - 1); - head = &raw_v6_hashinfo.ht[hash]; - read_lock(&raw_v6_hashinfo.lock); - sk_for_each(sk, head) { + hlist = &raw_v6_hashinfo.ht[hash]; + rcu_read_lock(); + hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) { /* Note: ipv6_hdr(skb) != skb->data */ const struct ipv6hdr *ip6h = (const struct ipv6hdr *)skb->data; saddr = &ip6h->saddr; @@ -355,7 +353,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr, continue; rawv6_err(sk, skb, NULL, type, code, inner_offset, info); } - read_unlock(&raw_v6_hashinfo.lock); + rcu_read_unlock(); }
static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb)
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit 5da39e31b1b0eb62b8ed369ad9615da850239e9e ]
The trailing semicolon causes a compiler error, so let's remove it.
net/ipv4/raw.c: In function ‘raw_icmp_error’: net/ipv4/raw.c:266:2: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement] 266 | struct hlist_nulls_head *hlist; | ^~~~~~
Fixes: ba44f8182ec2 ("raw: use more conventional iterators") Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/raw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index d28bf0b901a2..b3b255db9021 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -262,7 +262,7 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info) { - struct net *net = dev_net(skb->dev);; + struct net *net = dev_net(skb->dev); struct hlist_nulls_head *hlist; struct hlist_nulls_node *hnode; int dif = skb->dev->ifindex;
From: Eugen Hristev eugen.hristev@microchip.com
[ Upstream commit b2bae4b8e637dd751d27918a6b27bd5abcd08859 ]
All warnings (new ones prefixed by >>):
drivers/media/platform/atmel/atmel-sama7g5-isc.c:610:34: warning: unused variable 'microchip_xisc_of_match' [-Wunused-const-variable]
static const struct of_device_id microchip_xisc_of_match[] = { ^ 13 warnings generated.
vim +/microchip_xisc_of_match +610 drivers/media/platform/atmel/atmel-sama7g5-isc.c
609
610 static const struct of_device_id microchip_xisc_of_match[] = {
611 { .compatible = "microchip,sama7g5-isc" }, 612 { } 613 }; 614 MODULE_DEVICE_TABLE(of, microchip_xisc_of_match); 615
Fixed warning by guarding the atmel_isc_of_match by CONFIG_OF.
Reported-by: kernel test robot lkp@intel.com Fixes: c9aa973884a1 ("media: atmel: atmel-isc: add microchip-xisc driver") Signed-off-by: Eugen Hristev eugen.hristev@microchip.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/atmel/atmel-sama7g5-isc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c index 83b175070c06..8b11aa8340d7 100644 --- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c @@ -591,11 +591,13 @@ static const struct dev_pm_ops microchip_xisc_dev_pm_ops = { SET_RUNTIME_PM_OPS(xisc_runtime_suspend, xisc_runtime_resume, NULL) };
+#if IS_ENABLED(CONFIG_OF) static const struct of_device_id microchip_xisc_of_match[] = { { .compatible = "microchip,sama7g5-isc" }, { } }; MODULE_DEVICE_TABLE(of, microchip_xisc_of_match); +#endif
static struct platform_driver microchip_xisc_driver = { .probe = microchip_xisc_probe,
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 4c25384d136642d72098e36201ca988533e73065 ]
'supplies' is a pointer, the real size of struct regulator_bulk_data should be pass to devm_kmalloc_array().
Fixes: 0d8140179715 ("media: camss: Add regulator_bulk support") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/qcom/camss/camss-csid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index f993f349b66b..80628801cf09 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -666,7 +666,7 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, if (csid->num_supplies) { csid->supplies = devm_kmalloc_array(camss->dev, csid->num_supplies, - sizeof(csid->supplies), + sizeof(*csid->supplies), GFP_KERNEL); if (!csid->supplies) return -ENOMEM;
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit fb730334e0f759d00f72168fbc555e5a95e35210 ]
We got the following warning when booting the kernel:
[ 3.243674] INFO: trying to register non-static key. [ 3.243922] The code is fine but needs lockdep annotation, or maybe [ 3.244230] you didn't initialize this object before use? [ 3.245642] Call Trace: [ 3.247836] lock_acquire+0xff/0x2d0 [ 3.248727] tw686x_audio_irq+0x1a5/0xcc0 [tw686x] [ 3.249211] tw686x_irq+0x1f9/0x480 [tw686x]
The lock 'vc->qlock' will be initialized in tw686x_video_init(), but the driver registers the irq before calling the tw686x_video_init(), and we got the warning.
Fix this by registering the irq at the end of probe
Fixes: 704a84ccdbf1 ("[media] media: Support Intersil/Techwell TW686x-based video capture cards") Signed-off-by: Zheyu Ma zheyuma97@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/tw686x/tw686x-core.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/media/pci/tw686x/tw686x-core.c b/drivers/media/pci/tw686x/tw686x-core.c index 6676e069b515..384d38754a4b 100644 --- a/drivers/media/pci/tw686x/tw686x-core.c +++ b/drivers/media/pci/tw686x/tw686x-core.c @@ -315,13 +315,6 @@ static int tw686x_probe(struct pci_dev *pci_dev,
spin_lock_init(&dev->lock);
- err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED, - dev->name, dev); - if (err < 0) { - dev_err(&pci_dev->dev, "unable to request interrupt\n"); - goto iounmap; - } - timer_setup(&dev->dma_delay_timer, tw686x_dma_delay, 0);
/* @@ -333,18 +326,23 @@ static int tw686x_probe(struct pci_dev *pci_dev, err = tw686x_video_init(dev); if (err) { dev_err(&pci_dev->dev, "can't register video\n"); - goto free_irq; + goto iounmap; }
err = tw686x_audio_init(dev); if (err) dev_warn(&pci_dev->dev, "can't register audio\n");
+ err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED, + dev->name, dev); + if (err < 0) { + dev_err(&pci_dev->dev, "unable to request interrupt\n"); + goto iounmap; + } + pci_set_drvdata(pci_dev, dev); return 0;
-free_irq: - free_irq(pci_dev->irq, dev); iounmap: pci_iounmap(pci_dev, dev->mmio); free_region:
From: Ming Qian ming.qian@nxp.com
[ Upstream commit a3a2efca36a3a1ddba229a7be7991e8b5de4ac35 ]
return error if format is unsupported by vpu, otherwise the vpu will be stalled at decoding
Fixes: 3cd084519c6f9 ("media: amphion: add vpu v4l2 m2m support") Signed-off-by: Ming Qian ming.qian@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/amphion/vpu_malone.c | 2 ++ drivers/media/platform/amphion/vpu_v4l2.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c index f29c223eefce..40267c73b1f9 100644 --- a/drivers/media/platform/amphion/vpu_malone.c +++ b/drivers/media/platform/amphion/vpu_malone.c @@ -610,6 +610,8 @@ static int vpu_malone_set_params(struct vpu_shared_addr *shared, enum vpu_malone_format malone_format;
malone_format = vpu_malone_format_remap(params->codec_format); + if (WARN_ON(malone_format == MALONE_FMT_NULL)) + return -EINVAL; iface->udata_buffer[instance].base = params->udata.base; iface->udata_buffer[instance].slot_size = params->udata.size;
diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c index 446f07d09d0b..da455e5ab337 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.c +++ b/drivers/media/platform/amphion/vpu_v4l2.c @@ -500,10 +500,12 @@ static int vpu_vb2_start_streaming(struct vb2_queue *q, unsigned int count) fmt->sizeimage[1], fmt->bytesperline[1], fmt->sizeimage[2], fmt->bytesperline[2], q->num_buffers); - call_void_vop(inst, start, q->type); + ret = call_vop(inst, start, q->type); vb2_clear_last_buffer_dequeued(q); + if (ret) + vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_QUEUED);
- return 0; + return ret; }
static void vpu_vb2_stop_streaming(struct vb2_queue *q)
From: Benjamin Gaignard benjamin.gaignard@collabora.com
[ Upstream commit 300065f966d30baa59a13849753305aac8c320c3 ]
Documentation said that g2 init_qp field use bits 24 to 30 of the 8th register. Change the field mask to be able to set 7 bits and not only 6 of them.
Conformance test INITQP_B_Main10_Sony_1 decoding is OK with this patch.
Fixes: cb5dd5a0fa518 ("media: hantro: Introduce G2/HEVC decoder") Signed-off-by: Benjamin Gaignard benjamin.gaignard@collabora.com Reviewed-by: Nicolas Dufresne nicolas.dufresne@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/hantro/hantro_g2_regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/staging/media/hantro/hantro_g2_regs.h index 877d663a8181..82606783591a 100644 --- a/drivers/staging/media/hantro/hantro_g2_regs.h +++ b/drivers/staging/media/hantro/hantro_g2_regs.h @@ -107,7 +107,7 @@
#define g2_start_code_e G2_DEC_REG(10, 31, 0x1) #define g2_init_qp_old G2_DEC_REG(10, 25, 0x3f) -#define g2_init_qp G2_DEC_REG(10, 24, 0x3f) +#define g2_init_qp G2_DEC_REG(10, 24, 0x7f) #define g2_num_tile_cols_old G2_DEC_REG(10, 20, 0x1f) #define g2_num_tile_cols G2_DEC_REG(10, 19, 0x1f) #define g2_num_tile_rows_old G2_DEC_REG(10, 15, 0x1f)
From: Ming Qian ming.qian@nxp.com
[ Upstream commit 5a601f89e846c1b6005ab274d039e5036fc22015 ]
the register CAST_NOMFRSIZE_LO should be equal to CAST_STATUS16 the register CAST_NOMFRSIZE_HI should be equal to CAST_STATUS17 the register CAST_OFBSIZE_LO should be equal to CAST_STATUS18 the register CAST_OFBSIZE_HI should be equal to CAST_STATUS19
Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") Signed-off-by: Ming Qian ming.qian@nxp.com Reviewed-by: Mirela Rabulea mirela.rabulea@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h index d838e875616c..5f64cbbe0fa9 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h @@ -53,10 +53,10 @@ #define CAST_REC_REGS_SEL CAST_STATUS4 #define CAST_LUMTH CAST_STATUS5 #define CAST_CHRTH CAST_STATUS6 -#define CAST_NOMFRSIZE_LO CAST_STATUS7 -#define CAST_NOMFRSIZE_HI CAST_STATUS8 -#define CAST_OFBSIZE_LO CAST_STATUS9 -#define CAST_OFBSIZE_HI CAST_STATUS10 +#define CAST_NOMFRSIZE_LO CAST_STATUS16 +#define CAST_NOMFRSIZE_HI CAST_STATUS17 +#define CAST_OFBSIZE_LO CAST_STATUS18 +#define CAST_OFBSIZE_HI CAST_STATUS19
#define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/ /* JPEG-Decoder Wrapper Slot Registers 0..3 */
From: Ming Qian ming.qian@nxp.com
[ Upstream commit 6285cdea19daf764bf00f662a59fc83ef67345cf ]
There is a hardware bug that it will load the first 128 bytes of configuration data twice, it will led to some configure error. so shift the configuration data 128 bytes, and make the first 128 bytes all zero, then hardware will load the 128 zero twice, and ignore them as garbage. then the configuration data can be loaded correctly
Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") Signed-off-by: Ming Qian ming.qian@nxp.com Reviewed-by: Mirela Rabulea mirela.rabulea@nxp.com Reviewed-by: Tommaso Merciai tommaso.merciai@amarulasolutions.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index f36b512bae51..dd264b82d0dd 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -520,6 +520,7 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg, GFP_ATOMIC); if (!cfg_stm) goto err; + memset(cfg_stm, 0, MXC_JPEG_MAX_CFG_STREAM); jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm;
skip_alloc: @@ -755,7 +756,13 @@ static unsigned int mxc_jpeg_setup_cfg_stream(void *cfg_stream_vaddr, u32 fourcc, u16 w, u16 h) { - unsigned int offset = 0; + /* + * There is a hardware issue that first 128 bytes of configuration data + * can't be loaded correctly. + * To avoid this issue, we need to write the configuration from + * an offset which should be no less than 0x80 (128 bytes). + */ + unsigned int offset = 0x80; u8 *cfg = (u8 *)cfg_stream_vaddr; struct mxc_jpeg_sof *sof; struct mxc_jpeg_sos *sos;
From: Ming Qian ming.qian@nxp.com
[ Upstream commit 9e7aa76cdb02923ee23a0ddd48f38bdc3512f92b ]
The hardware can support any image size WxH, with arbitrary W (image width) and H (image height) dimensions.
Align upwards buffer size for both encoder and decoder. and leave the picture resolution unchanged.
For decoder, the risk of memory out of bounds can be avoided. For both encoder and decoder, the driver will lift the limitation of resolution alignment.
For example, the decoder can support jpeg whose resolution is 227x149 the encoder can support nv12 1080P, won't change it to 1920x1072.
Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") Signed-off-by: Ming Qian ming.qian@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 88 ++++++++----------- 1 file changed, 37 insertions(+), 51 deletions(-)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index dd264b82d0dd..9b8451b56657 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -894,8 +894,8 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf, jpeg->slot_data[slot].cfg_stream_size = mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr, q_data->fmt->fourcc, - q_data->w_adjusted, - q_data->h_adjusted); + q_data->w, + q_data->h);
/* chain the config descriptor with the encoding descriptor */ cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; @@ -977,7 +977,7 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx, &q_data_cap->h_adjusted, q_data_cap->h_adjusted, /* adjust up */ MXC_JPEG_MAX_HEIGHT, - q_data_cap->fmt->v_align, + 0, 0);
/* setup bytesperline/sizeimage for capture queue */ @@ -1161,18 +1161,30 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q, { struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q); struct mxc_jpeg_q_data *q_data = NULL; + struct mxc_jpeg_q_data tmp_q; int i;
q_data = mxc_jpeg_get_q_data(ctx, q->type); if (!q_data) return -EINVAL;
+ tmp_q.fmt = q_data->fmt; + tmp_q.w = q_data->w_adjusted; + tmp_q.h = q_data->h_adjusted; + for (i = 0; i < MXC_JPEG_MAX_PLANES; i++) { + tmp_q.bytesperline[i] = q_data->bytesperline[i]; + tmp_q.sizeimage[i] = q_data->sizeimage[i]; + } + mxc_jpeg_sizeimage(&tmp_q); + for (i = 0; i < MXC_JPEG_MAX_PLANES; i++) + tmp_q.sizeimage[i] = max(tmp_q.sizeimage[i], q_data->sizeimage[i]); + /* Handle CREATE_BUFS situation - *nplanes != 0 */ if (*nplanes) { if (*nplanes != q_data->fmt->colplanes) return -EINVAL; for (i = 0; i < *nplanes; i++) { - if (sizes[i] < q_data->sizeimage[i]) + if (sizes[i] < tmp_q.sizeimage[i]) return -EINVAL; } return 0; @@ -1181,7 +1193,7 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q, /* Handle REQBUFS situation */ *nplanes = q_data->fmt->colplanes; for (i = 0; i < *nplanes; i++) - sizes[i] = q_data->sizeimage[i]; + sizes[i] = tmp_q.sizeimage[i];
return 0; } @@ -1381,11 +1393,6 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb) } q_data_out->w = header.frame.width; q_data_out->h = header.frame.height; - if (header.frame.width % 8 != 0 || header.frame.height % 8 != 0) { - dev_err(dev, "JPEG width or height not multiple of 8: %dx%d\n", - header.frame.width, header.frame.height); - return -EINVAL; - } if (header.frame.width > MXC_JPEG_MAX_WIDTH || header.frame.height > MXC_JPEG_MAX_HEIGHT) { dev_err(dev, "JPEG width or height should be <= 8192: %dx%d\n", @@ -1691,22 +1698,17 @@ static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fm pix_mp->num_planes = fmt->colplanes; pix_mp->pixelformat = fmt->fourcc;
- /* - * use MXC_JPEG_H_ALIGN instead of fmt->v_align, for vertical - * alignment, to loosen up the alignment to multiple of 8, - * otherwise NV12-1080p fails as 1080 is not a multiple of 16 - */ + pix_mp->width = w; + pix_mp->height = h; v4l_bound_align_image(&w, - MXC_JPEG_MIN_WIDTH, - w, /* adjust downwards*/ + w, /* adjust upwards*/ + MXC_JPEG_MAX_WIDTH, fmt->h_align, &h, - MXC_JPEG_MIN_HEIGHT, - h, /* adjust downwards*/ - MXC_JPEG_H_ALIGN, + h, /* adjust upwards*/ + MXC_JPEG_MAX_HEIGHT, + 0, 0); - pix_mp->width = w; /* negotiate the width */ - pix_mp->height = h; /* negotiate the height */
/* get user input into the tmp_q */ tmp_q.w = w; @@ -1832,35 +1834,19 @@ static int mxc_jpeg_s_fmt(struct mxc_jpeg_ctx *ctx,
q_data->w_adjusted = q_data->w; q_data->h_adjusted = q_data->h; - if (jpeg->mode == MXC_JPEG_DECODE) { - /* - * align up the resolution for CAST IP, - * but leave the buffer resolution unchanged - */ - v4l_bound_align_image(&q_data->w_adjusted, - q_data->w_adjusted, /* adjust upwards */ - MXC_JPEG_MAX_WIDTH, - q_data->fmt->h_align, - &q_data->h_adjusted, - q_data->h_adjusted, /* adjust upwards */ - MXC_JPEG_MAX_HEIGHT, - q_data->fmt->v_align, - 0); - } else { - /* - * align down the resolution for CAST IP, - * but leave the buffer resolution unchanged - */ - v4l_bound_align_image(&q_data->w_adjusted, - MXC_JPEG_MIN_WIDTH, - q_data->w_adjusted, /* adjust downwards*/ - q_data->fmt->h_align, - &q_data->h_adjusted, - MXC_JPEG_MIN_HEIGHT, - q_data->h_adjusted, /* adjust downwards*/ - q_data->fmt->v_align, - 0); - } + /* + * align up the resolution for CAST IP, + * but leave the buffer resolution unchanged + */ + v4l_bound_align_image(&q_data->w_adjusted, + q_data->w_adjusted, /* adjust upwards */ + MXC_JPEG_MAX_WIDTH, + q_data->fmt->h_align, + &q_data->h_adjusted, + q_data->h_adjusted, /* adjust upwards */ + MXC_JPEG_MAX_HEIGHT, + q_data->fmt->v_align, + 0);
for (i = 0; i < pix_mp->num_planes; i++) { q_data->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
From: Ming Qian ming.qian@nxp.com
[ Upstream commit 4911c5acf9351c4caf692895c7cf6a4fa46c26b0 ]
v4l2 m2m has supplied some helper function to handle drain, so the driver can use the helper function directly.
Fixes: d8ebe298d008c ("media: imx-jpeg: Set V4L2_BUF_FLAG_LAST at eos") Signed-off-by: Ming Qian ming.qian@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 155 +++++++++--------- .../media/platform/nxp/imx-jpeg/mxc-jpeg.h | 2 - 2 files changed, 73 insertions(+), 84 deletions(-)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index 9b8451b56657..9a2fb0dc77a4 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -559,6 +559,18 @@ static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg, jpeg->slot_data[slot].used = false; }
+static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx, + struct vb2_v4l2_buffer *src_buf, + struct vb2_v4l2_buffer *dst_buf) +{ + if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) { + dst_buf->flags |= V4L2_BUF_FLAG_LAST; + v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx); + notify_eos(ctx); + ctx->header_parsed = false; + } +} + static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) { struct mxc_jpeg_dev *jpeg = priv; @@ -633,6 +645,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) dev_dbg(dev, "Decoder DHT cfg finished. Start decoding...\n"); goto job_unlock; } + if (jpeg->mode == MXC_JPEG_ENCODE) { payload = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR)); vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload); @@ -661,6 +674,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
buffers_done: jpeg->slot_data[slot].used = false; /* unused, but don't free */ + mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf); v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_buf_done(src_buf, buf_state); @@ -1034,6 +1048,7 @@ static void mxc_jpeg_device_run(void *priv) jpeg_src_buf->jpeg_parse_error = true; } if (jpeg_src_buf->jpeg_parse_error) { + mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf); v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); @@ -1084,45 +1099,33 @@ static void mxc_jpeg_device_run(void *priv) spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); }
-static void mxc_jpeg_set_last_buffer_dequeued(struct mxc_jpeg_ctx *ctx) -{ - struct vb2_queue *q; - - ctx->stopped = 1; - q = v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx); - if (!list_empty(&q->done_list)) - return; - - q->last_buffer_dequeued = true; - wake_up(&q->done_wq); - ctx->stopped = 0; - ctx->header_parsed = false; -} - static int mxc_jpeg_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd) { struct v4l2_fh *fh = file->private_data; struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh); - struct device *dev = ctx->mxc_jpeg->dev; int ret;
ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd); if (ret < 0) return ret;
- if (cmd->cmd == V4L2_DEC_CMD_STOP) { - dev_dbg(dev, "Received V4L2_DEC_CMD_STOP"); - if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) { - /* No more src bufs, notify app EOS */ - notify_eos(ctx); - mxc_jpeg_set_last_buffer_dequeued(ctx); - } else { - /* will send EOS later*/ - ctx->stopping = 1; - } + if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx))) + return 0; + + ret = v4l2_m2m_ioctl_decoder_cmd(file, priv, cmd); + if (ret < 0) + return ret; + + if (cmd->cmd == V4L2_DEC_CMD_STOP && + v4l2_m2m_has_stopped(fh->m2m_ctx)) { + notify_eos(ctx); + ctx->header_parsed = false; }
+ if (cmd->cmd == V4L2_DEC_CMD_START && + v4l2_m2m_has_stopped(fh->m2m_ctx)) + vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q); return 0; }
@@ -1131,24 +1134,27 @@ static int mxc_jpeg_encoder_cmd(struct file *file, void *priv, { struct v4l2_fh *fh = file->private_data; struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh); - struct device *dev = ctx->mxc_jpeg->dev; int ret;
ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd); if (ret < 0) return ret;
- if (cmd->cmd == V4L2_ENC_CMD_STOP) { - dev_dbg(dev, "Received V4L2_ENC_CMD_STOP"); - if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) { - /* No more src bufs, notify app EOS */ - notify_eos(ctx); - mxc_jpeg_set_last_buffer_dequeued(ctx); - } else { - /* will send EOS later*/ - ctx->stopping = 1; - } - } + if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)) || + !vb2_is_streaming(v4l2_m2m_get_dst_vq(fh->m2m_ctx))) + return 0; + + ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, cmd); + if (ret < 0) + return 0; + + if (cmd->cmd == V4L2_ENC_CMD_STOP && + v4l2_m2m_has_stopped(fh->m2m_ctx)) + notify_eos(ctx); + + if (cmd->cmd == V4L2_ENC_CMD_START && + v4l2_m2m_has_stopped(fh->m2m_ctx)) + vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q);
return 0; } @@ -1204,6 +1210,8 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type); int ret;
+ v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q); + if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type)) ctx->source_change = 0; dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx); @@ -1235,11 +1243,15 @@ static void mxc_jpeg_stop_streaming(struct vb2_queue *q) break; v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); } - pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev); - if (V4L2_TYPE_IS_OUTPUT(q->type)) { - ctx->stopping = 0; - ctx->stopped = 0; + + v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q); + if (V4L2_TYPE_IS_OUTPUT(q->type) && + v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) { + notify_eos(ctx); + ctx->header_parsed = false; } + + pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev); }
static int mxc_jpeg_valid_comp_id(struct device *dev, @@ -1438,6 +1450,20 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb) struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct mxc_jpeg_src_buf *jpeg_src_buf;
+ if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && + vb2_is_streaming(vb->vb2_queue) && + v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) { + struct mxc_jpeg_q_data *q_data; + + q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type); + vbuf->field = V4L2_FIELD_NONE; + vbuf->sequence = q_data->sequence++; + v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf); + notify_eos(ctx); + ctx->header_parsed = false; + return; + } + if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) goto end;
@@ -1486,24 +1512,11 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb) return -EINVAL; } } - return 0; -} - -static void mxc_jpeg_buf_finish(struct vb2_buffer *vb) -{ - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); - struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - struct vb2_queue *q = vb->vb2_queue; - - if (V4L2_TYPE_IS_OUTPUT(vb->type)) - return; - if (!ctx->stopped) - return; - if (list_empty(&q->done_list)) { - vbuf->flags |= V4L2_BUF_FLAG_LAST; - ctx->stopped = 0; - ctx->header_parsed = false; + if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) { + vb2_set_plane_payload(vb, 0, 0); + vb2_set_plane_payload(vb, 1, 0); } + return 0; }
static const struct vb2_ops mxc_jpeg_qops = { @@ -1512,7 +1525,6 @@ static const struct vb2_ops mxc_jpeg_qops = { .wait_finish = vb2_ops_wait_finish, .buf_out_validate = mxc_jpeg_buf_out_validate, .buf_prepare = mxc_jpeg_buf_prepare, - .buf_finish = mxc_jpeg_buf_finish, .start_streaming = mxc_jpeg_start_streaming, .stop_streaming = mxc_jpeg_stop_streaming, .buf_queue = mxc_jpeg_buf_queue, @@ -1956,27 +1968,6 @@ static int mxc_jpeg_subscribe_event(struct v4l2_fh *fh, } }
-static int mxc_jpeg_dqbuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct v4l2_fh *fh = file->private_data; - struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv); - struct device *dev = ctx->mxc_jpeg->dev; - int num_src_ready = v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx); - int ret; - - dev_dbg(dev, "DQBUF type=%d, index=%d", buf->type, buf->index); - if (ctx->stopping == 1 && num_src_ready == 0) { - /* No more src bufs, notify app EOS */ - notify_eos(ctx); - ctx->stopping = 0; - mxc_jpeg_set_last_buffer_dequeued(ctx); - } - - ret = v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf); - return ret; -} - static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = { .vidioc_querycap = mxc_jpeg_querycap, .vidioc_enum_fmt_vid_cap = mxc_jpeg_enum_fmt_vid_cap, @@ -2000,7 +1991,7 @@ static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = { .vidioc_encoder_cmd = mxc_jpeg_encoder_cmd,
.vidioc_qbuf = v4l2_m2m_ioctl_qbuf, - .vidioc_dqbuf = mxc_jpeg_dqbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
.vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h index 760eaf5387a1..1d41cb8ffb6c 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h @@ -92,8 +92,6 @@ struct mxc_jpeg_ctx { struct mxc_jpeg_q_data cap_q; struct v4l2_fh fh; enum mxc_jpeg_enc_state enc_state; - unsigned int stopping; - unsigned int stopped; unsigned int slot; unsigned int source_change; bool header_parsed;
From: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se
[ Upstream commit 5b9b598453d3ae5fa66d7ab591008373a89b91a0 ]
When converting to full Virtual Channel routing an error crept into the routing table for Ebisu (r8a77990). The routing information is used at probe time preventing rcar-vin from probing correctly on this SoC, solve by correcting the routing table.
Fixes: 3e52419ec04f9769 ("media: rcar-{csi2,vin}: Move to full Virtual Channel routing per CSI-2 IP") Reported-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se Tested-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/renesas/rcar-vin/rcar-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-core.c b/drivers/media/platform/renesas/rcar-vin/rcar-core.c index 49bdcfba010b..4b7a9743554a 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-core.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-core.c @@ -1261,7 +1261,7 @@ static const struct rvin_info rcar_info_r8a77980 = { };
static const struct rvin_group_route rcar_info_r8a77990_routes[] = { - { .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 }, + { .master = 4, .csi = RVIN_CSI40, .chsel = 0x03 }, { /* Sentinel */ } };
From: Pavel Skripkin paskripkin@gmail.com
[ Upstream commit 0ac4827f78c7ffe8eef074bc010e7e34bc22f533 ]
Syzbot reported use-after-free Read in ath9k_hif_usb_rx_cb() [0]. The problem was in incorrect htc_handle->drv_priv initialization.
Probable call trace which can trigger use-after-free:
ath9k_htc_probe_device() /* htc_handle->drv_priv = priv; */ ath9k_htc_wait_for_target() <--- Failed ieee80211_free_hw() <--- priv pointer is freed
<IRQ> ... ath9k_hif_usb_rx_cb() ath9k_hif_usb_rx_stream() RX_STAT_INC() <--- htc_handle->drv_priv access
In order to not add fancy protection for drv_priv we can move htc_handle->drv_priv initialization at the end of the ath9k_htc_probe_device() and add helper macro to make all *_STAT_* macros NULL safe, since syzbot has reported related NULL deref in that macros [1]
Link: https://syzkaller.appspot.com/bug?id=6ead44e37afb6866ac0c7dd121b4ce07cb665f6... [0] Link: https://syzkaller.appspot.com/bug?id=b8101ffcec107c0567a0cd8acbbacec91e9ee8d... [1] Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.") Reported-and-tested-by: syzbot+03110230a11411024147@syzkaller.appspotmail.com Reported-and-tested-by: syzbot+c6dde1f690b60e0b9fbe@syzkaller.appspotmail.com Signed-off-by: Pavel Skripkin paskripkin@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/d57bbedc857950659bfacac0ab48790c1eda00c8.165514574... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/htc.h | 10 +++++----- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 6b45e63fae4b..e3d546ef71dd 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -327,11 +327,11 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) }
#ifdef CONFIG_ATH9K_HTC_DEBUGFS - -#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) -#define TX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a) -#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++) -#define RX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a) +#define __STAT_SAFE(expr) (hif_dev->htc_handle->drv_priv ? (expr) : 0) +#define TX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) +#define TX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a) +#define RX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++) +#define RX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a) #define CAB_STAT_INC priv->debug.tx_stats.cab_queued++
#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index ff61ae34ecdf..07ac88fb1c57 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -944,7 +944,6 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, priv->hw = hw; priv->htc = htc_handle; priv->dev = dev; - htc_handle->drv_priv = priv; SET_IEEE80211_DEV(hw, priv->dev);
ret = ath9k_htc_wait_for_target(priv); @@ -965,6 +964,8 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, if (ret) goto err_init;
+ htc_handle->drv_priv = priv; + return 0;
err_init:
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 630c7e4621763220d23789fbb036e0cf227e0b22 ]
We should set the STA deflink addresses in case no link is really added.
Fixes: 046d2e7c50e3 ("mac80211: prepare sta handling for MLO support") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/sta_info.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index e04a0905e941..8b192cf7d446 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -373,6 +373,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
memcpy(sta->addr, addr, ETH_ALEN); memcpy(sta->sta.addr, addr, ETH_ALEN); + memcpy(sta->deflink.addr, addr, ETH_ALEN); + memcpy(sta->sta.deflink.addr, addr, ETH_ALEN); sta->sta.max_rx_aggregation_subframes = local->hw.max_rx_aggregation_subframes;
From: Alexey Kodanev aleksei.kodanev@bell-sw.com
[ Upstream commit a8eb8e6f7159c7c20c0ddac428bde3d110890aa7 ]
As a result of the execution of the inner while loop, the value of 'idx' can be equal to LINK_QUAL_MAX_RETRY_NUM. However, this is not checked after the loop and 'idx' is used to write the LINK_QUAL_MAX_RETRY_NUM size array 'lq_cmd->rs_table[idx]' below in the outer loop.
The fix is to check the new value of 'idx' inside the nested loop, and break both loops if index equals the size. Checking it at the start is now pointless, so let's remove it.
Detected using the static analysis tool - Svace.
Fixes: be663ab67077 ("iwlwifi: split the drivers for agn and legacy devices 3945/4965") Signed-off-by: Alexey Kodanev aleksei.kodanev@bell-sw.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220608171614.28891-1-aleksei.kodanev@bell-sw.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlegacy/4965-rs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlegacy/4965-rs.c b/drivers/net/wireless/intel/iwlegacy/4965-rs.c index 9dd2d890e35f..c62f299b9e0a 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-rs.c @@ -2403,7 +2403,7 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta, /* Repeat initial/next rate. * For legacy IL_NUMBER_TRY == 1, this loop will not execute. * For HT IL_HT_NUMBER_TRY == 3, this executes twice. */ - while (repeat_rate > 0 && idx < LINK_QUAL_MAX_RETRY_NUM) { + while (repeat_rate > 0) { if (is_legacy(tbl_type.lq_type)) { if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) ant_toggle_cnt++; @@ -2422,6 +2422,8 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta, cpu_to_le32(new_rate); repeat_rate--; idx++; + if (idx >= LINK_QUAL_MAX_RETRY_NUM) + goto out; }
il4965_rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, @@ -2466,6 +2468,7 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta, repeat_rate--; }
+out: lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
From: Ping-Ke Shih pkshih@realtek.com
[ Upstream commit 683a4647a7a3044868cfdc14c117525091b9fa0c ]
The DPK is a kind of RF calibration whose algorithm is to fine tune parameters and calibrate, and check the result. If the result isn't good enough, it could adjust parameters and try again.
This issue is to read and show the result, but it could be a negative calibration result that causes divisor 0 and core dump. So, fix it by phy_div() that does division only if divisor isn't zero; otherwise, zero is adopted.
divide error: 0000 [#1] PREEMPT SMP NOPTI CPU: 1 PID: 728 Comm: wpa_supplicant Not tainted 5.10.114-16019-g462a1661811a #1 <HASH:d024 28> RIP: 0010:rtw8852a_dpk+0x14ae/0x288f [rtw89_core] RSP: 0018:ffffa9bb412a7520 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 00000000000180fc RDI: ffffa141d01023c0 RBP: ffffa9bb412a76a0 R08: 0000000000001319 R09: 00000000ffffff92 R10: ffffffffc0292de3 R11: ffffffffc00d2f51 R12: 0000000000000000 R13: ffffa141d01023c0 R14: ffffffffc0290250 R15: ffffa141d0102638 FS: 00007fa99f5c2740(0000) GS:ffffa142e5e80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000013e8e010 CR3: 0000000110d2c000 CR4: 0000000000750ee0 PKRU: 55555554 Call Trace: rtw89_core_sta_add+0x95/0x9c [rtw89_core <HASH:d239 29>] rtw89_ops_sta_state+0x5d/0x108 [rtw89_core <HASH:d239 29>] drv_sta_state+0x115/0x66f [mac80211 <HASH:81fe 30>] sta_info_insert_rcu+0x45c/0x713 [mac80211 <HASH:81fe 30>] sta_info_insert+0xf/0x1b [mac80211 <HASH:81fe 30>] ieee80211_prep_connection+0x9d6/0xb0c [mac80211 <HASH:81fe 30>] ieee80211_mgd_auth+0x2aa/0x352 [mac80211 <HASH:81fe 30>] cfg80211_mlme_auth+0x160/0x1f6 [cfg80211 <HASH:00cd 31>] nl80211_authenticate+0x2e5/0x306 [cfg80211 <HASH:00cd 31>] genl_rcv_msg+0x371/0x3a1 ? nl80211_stop_sched_scan+0xe5/0xe5 [cfg80211 <HASH:00cd 31>] ? genl_rcv+0x36/0x36 netlink_rcv_skb+0x8a/0xf9 genl_rcv+0x28/0x36 netlink_unicast+0x27b/0x3a0 netlink_sendmsg+0x2aa/0x469 sock_sendmsg_nosec+0x49/0x4d ____sys_sendmsg+0xe5/0x213 __sys_sendmsg+0xec/0x157 ? syscall_enter_from_user_mode+0xd7/0x116 do_syscall_64+0x43/0x55 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7fa99f6e689b
Fixes: e3ec7017f6a2 ("rtw89: add Realtek 802.11ax driver") Signed-off-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220613065144.15647-1-pkshih@realtek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c index e3c2fce32651..3d60feb78312 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c @@ -2330,8 +2330,8 @@ static u8 _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) val2_q = abs(sign_extend32(val2_q, 11));
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", - (val1_i * val1_i + val1_q * val1_q) / - (val2_i * val2_i + val2_q * val2_q)); + phy_div(val1_i * val1_i + val1_q * val1_q, + val2_i * val2_i + val2_q * val2_q));
} else { for (i = 0; i < 32; i++) {
From: Alex Deucher alexander.deucher@amd.com
[ Upstream commit 1f43b8903f3aae4a26a603c36f6d5dd25d6edb51 ]
radeon is MIT. This were incorrectly changed in commit b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to files with no license") and commit d198b34f3855 (".gitignore: add SPDX License Identifier") and: commit ec8f24b7faaf ("treewide: Add SPDX license identifier - Makefile/Kconfig")
Fixes: d198b34f3855 (".gitignore: add SPDX License Identifier") Fixes: ec8f24b7faaf ("treewide: Add SPDX license identifier - Makefile/Kconfig") Fixes: b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to files with no license") Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2053 Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/radeon/.gitignore | 2 +- drivers/gpu/drm/radeon/Kconfig | 2 +- drivers/gpu/drm/radeon/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/radeon/.gitignore b/drivers/gpu/drm/radeon/.gitignore index 9c1a94153983..d8777383a64a 100644 --- a/drivers/gpu/drm/radeon/.gitignore +++ b/drivers/gpu/drm/radeon/.gitignore @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0-only +# SPDX-License-Identifier: MIT mkregtable *_reg_safe.h
diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig index 6f60f4840cc5..52819e7f1fca 100644 --- a/drivers/gpu/drm/radeon/Kconfig +++ b/drivers/gpu/drm/radeon/Kconfig @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0-only +# SPDX-License-Identifier: MIT config DRM_RADEON_USERPTR bool "Always enable userptr support" depends on DRM_RADEON diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index ea5380e24c3c..e3ab3aca1396 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0 +# SPDX-License-Identifier: MIT # # Makefile for the drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 1320d6c7b0deb7219701a55397e93e6c73d00366 ]
Some APUs with SMU13 are showing the following message: `amdgpu 0000:63:00.0: amdgpu: Unexpected and unhandled version: 3.1`
This warning isn't relevant for smu info 3.1, as no bootup information is present in the table.
Fixes: 593a54f18031 ("drm/amd/pm: correct the way for retrieving bootup clocks") Signed-off-by: Mario Limonciello mario.limonciello@amd.com Reviewed-by: Evan Quan evan.quan@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index ef9b56de143b..5aa08c031f72 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -714,6 +714,8 @@ int smu_v13_0_get_vbios_bootup_values(struct smu_context *smu) smu->smu_table.boot_values.vclk = smu_info_v3_6->bootup_vclk_10khz; smu->smu_table.boot_values.dclk = smu_info_v3_6->bootup_dclk_10khz; smu->smu_table.boot_values.fclk = smu_info_v3_6->bootup_fclk_10khz; + } else if ((frev == 3) && (crev == 1)) { + return 0; } else if ((frev == 4) && (crev == 0)) { smu_info_v4_0 = (struct atom_smu_info_v4_0 *)header;
From: Yifan Zhang yifan1.zhang@amd.com
[ Upstream commit efb4fd107cfd9748f777a4e9015d803d3c9db68b ]
sdma 6.0.1 has 8 queues instead of 2.
Fixes: 26776a7031c423 ("drm/amdkfd: add GC 11.0.1 KFD support") Signed-off-by: Yifan Zhang yifan1.zhang@amd.com Acked-by: Alex Deucher alexander.deucher@amd.com Reviewed-by: Tim Huang Tim.Huang@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_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index a08769c5e94b..d9f57a20a8bc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -75,7 +75,6 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd) case IP_VERSION(5, 2, 3):/* YELLOW_CARP */ case IP_VERSION(5, 2, 6):/* GC 10.3.6 */ case IP_VERSION(5, 2, 7):/* GC 10.3.7 */ - case IP_VERSION(6, 0, 1): kfd->device_info.num_sdma_queues_per_engine = 2; break; case IP_VERSION(4, 2, 0):/* VEGA20 */ @@ -90,6 +89,7 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd) case IP_VERSION(5, 2, 4):/* DIMGREY_CAVEFISH */ case IP_VERSION(5, 2, 5):/* BEIGE_GOBY */ case IP_VERSION(6, 0, 0): + case IP_VERSION(6, 0, 1): case IP_VERSION(6, 0, 2): kfd->device_info.num_sdma_queues_per_engine = 8; break;
From: Paul E. McKenney paulmck@kernel.org
[ Upstream commit 5c92d7501699a5deb72a579f808500db5bb6f92a ]
A recent change to the DEBUG_INFO Kconfig option means that simply adding CONFIG_DEBUG_INFO=y to the .config file and running "make oldconfig" no longer works. It is instead necessary to add CONFIG_DEBUG_INFO_NONE=n and (for example) CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y. This combination will then result in CONFIG_DEBUG_INFO being selected.
This commit therefore updates the Kconfig options produced in response to the kvm.sh --gdb, --kasan, and --kcsan Kconfig options.
Fixes: f9b3cd245784 ("Kconfig.debug: make DEBUG_INFO selectable from a choice") Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/rcutorture/bin/kvm.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh index 263e16aeca0e..6c734818a875 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm.sh @@ -164,7 +164,7 @@ do shift ;; --gdb) - TORTURE_KCONFIG_GDB_ARG="CONFIG_DEBUG_INFO=y"; export TORTURE_KCONFIG_GDB_ARG + TORTURE_KCONFIG_GDB_ARG="CONFIG_DEBUG_INFO_NONE=n CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y"; export TORTURE_KCONFIG_GDB_ARG TORTURE_BOOT_GDB_ARG="nokaslr"; export TORTURE_BOOT_GDB_ARG TORTURE_QEMU_GDB_ARG="-s -S"; export TORTURE_QEMU_GDB_ARG ;; @@ -180,7 +180,7 @@ do shift ;; --kasan) - TORTURE_KCONFIG_KASAN_ARG="CONFIG_DEBUG_INFO=y CONFIG_KASAN=y"; export TORTURE_KCONFIG_KASAN_ARG + TORTURE_KCONFIG_KASAN_ARG="CONFIG_DEBUG_INFO_NONE=n CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_KASAN=y"; export TORTURE_KCONFIG_KASAN_ARG if test -n "$torture_qemu_mem_default" then TORTURE_QEMU_MEM=2G @@ -192,7 +192,7 @@ do shift ;; --kcsan) - TORTURE_KCONFIG_KCSAN_ARG="CONFIG_DEBUG_INFO=y CONFIG_KCSAN=y CONFIG_KCSAN_STRICT=y CONFIG_KCSAN_REPORT_ONCE_IN_MS=100000 CONFIG_KCSAN_VERBOSE=y CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_PROVE_LOCKING=y"; export TORTURE_KCONFIG_KCSAN_ARG + TORTURE_KCONFIG_KCSAN_ARG="CONFIG_DEBUG_INFO_NONE=n CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_KCSAN=y CONFIG_KCSAN_STRICT=y CONFIG_KCSAN_REPORT_ONCE_IN_MS=100000 CONFIG_KCSAN_VERBOSE=y CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_PROVE_LOCKING=y"; export TORTURE_KCONFIG_KCSAN_ARG ;; --kmake-arg|--kmake-args) checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$'
From: Frederic Weisbecker frederic@kernel.org
[ Upstream commit 3002153a91a9732a6d1d0bb95138593c7da15743 ]
The RCU priority boosting can fail in two situations:
1) If (nr_cpus= > maxcpus=), which means if the total number of CPUs is higher than those brought online at boot, then torture_onoff() may later bring up CPUs that weren't online on boot. Now since rcutorture initialization only boosts the ksoftirqds of the CPUs that have been set online on boot, the CPUs later set online by torture_onoff won't benefit from the boost, making RCU priority boosting fail.
2) The ksoftirqd kthreads are boosted after the creation of rcu_torture_boost() kthreads, which opens a window large enough for these rcu_torture_boost() kthreads to wait (despite running at FIFO priority) for ksoftirqds that are still running at SCHED_NORMAL priority.
The issues can trigger for example with:
./kvm.sh --configs TREE01 --kconfig "CONFIG_RCU_BOOST=y"
[ 34.968561] rcu-torture: !!! [ 34.968627] ------------[ cut here ]------------ [ 35.014054] WARNING: CPU: 4 PID: 114 at kernel/rcu/rcutorture.c:1979 rcu_torture_stats_print+0x5ad/0x610 [ 35.052043] Modules linked in: [ 35.069138] CPU: 4 PID: 114 Comm: rcu_torture_sta Not tainted 5.18.0-rc1 #1 [ 35.096424] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.14.0-0-g155821a-rebuilt.opensuse.org 04/01/2014 [ 35.154570] RIP: 0010:rcu_torture_stats_print+0x5ad/0x610 [ 35.198527] Code: 63 1b 02 00 74 02 0f 0b 48 83 3d 35 63 1b 02 00 74 02 0f 0b 48 83 3d 21 63 1b 02 00 74 02 0f 0b 48 83 3d 0d 63 1b 02 00 74 02 <0f> 0b 83 eb 01 0f 8e ba fc ff ff 0f 0b e9 b3 fc ff f82 [ 37.251049] RSP: 0000:ffffa92a0050bdf8 EFLAGS: 00010202 [ 37.277320] rcu: De-offloading 8 [ 37.290367] RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000001 [ 37.290387] RDX: 0000000000000000 RSI: 00000000ffffbfff RDI: 00000000ffffffff [ 37.290398] RBP: 000000000000007b R08: 0000000000000000 R09: c0000000ffffbfff [ 37.290407] R10: 000000000000002a R11: ffffa92a0050bc18 R12: ffffa92a0050be20 [ 37.290417] R13: ffffa92a0050be78 R14: 0000000000000000 R15: 000000000001bea0 [ 37.290427] FS: 0000000000000000(0000) GS:ffff96045eb00000(0000) knlGS:0000000000000000 [ 37.290448] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 37.290460] CR2: 0000000000000000 CR3: 000000001dc0c000 CR4: 00000000000006e0 [ 37.290470] Call Trace: [ 37.295049] <TASK> [ 37.295065] ? preempt_count_add+0x63/0x90 [ 37.295095] ? _raw_spin_lock_irqsave+0x12/0x40 [ 37.295125] ? rcu_torture_stats_print+0x610/0x610 [ 37.295143] rcu_torture_stats+0x29/0x70 [ 37.295160] kthread+0xe3/0x110 [ 37.295176] ? kthread_complete_and_exit+0x20/0x20 [ 37.295193] ret_from_fork+0x22/0x30 [ 37.295218] </TASK>
Fix this with boosting the ksoftirqds kthreads from the boosting hotplug callback itself and before the boosting kthreads are created.
Fixes: ea6d962e80b6 ("rcutorture: Judge RCU priority boosting on grace periods, not callbacks") Signed-off-by: Frederic Weisbecker frederic@kernel.org Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcutorture.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 7120165a9342..7c72ee97455f 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -2075,6 +2075,19 @@ static int rcutorture_booster_init(unsigned int cpu) if (boost_tasks[cpu] != NULL) return 0; /* Already created, nothing more to do. */
+ // Testing RCU priority boosting requires rcutorture do + // some serious abuse. Counter this by running ksoftirqd + // at higher priority. + if (IS_BUILTIN(CONFIG_RCU_TORTURE_TEST)) { + struct sched_param sp; + struct task_struct *t; + + t = per_cpu(ksoftirqd, cpu); + WARN_ON_ONCE(!t); + sp.sched_priority = 2; + sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); + } + /* Don't allow time recalculation while creating a new task. */ mutex_lock(&boost_mutex); rcu_torture_disable_rt_throttle(); @@ -3329,21 +3342,6 @@ rcu_torture_init(void) rcutor_hp = firsterr; if (torture_init_error(firsterr)) goto unwind; - - // Testing RCU priority boosting requires rcutorture do - // some serious abuse. Counter this by running ksoftirqd - // at higher priority. - if (IS_BUILTIN(CONFIG_RCU_TORTURE_TEST)) { - for_each_online_cpu(cpu) { - struct sched_param sp; - struct task_struct *t; - - t = per_cpu(ksoftirqd, cpu); - WARN_ON_ONCE(!t); - sp.sched_priority = 2; - sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); - } - } } shutdown_jiffies = jiffies + shutdown_secs * HZ; firsterr = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup);
From: Jian Shen shenjian15@huawei.com
[ Upstream commit 9676feccacdb0571791c88b23e3b7ac4e7c9c457 ]
The prototype of .features is netdev_features_t, it should use NETIF_F_LLTX and NETIF_F_HW_VLAN_STAG_TX, not NETIF_F_LLTX_BIT and NETIF_F_HW_VLAN_STAG_TX_BIT.
Fixes: cf204a718357 ("bpf, testing: Introduce 'gso_linear_no_head_frag' skb_segment test") Signed-off-by: Jian Shen shenjian15@huawei.com Acked-by: John Fastabend john.fastabend@gmail.com Link: https://lore.kernel.org/r/20220622135002.8263-1-shenjian15@huawei.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/test_bpf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/test_bpf.c b/lib/test_bpf.c index 2a7836e115b4..5820704165a6 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -14733,9 +14733,9 @@ static struct skb_segment_test skb_segment_tests[] __initconst = { .build_skb = build_test_skb_linear_no_head_frag, .features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_GSO | - NETIF_F_LLTX_BIT | NETIF_F_GRO | + NETIF_F_LLTX | NETIF_F_GRO | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | - NETIF_F_HW_VLAN_STAG_TX_BIT + NETIF_F_HW_VLAN_STAG_TX } };
From: YueHaibing yuehaibing@huawei.com
[ Upstream commit 876271118aa41097d035c84f99648746b4a125f3 ]
While CONFIG_OF is n but COMPILE_TEST is y, we got this:
WARNING: unmet direct dependencies detected for DRM_DP_AUX_BUS Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && OF [=n] Selected by [y]: - DRM_MSM [=y] && HAS_IOMEM [=y] && DRM [=y] && (ARCH_QCOM || SOC_IMX5 || COMPILE_TEST [=y]) && COMMON_CLK [=y] && IOMMU_SUPPORT [=y] && (QCOM_OCMEM [=n] || QCOM_OCMEM [=n]=n) && (QCOM_LLCC [=y] || QCOM_LLCC [=y]=n) && (QCOM_COMMAND_DB [=n] || QCOM_COMMAND_DB [=n]=n)
Make DRM_DP_AUX_BUS depends on OF || COMPILE_TEST to fix this warning.
Fixes: 1e0f66420b13 ("drm/display: Introduce a DRM display-helper module") Signed-off-by: YueHaibing yuehaibing@huawei.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Acked-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220611041612.1976-1-yuehaibi... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/display/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig index 1b6e6af37546..09712b88a5b8 100644 --- a/drivers/gpu/drm/display/Kconfig +++ b/drivers/gpu/drm/display/Kconfig @@ -3,7 +3,7 @@ config DRM_DP_AUX_BUS tristate depends on DRM - depends on OF + depends on OF || COMPILE_TEST
config DRM_DISPLAY_HELPER tristate
From: Jörn-Thorben Hinz jthinz@mailbox.tu-berlin.de
[ Upstream commit 6dc7a0baf1a70b7d22662d38481824c14ddd80c5 ]
test_sock_fields__detach() got called with a null pointer here when one of the CHECKs or ASSERTs up to the test_sock_fields__open_and_load() call resulted in a jump to the "done" label.
A skeletons *__detach() is not safe to call with a null pointer, though. This led to a segfault.
Go the easy route and only call test_sock_fields__destroy() which is null-pointer safe and includes detaching.
Came across this while looking[1] to introduce the usage of bpf_tcp_helpers.h (included in progs/test_sock_fields.c) together with vmlinux.h.
[1] https://lore.kernel.org/bpf/629bc069dd807d7ac646f836e9dca28bbc1108e2.camel@m...
Fixes: 8f50f16ff39d ("selftests/bpf: Extend verifier and bpf_sock tests for dst_port loads") Signed-off-by: Jörn-Thorben Hinz jthinz@mailbox.tu-berlin.de Signed-off-by: Andrii Nakryiko andrii@kernel.org Reviewed-by: Jakub Sitnicki jakub@cloudflare.com Reviewed-by: Martin KaFai Lau kafai@fb.com Acked-by: John Fastabend john.fastabend@gmail.com Link: https://lore.kernel.org/bpf/20220621070116.307221-1-jthinz@mailbox.tu-berlin... Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/prog_tests/sock_fields.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/sock_fields.c b/tools/testing/selftests/bpf/prog_tests/sock_fields.c index 9d211b5c22c4..7d23166c77af 100644 --- a/tools/testing/selftests/bpf/prog_tests/sock_fields.c +++ b/tools/testing/selftests/bpf/prog_tests/sock_fields.c @@ -394,7 +394,6 @@ void serial_test_sock_fields(void) test();
done: - test_sock_fields__detach(skel); test_sock_fields__destroy(skel); if (child_cg_fd >= 0) close(child_cg_fd);
From: Tom Lendacky thomas.lendacky@amd.com
[ Upstream commit 1b05ece0c931536c0a38a9385e243a7962e933f6 ]
On shutdown, each CCP device instance performs shutdown processing. However, __sev_platform_shutdown_locked() uses the controlling psp structure to obtain the pointer to the sev_device structure. However, during driver initialization, it is possible that an error can be received from the firmware that results in the sev_data pointer being cleared from the controlling psp structure. The __sev_platform_shutdown_locked() function does not check for this situation and will segfault.
While not common, this scenario should be accounted for. Add a check for a NULL sev_device structure before attempting to use it.
Fixes: 5441a07a127f ("crypto: ccp - shutdown SEV firmware on kexec") Signed-off-by: Tom Lendacky thomas.lendacky@amd.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/ccp/sev-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 0c92d940ac4e..9f588c9728f8 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -503,7 +503,7 @@ static int __sev_platform_shutdown_locked(int *error) struct sev_device *sev = psp_master->sev_data; int ret;
- if (sev->state == SEV_STATE_UNINIT) + if (!sev || sev->state == SEV_STATE_UNINIT) return 0;
ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error);
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit 831463667b5f4f1e5bce9c3b94e9e794d2bc8923 ]
As mipi_dsi_driver_register could return error if fails, it should be better to check the return value and return error if fails. Moreover, if i2c_add_driver fails, mipi_dsi_driver_register should be reverted.
Fixes: 1e4d58cd7f88 ("drm/bridge: adv7533: Create a MIPI DSI device") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/20220602103401.2980938-1-jiash... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 074c2e650cae..38bf28720f3a 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1393,10 +1393,21 @@ static struct i2c_driver adv7511_driver = {
static int __init adv7511_init(void) { - if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) - mipi_dsi_driver_register(&adv7533_dsi_driver); + int ret; + + if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) { + ret = mipi_dsi_driver_register(&adv7533_dsi_driver); + if (ret) + return ret; + }
- return i2c_add_driver(&adv7511_driver); + ret = i2c_add_driver(&adv7511_driver); + if (ret) { + if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) + mipi_dsi_driver_unregister(&adv7533_dsi_driver); + } + + return ret; } module_init(adv7511_init);
From: Ming Qian ming.qian@nxp.com
[ Upstream commit 22a2bc88c139dc9757bdb1d0a3665ac27edc79a5 ]
The interrupt STMBUF_HALF may be triggered after frame done. It may led to system hang if driver try to access the register after power off.
Disable the slot interrupt when frame done.
Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") Signed-off-by: Ming Qian ming.qian@nxp.com Reviewed-by: Mirela Rabulea mirela.rabulea@nxp.com Tested-by: Mirela Rabulea mirela.rabulea@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c | 5 +++++ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h | 1 + drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 10 ++-------- 3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c index 29c604b1b179..718b7b08f93e 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c @@ -79,6 +79,11 @@ void mxc_jpeg_enable_irq(void __iomem *reg, int slot) writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN)); }
+void mxc_jpeg_disable_irq(void __iomem *reg, int slot) +{ + writel(0x0, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN)); +} + void mxc_jpeg_sw_reset(void __iomem *reg) { /* diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h index 5f64cbbe0fa9..645a24fe8bc1 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h @@ -125,6 +125,7 @@ u32 mxc_jpeg_get_offset(void __iomem *reg, int slot); void mxc_jpeg_enable_slot(void __iomem *reg, int slot); void mxc_jpeg_set_l_endian(void __iomem *reg, int le); void mxc_jpeg_enable_irq(void __iomem *reg, int slot); +void mxc_jpeg_disable_irq(void __iomem *reg, int slot); int mxc_jpeg_set_input(void __iomem *reg, u32 in_buf, u32 bufsize); int mxc_jpeg_set_output(void __iomem *reg, u16 out_pitch, u32 out_buf, u16 w, u16 h); diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index 9a2fb0dc77a4..35a7cb936653 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -593,15 +593,8 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) dev_dbg(dev, "Irq %d on slot %d.\n", irq, slot);
ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); - if (!ctx) { - dev_err(dev, - "Instance released before the end of transaction.\n"); - /* soft reset only resets internal state, not registers */ - mxc_jpeg_sw_reset(reg); - /* clear all interrupts */ - writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); + if (WARN_ON(!ctx)) goto job_unlock; - }
if (slot != ctx->slot) { /* TODO investigate when adding multi-instance support */ @@ -673,6 +666,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) buf_state = VB2_BUF_STATE_DONE;
buffers_done: + mxc_jpeg_disable_irq(reg, ctx->slot); jpeg->slot_data[slot].used = false; /* unused, but don't free */ mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf); v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
From: Ming Qian ming.qian@nxp.com
[ Upstream commit 89e3f3fb3d9014efa59ed6bb526d5f1a00168452 ]
Firmware may send the error event with some error message, and it help locate the firmware error, so output the error message if it exists
Fixes: 61cbf1c1fa6d7 ("media: amphion: implement vpu core communication based on mailbox") Signed-off-by: Ming Qian ming.qian@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/amphion/vpu_msgs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c index d5850df8f1d5..d8247f36d84b 100644 --- a/drivers/media/platform/amphion/vpu_msgs.c +++ b/drivers/media/platform/amphion/vpu_msgs.c @@ -150,7 +150,12 @@ static void vpu_session_handle_eos(struct vpu_inst *inst, struct vpu_rpc_event *
static void vpu_session_handle_error(struct vpu_inst *inst, struct vpu_rpc_event *pkt) { - dev_err(inst->dev, "unsupported stream\n"); + char *str = (char *)pkt->data; + + if (strlen(str)) + dev_err(inst->dev, "instance %d firmware error : %s\n", inst->id, str); + else + dev_err(inst->dev, "instance %d is unsupported stream\n", inst->id); call_void_vop(inst, event_notify, VPU_MSG_ID_UNSUPPORTED, NULL); vpu_v4l2_set_error(inst); }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 3a149169e4a2f9127022fec6ef5d71b4e804b3b9 ]
Every iteration of for_each_available_child_of_node() decrements the reference counter of the previous node. There is no decrement when break out from the loop and results in refcount leak. Add missing of_node_put() to fix this.
Fixes: 5fc537bfd000 ("drm/mcde: Add new driver for ST-Ericsson MCDE") Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220525115411.65455-1-linmq00... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/mcde/mcde_dsi.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c index 5651734ce977..9f9ac8699310 100644 --- a/drivers/gpu/drm/mcde/mcde_dsi.c +++ b/drivers/gpu/drm/mcde/mcde_dsi.c @@ -1111,6 +1111,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master, bridge = of_drm_find_bridge(child); if (!bridge) { dev_err(dev, "failed to find bridge\n"); + of_node_put(child); return -EINVAL; } }
From: Niels Dossche dossche.niels@gmail.com
[ Upstream commit 359c27c6ddbde404f44a9c0d3ec88ccd1e2042f2 ]
Error return values are supposed to be negative in hdpvr_read. Most error returns are currently handled via an unsigned integer "ret". When setting a negative error value to "ret", the value actually becomes a large positive value, because "ret" is unsigned. Later on, the "ret" value is returned. But as ssize_t is a 64-bit signed number, the error return value stays a large positive integer instead of a negative integer. This can cause an error value to be interpreted as the read size, which can cause a buffer overread for applications relying on the returned size.
Fixes: 9aba42efe85b ("V4L/DVB (11096): V4L2 Driver for the Hauppauge HD PVR usb capture device") Signed-off-by: Niels Dossche dossche.niels@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/hdpvr/hdpvr-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index 60e57e0f1927..fd7d2a9d0449 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c @@ -409,7 +409,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, struct hdpvr_device *dev = video_drvdata(file); struct hdpvr_buffer *buf = NULL; struct urb *urb; - unsigned int ret = 0; + int ret = 0; int rem, cnt;
if (*pos)
From: Ming Qian ming.qian@nxp.com
[ Upstream commit d4de27a9b1eadd33a2e40de87a646d1bf5fef756 ]
If the last buffer was dequeued from the capture queue, signal userspace. DQBUF(CAPTURE) will return -EPIPE.
But if output queue is empty and capture queue is empty, v4l2_m2m_poll_for_data will return EPOLLERR, This is very easy to happen in drain.
When last_buffer_dequeued is set, we shouldn't return EPOLLERR, but return EPOLLIN | EPOLLRDNORM.
Fixes: 1698a7f151126 ("media: v4l2-mem2mem: simplify poll logic") Signed-off-by: Ming Qian ming.qian@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/v4l2-core/v4l2-mem2mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 6469f9a25a4e..837e1855f94b 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -925,7 +925,7 @@ static __poll_t v4l2_m2m_poll_for_data(struct file *file, if ((!src_q->streaming || src_q->error || list_empty(&src_q->queued_list)) && (!dst_q->streaming || dst_q->error || - list_empty(&dst_q->queued_list))) + (list_empty(&dst_q->queued_list) && !dst_q->last_buffer_dequeued))) return EPOLLERR;
spin_lock_irqsave(&src_q->done_lock, flags);
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit a157802359f7451ed8046b2b6dbaca187797e062 ]
This driver does not use the virt_to_bus() function, though it depends on x86 specific fixups in the swiotlb code, which was last rewritten in commit e380a0394c36 ("x86/PCI: sta2x11: use default DMA address translation").
It is possible that the driver still fails to build on some architectures that are missing CONFIG_VIRT_TO_BUS, but it is always set on x86 machines with the STA2X11 platform enabled.
More likely though is that it was never meant to depend on CONFIG_VIRT_TO_BUS, and the Kconfig dependency was kept from an out-of-tree version when the driver was originally merged.
Fixes: efeb98b4e2b2 ("[media] STA2X11 VIP: new V4L2 driver") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/sta2x11/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/pci/sta2x11/Kconfig b/drivers/media/pci/sta2x11/Kconfig index a96e170ab04e..118b922c08c3 100644 --- a/drivers/media/pci/sta2x11/Kconfig +++ b/drivers/media/pci/sta2x11/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only config STA2X11_VIP tristate "STA2X11 VIP Video For Linux" - depends on PCI && VIDEO_DEV && VIRT_TO_BUS && I2C + depends on PCI && VIDEO_DEV && I2C depends on STA2X11 || COMPILE_TEST select GPIOLIB if MEDIA_SUBDRV_AUTOSELECT select VIDEO_ADV7180 if MEDIA_SUBDRV_AUTOSELECT
From: Yunfei Dong yunfei.dong@mediatek.com
[ Upstream commit faddaa735c208560a3f419038e8d154a01b584e3 ]
Need to get dec_capability from scp first, then initialize decoder supported format and other parameters according to dec_capability value.
Fixes: fd00d90330d1 ("media: mtk-vcodec: vdec: move stateful ops into their own file") Signed-off-by: Yunfei Dong yunfei.dong@mediatek.com Reviewed-by: Chen-Yu Tsai wenst@chromium.org Tested-by: Chen-Yu Tsai wenst@chromium.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c | 2 -- drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c index 52e5d36aa912..50cfb18f85ae 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c @@ -112,8 +112,6 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx) { struct mtk_q_data *q_data;
- ctx->dev->vdec_pdata->init_vdec_params(ctx); - ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex; ctx->fh.m2m_ctx = ctx->m2m_ctx; ctx->fh.ctrl_handler = &ctx->ctrl_hdl; diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c index 995e6e2fb1ab..95a53385a61c 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c @@ -208,6 +208,8 @@ static int fops_vcodec_open(struct file *file)
dev->dec_capability = mtk_vcodec_fw_get_vdec_capa(dev->fw_handler); + ctx->dev->vdec_pdata->init_vdec_params(ctx); + mtk_v4l2_debug(0, "decoder capability %x", dev->dec_capability); }
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit e13ca460e20ed42fe57a3845b0bb9a82f81f05cd ]
The stateless decoder API does not specify the usage of SOURCE_CHANGE and EOF events. These events are used by stateful decoders to signal changes in the bitstream. They do not make sense for stateless decoders.
Do not handle subscription for these two types of events for stateless decoder instances. This fixes the last v4l2-compliance error:
Control ioctls: fail: v4l2-test-controls.cpp(946): have_source_change || have_eos test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: FAIL
Fixes: 8cdc3794b2e3 ("media: mtk-vcodec: vdec: support stateless API") Signed-off-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: Nicolas Dufresne nicolas.dufresne@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c index 50cfb18f85ae..01836a1c7d3f 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c @@ -196,6 +196,11 @@ static int vidioc_vdec_querycap(struct file *file, void *priv, static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub) { + struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh); + + if (ctx->dev->vdec_pdata->uses_stateless_api) + return v4l2_ctrl_subscribe_event(fh, sub); + switch (sub->type) { case V4L2_EVENT_EOS: return v4l2_event_subscribe(fh, sub, 2, NULL);
From: Jian Zhang zhangjian210@huawei.com
[ Upstream commit 5b304046a81eda221b5d06a9c62f7b5e45530fa5 ]
In function mxc_jpeg_probe(), when devm_clk_get() fail, the return value will be unexpected, and it should be the devm_clk_get's error code.
Fixes: 4c2e5156d9fa6 ("media: imx-jpeg: Add pm-runtime support for imx-jpeg") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Jian Zhang zhangjian210@huawei.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index 35a7cb936653..b2ea57b45028 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -2145,12 +2145,14 @@ static int mxc_jpeg_probe(struct platform_device *pdev) jpeg->clk_ipg = devm_clk_get(dev, "ipg"); if (IS_ERR(jpeg->clk_ipg)) { dev_err(dev, "failed to get clock: ipg\n"); + ret = PTR_ERR(jpeg->clk_ipg); goto err_clk; }
jpeg->clk_per = devm_clk_get(dev, "per"); if (IS_ERR(jpeg->clk_per)) { dev_err(dev, "failed to get clock: per\n"); + ret = PTR_ERR(jpeg->clk_per); goto err_clk; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit e0b212ec9d8177d6f7c404315293f6a085d6ee42 ]
video_device_alloc() allocates memory for vdev, when video_register_device() fails, it doesn't release the memory and leads to memory leak, call video_device_release() to fix this.
Fixes: 704a84ccdbf1 ("[media] media: Support Intersil/Techwell TW686x-based video capture cards") Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/tw686x/tw686x-video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/media/pci/tw686x/tw686x-video.c b/drivers/media/pci/tw686x/tw686x-video.c index 6344a479119f..3ebf7a2c95f0 100644 --- a/drivers/media/pci/tw686x/tw686x-video.c +++ b/drivers/media/pci/tw686x/tw686x-video.c @@ -1280,8 +1280,10 @@ int tw686x_video_init(struct tw686x_dev *dev) video_set_drvdata(vdev, vc);
err = video_register_device(vdev, VFL_TYPE_VIDEO, -1); - if (err < 0) + if (err < 0) { + video_device_release(vdev); goto error; + } vc->num = vdev->num; }
From: Yunfei Dong yunfei.dong@mediatek.com
[ Upstream commit 083f54a7c9c66496b9d9f3c50dfdca24e6aa7012 ]
According to subdev_bitmap bit value to open hardware power, need to set subdev_bitmap value for non subdev architecture.
Fixes: c05bada35f01 ("media: mtk-vcodec: Add to support multi hardware decode") Signed-off-by: Yunfei Dong yunfei.dong@mediatek.com Reviewed-by: Chen-Yu Tsai wenst@chromium.org Tested-by: Chen-Yu Tsai wenst@chromium.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c index 95a53385a61c..99d7b15f2b9d 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c @@ -388,6 +388,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev) mtk_v4l2_err("Main device of_platform_populate failed."); goto err_reg_cont; } + } else { + set_bit(MTK_VDEC_CORE, dev->subdev_bitmap); }
ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, -1);
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit 1701a23a4ef0993964ccc2f2d5d13f83a5ff4c70 ]
The core clock computation takes into account both the load due to the input (ie, planes) and its output (ie, encoders).
However, while the input load needs to consider all the planes, and thus sum all of their associated loads, the output happens mostly in parallel.
Therefore, we need to consider only the maximum of all the output loads, and not the sum like we were doing. This resulted in a clock rate way too high which could be discarded for being too high by the clock framework.
Since recent changes, the clock framework will even downright reject it, leading to a core clock being too low for its current needs.
Fixes: 16e101051f32 ("drm/vc4: Increase the core clock based on HVS load") Signed-off-by: Maxime Ripard maxime@cerno.tech Reviewed-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-4-maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_kms.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index 893d831b24aa..b7353d4c0811 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -950,7 +950,9 @@ vc4_core_clock_atomic_check(struct drm_atomic_state *state) continue;
num_outputs++; - cob_rate += hvs_new_state->fifo_state[i].fifo_load; + cob_rate = max_t(unsigned long, + hvs_new_state->fifo_state[i].fifo_load, + cob_rate); }
pixel_rate = load_state->hvs_load;
From: Dom Cobley popcornmix@gmail.com
[ Upstream commit 517db1ab1566dba3093dbdb8de4263ba4aa66416 ]
There is little harm in ignoring fractional coordinates (they just get truncated).
Without this: modetest -M vc4 -F tiles,gradient -s 32:1920x1080-60 -P89@74:1920x1080*.1.1@XR24
is rejected. We have the same issue in Kodi when trying to use zoom options on video.
Note: even if all coordinates are fully integer. e.g. src:[0,0,1920,1080] dest:[-10,-10,1940,1100]
it will still get rejected as drm_atomic_helper_check_plane_state uses drm_rect_clip_scaled which transforms this to fractional src coords
Fixes: 21af94cf1a4c ("drm/vc4: Add support for scaling of display planes.") Signed-off-by: Dom Cobley popcornmix@gmail.com Link: https://lore.kernel.org/r/20220613144800.326124-5-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_plane.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 1e866dc00ac3..67402da89213 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -339,7 +339,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); struct drm_framebuffer *fb = state->fb; struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); - u32 subpixel_src_mask = (1 << 16) - 1; int num_planes = fb->format->num_planes; struct drm_crtc_state *crtc_state; u32 h_subsample = fb->format->hsub; @@ -361,18 +360,15 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) for (i = 0; i < num_planes; i++) vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
- /* We don't support subpixel source positioning for scaling. */ - if ((state->src.x1 & subpixel_src_mask) || - (state->src.x2 & subpixel_src_mask) || - (state->src.y1 & subpixel_src_mask) || - (state->src.y2 & subpixel_src_mask)) { - return -EINVAL; - } - - vc4_state->src_x = state->src.x1 >> 16; - vc4_state->src_y = state->src.y1 >> 16; - vc4_state->src_w[0] = (state->src.x2 - state->src.x1) >> 16; - vc4_state->src_h[0] = (state->src.y2 - state->src.y1) >> 16; + /* + * We don't support subpixel source positioning for scaling, + * but fractional coordinates can be generated by clipping + * so just round for now + */ + vc4_state->src_x = DIV_ROUND_CLOSEST(state->src.x1, 1 << 16); + vc4_state->src_y = DIV_ROUND_CLOSEST(state->src.y1, 1 << 16); + vc4_state->src_w[0] = DIV_ROUND_CLOSEST(state->src.x2, 1 << 16) - vc4_state->src_x; + vc4_state->src_h[0] = DIV_ROUND_CLOSEST(state->src.y2, 1 << 16) - vc4_state->src_y;
vc4_state->crtc_x = state->dst.x1; vc4_state->crtc_y = state->dst.y1;
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit b7c3d6821627861f4ea3e1f2b595d0ed9e80aac8 ]
The current plane margin calculation code clips the right and bottom edges of the range based using the left and top margins.
This is obviously wrong, so let's fix it.
Fixes: 666e73587f90 ("drm/vc4: Take margin setup into account when updating planes") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-6-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_plane.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 67402da89213..568371aa89c5 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -310,16 +310,16 @@ static int vc4_plane_margins_adj(struct drm_plane_state *pstate) adjhdisplay, crtc_state->mode.hdisplay); vc4_pstate->crtc_x += left; - if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - left) - vc4_pstate->crtc_x = crtc_state->mode.hdisplay - left; + if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - right) + vc4_pstate->crtc_x = crtc_state->mode.hdisplay - right;
adjvdisplay = crtc_state->mode.vdisplay - (top + bottom); vc4_pstate->crtc_y = DIV_ROUND_CLOSEST(vc4_pstate->crtc_y * adjvdisplay, crtc_state->mode.vdisplay); vc4_pstate->crtc_y += top; - if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - top) - vc4_pstate->crtc_y = crtc_state->mode.vdisplay - top; + if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - bottom) + vc4_pstate->crtc_y = crtc_state->mode.vdisplay - bottom;
vc4_pstate->crtc_w = DIV_ROUND_CLOSEST(vc4_pstate->crtc_w * adjhdisplay,
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit 89c4bbe2a01ea401c2b0fabc104720809084b77f ]
On Pi0-3 the driver allocates a buffer and requests a DMA channel because the ARM can't write to DSI1's registers directly.
However, we never release that buffer or channel. Let's add a device-managed action to release each.
Fixes: 4078f5757144 ("drm/vc4: Add DSI driver") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-12-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_dsi.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index 98308a17e4ed..e82ee94cafc7 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -1487,13 +1487,29 @@ vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi) dsi->clk_onecell); }
+static void vc4_dsi_dma_mem_release(void *ptr) +{ + struct vc4_dsi *dsi = ptr; + struct device *dev = &dsi->pdev->dev; + + dma_free_coherent(dev, 4, dsi->reg_dma_mem, dsi->reg_dma_paddr); + dsi->reg_dma_mem = NULL; +} + +static void vc4_dsi_dma_chan_release(void *ptr) +{ + struct vc4_dsi *dsi = ptr; + + dma_release_channel(dsi->reg_dma_chan); + dsi->reg_dma_chan = NULL; +} + static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm = dev_get_drvdata(master); struct vc4_dsi *dsi = dev_get_drvdata(dev); struct vc4_dsi_encoder *vc4_dsi_encoder; - dma_cap_mask_t dma_mask; int ret;
dsi->variant = of_device_get_match_data(dev); @@ -1527,6 +1543,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) * so set up a channel for talking to it. */ if (dsi->variant->broken_axi_workaround) { + dma_cap_mask_t dma_mask; + dsi->reg_dma_mem = dma_alloc_coherent(dev, 4, &dsi->reg_dma_paddr, GFP_KERNEL); @@ -1535,8 +1553,13 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) return -ENOMEM; }
+ ret = devm_add_action_or_reset(dev, vc4_dsi_dma_mem_release, dsi); + if (ret) + return ret; + dma_cap_zero(dma_mask); dma_cap_set(DMA_MEMCPY, dma_mask); + dsi->reg_dma_chan = dma_request_chan_by_mask(&dma_mask); if (IS_ERR(dsi->reg_dma_chan)) { ret = PTR_ERR(dsi->reg_dma_chan); @@ -1546,6 +1569,10 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) return ret; }
+ ret = devm_add_action_or_reset(dev, vc4_dsi_dma_chan_release, dsi); + if (ret) + return ret; + /* Get the physical address of the device's registers. The * struct resource for the regs gives us the bus address * instead.
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit 3b45eee87da171caa28f61240ddb5c21170cda53 ]
The divider calculations tried to find the divider just faster than the clock requested. However if it required a divider of 7 then the for loop aborted without handling the "error" case, and could end up with a clock lower than requested.
The integer divider from parent PLL to DSI clock is also capable of going up to /255, not just /7 that the driver was trying. This allows for slower link frequencies on the DSI bus where the resolution permits.
Correct the loop so that we always have a clock greater than requested, and covering the whole range of dividers.
Fixes: 86c1b9eff3f2 ("drm/vc4: Adjust modes in DSI to work around the integer PLL divider.") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-13-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_dsi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index e82ee94cafc7..81a6c4e9576d 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -805,11 +805,9 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder, /* Find what divider gets us a faster clock than the requested * pixel clock. */ - for (divider = 1; divider < 8; divider++) { - if (parent_rate / divider < pll_clock) { - divider--; + for (divider = 1; divider < 255; divider++) { + if (parent_rate / (divider + 1) < pll_clock) break; - } }
/* Now that we've picked a PLL divider, calculate back to its
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit edfe84ae0df16be1251b5a8e840d95f1f3827500 ]
For slightly unknown reasons, dsi0 takes a different pixel format to dsi1, and that has to be set in the pixel valve.
Amend the setup accordingly.
Fixes: a86773d120d7 ("drm/vc4: Add support for feeding DSI encoders from the pixel valve.") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-14-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_crtc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 9355213dc883..12a5944ee980 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -319,7 +319,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1; bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 || vc4_encoder->type == VC4_ENCODER_TYPE_DSI1); - u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24; + bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1; + u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24; u8 ppc = pv_data->pixels_per_clock; bool debug_dump_regs = false;
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit 4d9273c978d4c1af15d7874c10c732ec83d444d0 ]
vc4_dsi was registering both dsi0 and dsi1 as VC4_ENCODER_TYPE_DSI1 which seemed to work OK for a single DSI display, but fails if there are two DSI displays connected.
Update to register the correct type.
Fixes: 4078f5757144 ("drm/vc4: Add DSI driver") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-15-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_dsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index 81a6c4e9576d..97a258c934af 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -1518,7 +1518,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) return -ENOMEM;
INIT_LIST_HEAD(&dsi->bridge_chain); - vc4_dsi_encoder->base.type = VC4_ENCODER_TYPE_DSI1; + vc4_dsi_encoder->base.type = dsi->variant->port ? + VC4_ENCODER_TYPE_DSI1 : VC4_ENCODER_TYPE_DSI0; vc4_dsi_encoder->dsi = dsi; dsi->encoder = &vc4_dsi_encoder->base.base;
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit bc5b815e06f90cccdb6461aba1e49fdc2f3c8cd1 ]
DSI0 seemingly had very little or no testing as a load of the register mappings were incorrect/missing, so host transfers always timed out due to enabling/checking incorrect bits in the interrupt enable and status registers.
Fixes: 4078f5757144 ("drm/vc4: Add DSI driver") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-16-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_dsi.c | 111 ++++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index 97a258c934af..333ea96fcde4 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -181,8 +181,50 @@
#define DSI0_TXPKT_PIX_FIFO 0x20 /* AKA PIX_FIFO */
-#define DSI0_INT_STAT 0x24 -#define DSI0_INT_EN 0x28 +#define DSI0_INT_STAT 0x24 +#define DSI0_INT_EN 0x28 +# define DSI0_INT_FIFO_ERR BIT(25) +# define DSI0_INT_CMDC_DONE_MASK VC4_MASK(24, 23) +# define DSI0_INT_CMDC_DONE_SHIFT 23 +# define DSI0_INT_CMDC_DONE_NO_REPEAT 1 +# define DSI0_INT_CMDC_DONE_REPEAT 3 +# define DSI0_INT_PHY_DIR_RTF BIT(22) +# define DSI0_INT_PHY_D1_ULPS BIT(21) +# define DSI0_INT_PHY_D1_STOP BIT(20) +# define DSI0_INT_PHY_RXLPDT BIT(19) +# define DSI0_INT_PHY_RXTRIG BIT(18) +# define DSI0_INT_PHY_D0_ULPS BIT(17) +# define DSI0_INT_PHY_D0_LPDT BIT(16) +# define DSI0_INT_PHY_D0_FTR BIT(15) +# define DSI0_INT_PHY_D0_STOP BIT(14) +/* Signaled when the clock lane enters the given state. */ +# define DSI0_INT_PHY_CLK_ULPS BIT(13) +# define DSI0_INT_PHY_CLK_HS BIT(12) +# define DSI0_INT_PHY_CLK_FTR BIT(11) +/* Signaled on timeouts */ +# define DSI0_INT_PR_TO BIT(10) +# define DSI0_INT_TA_TO BIT(9) +# define DSI0_INT_LPRX_TO BIT(8) +# define DSI0_INT_HSTX_TO BIT(7) +/* Contention on a line when trying to drive the line low */ +# define DSI0_INT_ERR_CONT_LP1 BIT(6) +# define DSI0_INT_ERR_CONT_LP0 BIT(5) +/* Control error: incorrect line state sequence on data lane 0. */ +# define DSI0_INT_ERR_CONTROL BIT(4) +# define DSI0_INT_ERR_SYNC_ESC BIT(3) +# define DSI0_INT_RX2_PKT BIT(2) +# define DSI0_INT_RX1_PKT BIT(1) +# define DSI0_INT_CMD_PKT BIT(0) + +#define DSI0_INTERRUPTS_ALWAYS_ENABLED (DSI0_INT_ERR_SYNC_ESC | \ + DSI0_INT_ERR_CONTROL | \ + DSI0_INT_ERR_CONT_LP0 | \ + DSI0_INT_ERR_CONT_LP1 | \ + DSI0_INT_HSTX_TO | \ + DSI0_INT_LPRX_TO | \ + DSI0_INT_TA_TO | \ + DSI0_INT_PR_TO) + # define DSI1_INT_PHY_D3_ULPS BIT(30) # define DSI1_INT_PHY_D3_STOP BIT(29) # define DSI1_INT_PHY_D2_ULPS BIT(28) @@ -892,6 +934,9 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
DSI_PORT_WRITE(PHY_AFEC0, afec0);
+ /* AFEC reset hold time */ + mdelay(1); + DSI_PORT_WRITE(PHY_AFEC1, VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE1) | VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE0) | @@ -1058,12 +1103,9 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI1_CTRL_EN);
/* Bring AFE out of reset. */ - if (dsi->variant->port == 0) { - } else { - DSI_PORT_WRITE(PHY_AFEC0, - DSI_PORT_READ(PHY_AFEC0) & - ~DSI1_PHY_AFEC0_RESET); - } + DSI_PORT_WRITE(PHY_AFEC0, + DSI_PORT_READ(PHY_AFEC0) & + ~DSI_PORT_BIT(PHY_AFEC0_RESET));
vc4_dsi_ulps(dsi, false);
@@ -1182,13 +1224,28 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host, /* Enable the appropriate interrupt for the transfer completion. */ dsi->xfer_result = 0; reinit_completion(&dsi->xfer_completion); - DSI_PORT_WRITE(INT_STAT, DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF); - if (msg->rx_len) { - DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED | - DSI1_INT_PHY_DIR_RTF)); + if (dsi->variant->port == 0) { + DSI_PORT_WRITE(INT_STAT, + DSI0_INT_CMDC_DONE_MASK | DSI1_INT_PHY_DIR_RTF); + if (msg->rx_len) { + DSI_PORT_WRITE(INT_EN, (DSI0_INTERRUPTS_ALWAYS_ENABLED | + DSI0_INT_PHY_DIR_RTF)); + } else { + DSI_PORT_WRITE(INT_EN, + (DSI0_INTERRUPTS_ALWAYS_ENABLED | + VC4_SET_FIELD(DSI0_INT_CMDC_DONE_NO_REPEAT, + DSI0_INT_CMDC_DONE))); + } } else { - DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED | - DSI1_INT_TXPKT1_DONE)); + DSI_PORT_WRITE(INT_STAT, + DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF); + if (msg->rx_len) { + DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED | + DSI1_INT_PHY_DIR_RTF)); + } else { + DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED | + DSI1_INT_TXPKT1_DONE)); + } }
/* Send the packet. */ @@ -1205,7 +1262,7 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host, ret = dsi->xfer_result; }
- DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED); + DSI_PORT_WRITE(INT_EN, DSI_PORT_BIT(INTERRUPTS_ALWAYS_ENABLED));
if (ret) goto reset_fifo_and_return; @@ -1251,7 +1308,7 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host, DSI_PORT_BIT(CTRL_RESET_FIFOS));
DSI_PORT_WRITE(TXPKT1C, 0); - DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED); + DSI_PORT_WRITE(INT_EN, DSI_PORT_BIT(INTERRUPTS_ALWAYS_ENABLED)); return ret; }
@@ -1388,26 +1445,28 @@ static irqreturn_t vc4_dsi_irq_handler(int irq, void *data) DSI_PORT_WRITE(INT_STAT, stat);
dsi_handle_error(dsi, &ret, stat, - DSI1_INT_ERR_SYNC_ESC, "LPDT sync"); + DSI_PORT_BIT(INT_ERR_SYNC_ESC), "LPDT sync"); dsi_handle_error(dsi, &ret, stat, - DSI1_INT_ERR_CONTROL, "data lane 0 sequence"); + DSI_PORT_BIT(INT_ERR_CONTROL), "data lane 0 sequence"); dsi_handle_error(dsi, &ret, stat, - DSI1_INT_ERR_CONT_LP0, "LP0 contention"); + DSI_PORT_BIT(INT_ERR_CONT_LP0), "LP0 contention"); dsi_handle_error(dsi, &ret, stat, - DSI1_INT_ERR_CONT_LP1, "LP1 contention"); + DSI_PORT_BIT(INT_ERR_CONT_LP1), "LP1 contention"); dsi_handle_error(dsi, &ret, stat, - DSI1_INT_HSTX_TO, "HSTX timeout"); + DSI_PORT_BIT(INT_HSTX_TO), "HSTX timeout"); dsi_handle_error(dsi, &ret, stat, - DSI1_INT_LPRX_TO, "LPRX timeout"); + DSI_PORT_BIT(INT_LPRX_TO), "LPRX timeout"); dsi_handle_error(dsi, &ret, stat, - DSI1_INT_TA_TO, "turnaround timeout"); + DSI_PORT_BIT(INT_TA_TO), "turnaround timeout"); dsi_handle_error(dsi, &ret, stat, - DSI1_INT_PR_TO, "peripheral reset timeout"); + DSI_PORT_BIT(INT_PR_TO), "peripheral reset timeout");
- if (stat & (DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF)) { + if (stat & ((dsi->variant->port ? DSI1_INT_TXPKT1_DONE : + DSI0_INT_CMDC_DONE_MASK) | + DSI_PORT_BIT(INT_PHY_DIR_RTF))) { complete(&dsi->xfer_completion); ret = IRQ_HANDLED; - } else if (stat & DSI1_INT_HSTX_TO) { + } else if (stat & DSI_PORT_BIT(INT_HSTX_TO)) { complete(&dsi->xfer_completion); dsi->xfer_result = -ETIMEDOUT; ret = IRQ_HANDLED;
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit 7bcb9c8d0bc9f3cab8ac2634b056c2e6b63945ca ]
vc4_dsi_encoder_disable is partially an open coded version of drm_bridge_chain_disable, but it missed a termination condition in the loop for ->disable which meant that no post_disable calls were made.
Add in the termination clause.
Fixes: 033bfe7538a1 ("drm/vc4: dsi: Fix bridge chain handling") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-17-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_dsi.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index 333ea96fcde4..b7b2c76770dc 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -803,6 +803,9 @@ static void vc4_dsi_encoder_disable(struct drm_encoder *encoder) list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) { if (iter->funcs->disable) iter->funcs->disable(iter); + + if (iter == dsi->bridge) + break; }
vc4_dsi_ulps(dsi, true);
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit 25eb441d55d479581a65bcc9de88bc1d86bf76c1 ]
The vc5 HDMI registers hadn't been added into the debugfs register sets, therefore weren't dumped on request. Add them in.
Fixes: 8323989140f3 ("drm/vc4: hdmi: Support the BCM2711 HDMI controllers") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-19-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 39 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vc4/vc4_hdmi.h | 8 +++++++ 2 files changed, 47 insertions(+)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 6b4f42332d95..e314e0a4c4c3 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -145,6 +145,12 @@ static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
drm_print_regset32(&p, &vc4_hdmi->hdmi_regset); drm_print_regset32(&p, &vc4_hdmi->hd_regset); + drm_print_regset32(&p, &vc4_hdmi->cec_regset); + drm_print_regset32(&p, &vc4_hdmi->csc_regset); + drm_print_regset32(&p, &vc4_hdmi->dvp_regset); + drm_print_regset32(&p, &vc4_hdmi->phy_regset); + drm_print_regset32(&p, &vc4_hdmi->ram_regset); + drm_print_regset32(&p, &vc4_hdmi->rm_regset);
return 0; } @@ -2704,6 +2710,7 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi) struct platform_device *pdev = vc4_hdmi->pdev; struct device *dev = &pdev->dev; struct resource *res; + int ret;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi"); if (!res) @@ -2800,6 +2807,38 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi) return PTR_ERR(vc4_hdmi->reset); }
+ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hdmi_regset, VC4_HDMI); + if (ret) + return ret; + + ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hd_regset, VC4_HD); + if (ret) + return ret; + + ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->cec_regset, VC5_CEC); + if (ret) + return ret; + + ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->csc_regset, VC5_CSC); + if (ret) + return ret; + + ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->dvp_regset, VC5_DVP); + if (ret) + return ret; + + ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->phy_regset, VC5_PHY); + if (ret) + return ret; + + ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->ram_regset, VC5_RAM); + if (ret) + return ret; + + ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->rm_regset, VC5_RM); + if (ret) + return ret; + return 0; }
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h index 51b27dcdcd9b..1520387b317f 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h @@ -179,6 +179,14 @@ struct vc4_hdmi { struct debugfs_regset32 hdmi_regset; struct debugfs_regset32 hd_regset;
+ /* VC5 only */ + struct debugfs_regset32 cec_regset; + struct debugfs_regset32 csc_regset; + struct debugfs_regset32 dvp_regset; + struct debugfs_regset32 phy_regset; + struct debugfs_regset32 ram_regset; + struct debugfs_regset32 rm_regset; + /** * @hw_lock: Spinlock protecting device register access. */
From: Dom Cobley popcornmix@gmail.com
[ Upstream commit b6079d1578dc4b4b8050d613a5449a63def7d1dd ]
Using a hdmi analyser the bytes in packet ram registers beyond the length were visible in the infoframes and it flagged the checksum as invalid.
Zeroing unused words of packet RAM avoids this
Fixes: 21317b3fba54 ("drm/vc4: Set up the AVI and SPD infoframes.") Signed-off-by: Dom Cobley popcornmix@gmail.com Link: https://lore.kernel.org/r/20220613144800.326124-20-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index e314e0a4c4c3..ecd49214bd92 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -461,9 +461,11 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder, const struct vc4_hdmi_register *ram_packet_start = &vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START]; u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id; + u32 packet_reg_next = ram_packet_start->offset + + VC4_HDMI_PACKET_STRIDE * (packet_id + 1); void __iomem *base = __vc4_hdmi_get_field_base(vc4_hdmi, ram_packet_start->reg); - uint8_t buffer[VC4_HDMI_PACKET_STRIDE]; + uint8_t buffer[VC4_HDMI_PACKET_STRIDE] = {}; unsigned long flags; ssize_t len, i; int ret; @@ -499,6 +501,13 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder, packet_reg += 4; }
+ /* + * clear remainder of packet ram as it's included in the + * infoframe and triggers a checksum error on hdmi analyser + */ + for (; packet_reg < packet_reg_next; packet_reg += 4) + writel(0, base + packet_reg); + HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, HDMI_READ(HDMI_RAM_PACKET_CONFIG) | BIT(packet_id));
From: Dom Cobley popcornmix@gmail.com
[ Upstream commit 1c594eeccf92368177c2e22f1d3ee4933dfb8567 ]
We are getting occasional VC4_HD_MAI_CTL_ERRORF in HDMI_MAI_CTL which seem to correspond with audio dropouts.
Reduce the threshold where we deassert DREQ to avoid the fifo overfilling
Fixes: bb7d78568814 ("drm/vc4: Add HDMI audio support") Signed-off-by: Dom Cobley popcornmix@gmail.com Link: https://lore.kernel.org/r/20220613144800.326124-21-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index ecd49214bd92..d0921f832f19 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1956,10 +1956,10 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
/* Set the MAI threshold */ HDMI_WRITE(HDMI_MAI_THR, - VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) | - VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) | - VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQHIGH) | - VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQLOW)); + VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_PANICHIGH) | + VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_PANICLOW) | + VC4_SET_FIELD(0x06, VC4_HD_MAI_THR_DREQHIGH) | + VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_DREQLOW));
HDMI_WRITE(HDMI_MAI_CONFIG, VC4_HDMI_MAI_CONFIG_BIT_REVERSE |
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit 35dc00c12a72700a9c4592afee7d136ecb280cbd ]
The HDMI block can repeat pixels for double clocked modes, and the firmware is now configuring the block to do this as the PV is doing it incorrectly when at 2pixels/clock. If the kernel doesn't reset it then we end up with strange modes.
Reset MISC_CONTROL.
Fixes: 8323989140f3 ("drm/vc4: hdmi: Support the BCM2711 HDMI controllers") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-22-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++++++ drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 3 +++ 2 files changed, 11 insertions(+)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index d0921f832f19..b73f64f0ba09 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -79,6 +79,9 @@ #define VC5_HDMI_VERTB_VSPO_SHIFT 16 #define VC5_HDMI_VERTB_VSPO_MASK VC4_MASK(29, 16)
+#define VC5_HDMI_MISC_CONTROL_PIXEL_REP_SHIFT 0 +#define VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK VC4_MASK(3, 0) + #define VC5_HDMI_SCRAMBLER_CTL_ENABLE BIT(0)
#define VC5_HDMI_DEEP_COLOR_CONFIG_1_INIT_PACK_PHASE_SHIFT 8 @@ -1117,6 +1120,11 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, reg |= gcp_en ? VC5_HDMI_GCP_CONFIG_GCP_ENABLE : 0; HDMI_WRITE(HDMI_GCP_CONFIG, reg);
+ reg = HDMI_READ(HDMI_MISC_CONTROL); + reg &= ~VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK; + reg |= VC4_SET_FIELD(0, VC5_HDMI_MISC_CONTROL_PIXEL_REP); + HDMI_WRITE(HDMI_MISC_CONTROL, reg); + HDMI_WRITE(HDMI_CLOCK_STOP, 0);
spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h index a040356b6bdc..549cc63dab39 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h @@ -127,6 +127,7 @@ enum vc4_hdmi_field { HDMI_VERTB0, HDMI_VERTB1, HDMI_VID_CTL, + HDMI_MISC_CONTROL, };
struct vc4_hdmi_register { @@ -237,6 +238,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi0_fields[] = { VC4_HDMI_REG(HDMI_VERTB0, 0x0f0), VC4_HDMI_REG(HDMI_VERTA1, 0x0f4), VC4_HDMI_REG(HDMI_VERTB1, 0x0f8), + VC4_HDMI_REG(HDMI_MISC_CONTROL, 0x100), VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c), VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0), VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x170), @@ -319,6 +321,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi1_fields[] = { VC4_HDMI_REG(HDMI_VERTB0, 0x0f0), VC4_HDMI_REG(HDMI_VERTA1, 0x0f4), VC4_HDMI_REG(HDMI_VERTB1, 0x0f8), + VC4_HDMI_REG(HDMI_MISC_CONTROL, 0x100), VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c), VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0), VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x170),
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit fcef97e70094a33ded73b3eb9bef06698c6e9c12 ]
If the controller isn't clocked or its domain powered up, the register accesses will either stall the CPU or return garbage, respectively.
Thus, we had a warning in our register access function to complain when that kind of risky accesses were performed.
In order to check the runtime_pm power state, we were using pm_runtime_active(), but it turns out that it will become active only once the runtime_resume hook has been executed.
This prevents us from doing any WARN-free register access in our runtime_resume() implementation, while this is valid.
Let's switch to pm_runtime_status_suspended() instead.
Fixes: 14e193b95604 ("drm/vc4: hdmi: Warn if we access the controller while disabled") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-23-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h index 549cc63dab39..0198de96c7b2 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h @@ -423,7 +423,7 @@ static inline u32 vc4_hdmi_read(struct vc4_hdmi *hdmi, const struct vc4_hdmi_variant *variant = hdmi->variant; void __iomem *base;
- WARN_ON(!pm_runtime_active(&hdmi->pdev->dev)); + WARN_ON(pm_runtime_status_suspended(&hdmi->pdev->dev));
if (reg >= variant->num_registers) { dev_warn(&hdmi->pdev->dev, @@ -453,7 +453,7 @@ static inline void vc4_hdmi_write(struct vc4_hdmi *hdmi,
lockdep_assert_held(&hdmi->hw_lock);
- WARN_ON(!pm_runtime_active(&hdmi->pdev->dev)); + WARN_ON(pm_runtime_status_suspended(&hdmi->pdev->dev));
if (reg >= variant->num_registers) { dev_warn(&hdmi->pdev->dev,
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit 467e30171b5b483922b1c24c573fa50787207cb6 ]
The BCM2835-37 found in the RaspberryPi 0 to 3 have a power domain attached to the HDMI block, handled in Linux through runtime_pm.
That power domain is shared with the VEC block, so even if we put our runtime_pm reference in the HDMI driver it would keep being on. If the VEC is disabled though, the power domain would be disabled and we would lose any initialization done in our bind implementation.
That initialization involves calling the reset function and initializing the CEC registers.
Let's move the initialization to our runtime_resume implementation so that we initialize everything properly if we ever need to.
Fixes: c86b41214362 ("drm/vc4: hdmi: Move the HSM clock enable to runtime_pm") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-24-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 41 ++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index b73f64f0ba09..f3e0de6515e0 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -2544,8 +2544,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) struct cec_connector_info conn_info; struct platform_device *pdev = vc4_hdmi->pdev; struct device *dev = &pdev->dev; - unsigned long flags; - u32 value; int ret;
if (!of_find_property(dev->of_node, "interrupts", NULL)) { @@ -2564,15 +2562,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector); cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info);
- spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - value = HDMI_READ(HDMI_CEC_CNTRL_1); - /* Set the logical address to Unregistered */ - value |= VC4_HDMI_CEC_ADDR_MASK; - HDMI_WRITE(HDMI_CEC_CNTRL_1, value); - spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - - vc4_hdmi_cec_update_clk_div(vc4_hdmi); - if (vc4_hdmi->variant->external_irq_controller) { ret = request_threaded_irq(platform_get_irq_byname(pdev, "cec-rx"), vc4_cec_irq_handler_rx_bare, @@ -2588,10 +2577,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) if (ret) goto err_remove_cec_rx_handler; } else { - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff); - spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - ret = request_threaded_irq(platform_get_irq(pdev, 0), vc4_cec_irq_handler, vc4_cec_irq_handler_thread, 0, @@ -2642,7 +2627,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) }
static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi) {}; - #endif
static int vc4_hdmi_build_regset(struct vc4_hdmi *vc4_hdmi, @@ -2871,12 +2855,34 @@ static int __maybe_unused vc4_hdmi_runtime_suspend(struct device *dev) static int vc4_hdmi_runtime_resume(struct device *dev) { struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); + unsigned long __maybe_unused flags; + u32 __maybe_unused value; int ret;
ret = clk_prepare_enable(vc4_hdmi->hsm_clock); if (ret) return ret;
+ if (vc4_hdmi->variant->reset) + vc4_hdmi->variant->reset(vc4_hdmi); + +#ifdef CONFIG_DRM_VC4_HDMI_CEC + spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); + value = HDMI_READ(HDMI_CEC_CNTRL_1); + /* Set the logical address to Unregistered */ + value |= VC4_HDMI_CEC_ADDR_MASK; + HDMI_WRITE(HDMI_CEC_CNTRL_1, value); + spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); + + vc4_hdmi_cec_update_clk_div(vc4_hdmi); + + if (!vc4_hdmi->variant->external_irq_controller) { + spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); + HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff); + spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); + } +#endif + return 0; }
@@ -2966,9 +2972,6 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) pm_runtime_set_active(dev); pm_runtime_enable(dev);
- if (vc4_hdmi->variant->reset) - vc4_hdmi->variant->reset(vc4_hdmi); - if ((of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi0") || of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi1")) && HDMI_READ(HDMI_VID_CTL) & VC4_HD_VID_CTL_ENABLE) {
From: Mateusz Kwiatkowski kfyatek+publicgit@gmail.com
[ Upstream commit 0ee5a40152b15f200ed3a0d51e8aa782ea979c6a ]
Increase the number of post-sync blanking lines on odd fields instead of decreasing it on even fields. This makes the total number of lines properly match the modelines.
Additionally fix the value of PV_VCONTROL_ODD_DELAY, which did not take pixels_per_clock into account, causing some displays to invert the fields when driven by bcm2711.
Fixes: 682e62c45406 ("drm/vc4: Fix support for interlaced modes on HDMI.") Signed-off-by: Mateusz Kwiatkowski kfyatek+publicgit@gmail.com Link: https://lore.kernel.org/r/20220613144800.326124-31-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_crtc.c | 7 ++++--- drivers/gpu/drm/vc4/vc4_hdmi.c | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 12a5944ee980..b2628afcb327 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -346,7 +346,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode PV_HORZB_HACTIVE));
CRTC_WRITE(PV_VERTA, - VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end, + VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end + + interlace, PV_VERTA_VBP) | VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start, PV_VERTA_VSYNC)); @@ -358,7 +359,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode if (interlace) { CRTC_WRITE(PV_VERTA_EVEN, VC4_SET_FIELD(mode->crtc_vtotal - - mode->crtc_vsync_end - 1, + mode->crtc_vsync_end, PV_VERTA_VBP) | VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start, @@ -378,7 +379,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode PV_VCONTROL_CONTINUOUS | (is_dsi ? PV_VCONTROL_DSI : 0) | PV_VCONTROL_INTERLACE | - VC4_SET_FIELD(mode->htotal * pixel_rep / 2, + VC4_SET_FIELD(mode->htotal * pixel_rep / (2 * ppc), PV_VCONTROL_ODD_DELAY)); CRTC_WRITE(PV_VSYNCD_EVEN, 0); } else { diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index f3e0de6515e0..674bd29a7cf2 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -988,12 +988,12 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, VC4_HDMI_VERTA_VFP) | VC4_SET_FIELD(mode->crtc_vdisplay, VC4_HDMI_VERTA_VAL)); u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) | - VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end, + VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end + + interlaced, VC4_HDMI_VERTB_VBP)); u32 vertb_even = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) | VC4_SET_FIELD(mode->crtc_vtotal - - mode->crtc_vsync_end - - interlaced, + mode->crtc_vsync_end, VC4_HDMI_VERTB_VBP)); unsigned long flags;
@@ -1041,12 +1041,12 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, VC5_HDMI_VERTA_VFP) | VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL)); u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) | - VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end, + VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end + + interlaced, VC4_HDMI_VERTB_VBP)); u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) | VC4_SET_FIELD(mode->crtc_vtotal - - mode->crtc_vsync_end - - interlaced, + mode->crtc_vsync_end, VC4_HDMI_VERTB_VBP)); unsigned long flags; unsigned char gcp;
From: Dom Cobley popcornmix@gmail.com
[ Upstream commit c94cd0620a922156c9ff9af9c3301b174b287677 ]
Whenever the maximum BPC is changed, vc4_hdmi_encoder_compute_config() might pick up a different BPC or format depending on the display capabilities.
That change will have a number of side effects, including the clock rates and whether the scrambling is enabled.
However, only drm_crtc_state.connectors_changed will be set to true, since that properly only affects the connector.
This means that while drm_atomic_crtc_needs_modeset() will return true, and thus drm_atomic_helper_commit_modeset_enables() will call our encoder atomic_enable() hook, mode_changed will be false.
So crtc_set_mode() will not call our encoder .atomic_mode_set() hook. We use this hook in vc4 to set the vc4_hdmi_connector_state.output_bpc (and output_format), and will then reuse the value in .atomic_enable() to select whether or not scrambling should be enabled.
However, since our clock rate is pre-computed during .atomic_check(), we end up with the clocks properly configured, but the scrambling disabled, leading to a blank screen.
Let's set mode_changed to true in our HDMI driver to force the update of output_bpc, and thus prevent the issue entirely.
Fixes: ba8c0faebbb0 ("drm/vc4: hdmi: Enable 10/12 bpc output") Signed-off-by: Dom Cobley popcornmix@gmail.com Link: https://lore.kernel.org/r/20220613144800.326124-32-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 674bd29a7cf2..3829e13c8627 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1620,9 +1620,14 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { + struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); + struct drm_connector *connector = &vc4_hdmi->connector; + struct drm_connector_state *old_conn_state = + drm_atomic_get_old_connector_state(conn_state->state, connector); + struct vc4_hdmi_connector_state *old_vc4_state = + conn_state_to_vc4_hdmi_conn_state(old_conn_state); struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state); struct drm_display_mode *mode = &crtc_state->adjusted_mode; - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); unsigned long long tmds_char_rate = mode->clock * 1000; unsigned long long tmds_bit_rate; int ret; @@ -1651,6 +1656,11 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder, if (ret) return ret;
+ /* vc4_hdmi_encoder_compute_config may have changed output_bpc and/or output_format */ + if (vc4_state->output_bpc != old_vc4_state->output_bpc || + vc4_state->output_format != old_vc4_state->output_format) + crtc_state->mode_changed = true; + return 0; }
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit fb10dc451c0f15e3c19798a2f41d357f3f7576f5 ]
For interlaced modes the timings were not being correctly programmed into the HDMI block, so correct them.
Fixes: 8323989140f3 ("drm/vc4: hdmi: Support the BCM2711 HDMI controllers") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-33-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 3829e13c8627..ad7fcfa5a068 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1040,13 +1040,13 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay, VC5_HDMI_VERTA_VFP) | VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL)); - u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) | - VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end + - interlaced, + u32 vertb = (VC4_SET_FIELD(mode->htotal >> (2 - pixel_rep), + VC5_HDMI_VERTB_VSPO) | + VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end, VC4_HDMI_VERTB_VBP)); u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) | VC4_SET_FIELD(mode->crtc_vtotal - - mode->crtc_vsync_end, + mode->crtc_vsync_end - interlaced, VC4_HDMI_VERTB_VBP)); unsigned long flags; unsigned char gcp;
From: Dave Stevenson dave.stevenson@raspberrypi.com
[ Upstream commit 3650062e4281ab28a6f8c9d59606d0a6266be736 ]
With the change to 2 pixels/clock, the pixel doubling in the PV results in doubling each pair of pixels, ie ABABCDCD instead of AABBCCDD.
Move the pixel doubling to the HDMI block, however this means that DBLCLK modes now fall foul of requiring even values for all the horizontal timing parameters. As both 480i and 576i fail this, attempt to fix up DBLCLK modes that have odd timings values.
Fixes: 8323989140f3 ("drm/vc4: hdmi: Support the BCM2711 HDMI controllers") Signed-off-by: Dave Stevenson dave.stevenson@raspberrypi.com Link: https://lore.kernel.org/r/20220613144800.326124-34-maxime@cerno.tech Signed-off-by: Maxime Ripard maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_crtc.c | 4 +++- drivers/gpu/drm/vc4/vc4_hdmi.c | 34 ++++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index b2628afcb327..af0fcb41e420 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -316,7 +316,9 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode struct drm_crtc_state *crtc_state = crtc->state; struct drm_display_mode *mode = &crtc_state->adjusted_mode; bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE; - u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1; + bool is_hdmi = vc4_encoder->type == VC4_ENCODER_TYPE_HDMI0 || + vc4_encoder->type == VC4_ENCODER_TYPE_HDMI1; + u32 pixel_rep = ((mode->flags & DRM_MODE_FLAG_DBLCLK) && !is_hdmi) ? 2 : 1; bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 || vc4_encoder->type == VC4_ENCODER_TYPE_DSI1); bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1; diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index ad7fcfa5a068..23ff6aa5e8f6 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -79,6 +79,8 @@ #define VC5_HDMI_VERTB_VSPO_SHIFT 16 #define VC5_HDMI_VERTB_VSPO_MASK VC4_MASK(29, 16)
+#define VC4_HDMI_MISC_CONTROL_PIXEL_REP_SHIFT 0 +#define VC4_HDMI_MISC_CONTROL_PIXEL_REP_MASK VC4_MASK(3, 0) #define VC5_HDMI_MISC_CONTROL_PIXEL_REP_SHIFT 0 #define VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK VC4_MASK(3, 0)
@@ -996,6 +998,7 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, mode->crtc_vsync_end, VC4_HDMI_VERTB_VBP)); unsigned long flags; + u32 reg;
spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
@@ -1022,6 +1025,11 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, HDMI_WRITE(HDMI_VERTB0, vertb_even); HDMI_WRITE(HDMI_VERTB1, vertb);
+ reg = HDMI_READ(HDMI_MISC_CONTROL); + reg &= ~VC4_HDMI_MISC_CONTROL_PIXEL_REP_MASK; + reg |= VC4_SET_FIELD(pixel_rep - 1, VC4_HDMI_MISC_CONTROL_PIXEL_REP); + HDMI_WRITE(HDMI_MISC_CONTROL, reg); + spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); }
@@ -1122,7 +1130,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
reg = HDMI_READ(HDMI_MISC_CONTROL); reg &= ~VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK; - reg |= VC4_SET_FIELD(0, VC5_HDMI_MISC_CONTROL_PIXEL_REP); + reg |= VC4_SET_FIELD(pixel_rep - 1, VC5_HDMI_MISC_CONTROL_PIXEL_REP); HDMI_WRITE(HDMI_MISC_CONTROL, reg);
HDMI_WRITE(HDMI_CLOCK_STOP, 0); @@ -1632,11 +1640,25 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder, unsigned long long tmds_bit_rate; int ret;
- if (vc4_hdmi->variant->unsupported_odd_h_timings && - !(mode->flags & DRM_MODE_FLAG_DBLCLK) && - ((mode->hdisplay % 2) || (mode->hsync_start % 2) || - (mode->hsync_end % 2) || (mode->htotal % 2))) - return -EINVAL; + if (vc4_hdmi->variant->unsupported_odd_h_timings) { + if (mode->flags & DRM_MODE_FLAG_DBLCLK) { + /* Only try to fixup DBLCLK modes to get 480i and 576i + * working. + * A generic solution for all modes with odd horizontal + * timing values seems impossible based on trying to + * solve it for 1366x768 monitors. + */ + if ((mode->hsync_start - mode->hdisplay) & 1) + mode->hsync_start--; + if ((mode->hsync_end - mode->hsync_start) & 1) + mode->hsync_end--; + } + + /* Now check whether we still have odd values remaining */ + if ((mode->hdisplay % 2) || (mode->hsync_start % 2) || + (mode->hsync_end % 2) || (mode->htotal % 2)) + return -EINVAL; + }
/* * The 1440p@60 pixel rate is in the same range than the first
From: Matthew Wilcox (Oracle) willy@infradead.org
[ Upstream commit fb5c2029f8221e904e604938171c4a8ef169aadb ]
If the last folio in a file is split as a result of truncation, we simply clear the dirty bits for the pages we're discarding. That causes NR_FILE_DIRTY (among other counters) to be thrown off and eventually Linux will hang in balance_dirty_pages_ratelimited()
Reported-by: Dave Chinner dchinner@redhat.com Tested-by: Dave Chinner dchinner@redhat.com Tested-by: Darrick J. Wong djwong@kernel.org Fixes: d68eccad3706 ("mm/filemap: Allow large folios to be added to the page cache") Signed-off-by: Matthew Wilcox (Oracle) willy@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/huge_memory.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 834f288b3769..15965084816d 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -18,6 +18,7 @@ #include <linux/shrinker.h> #include <linux/mm_inline.h> #include <linux/swapops.h> +#include <linux/backing-dev.h> #include <linux/dax.h> #include <linux/khugepaged.h> #include <linux/freezer.h> @@ -2440,11 +2441,15 @@ static void __split_huge_page(struct page *page, struct list_head *list, __split_huge_page_tail(head, i, lruvec, list); /* Some pages can be beyond EOF: drop them from page cache */ if (head[i].index >= end) { - ClearPageDirty(head + i); - __delete_from_page_cache(head + i, NULL); + struct folio *tail = page_folio(head + i); + if (shmem_mapping(head->mapping)) shmem_uncharge(head->mapping->host, 1); - put_page(head + i); + else if (folio_test_clear_dirty(tail)) + folio_account_cleaned(tail, + inode_to_wb(folio->mapping->host)); + __filemap_remove_folio(tail, NULL); + folio_put(tail); } else if (!PageAnon(page)) { __xa_store(&head->mapping->i_pages, head[i].index, head + i, 0);
From: Qian Cai quic_qiancai@quicinc.com
[ Upstream commit fac76f2260893dde5aa05bb693b4c13e8ed0454b ]
Otherwise, we could fail to compile.
ld: arch/arm64/crypto/ghash-ce-glue.o: in function 'ghash_ce_mod_exit': ghash-ce-glue.c:(.exit.text+0x24): undefined reference to 'crypto_unregister_aead' ld: arch/arm64/crypto/ghash-ce-glue.o: in function 'ghash_ce_mod_init': ghash-ce-glue.c:(.init.text+0x34): undefined reference to 'crypto_register_aead'
Fixes: 537c1445ab0b ("crypto: arm64/gcm - implement native driver using v8 Crypto Extensions") Signed-off-by: Qian Cai quic_qiancai@quicinc.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/crypto/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig index ac85682c013c..e3aaa971d660 100644 --- a/arch/arm64/crypto/Kconfig +++ b/arch/arm64/crypto/Kconfig @@ -71,6 +71,7 @@ config CRYPTO_GHASH_ARM64_CE select CRYPTO_HASH select CRYPTO_GF128MUL select CRYPTO_LIB_AES + select CRYPTO_AEAD
config CRYPTO_CRCT10DIF_ARM64_CE tristate "CRCT10DIF digest algorithm using PMULL instructions"
From: Maciej Fijalkowski maciej.fijalkowski@intel.com
[ Upstream commit 39e940d4abfabb08b6937a315546b24d10be67e3 ]
Currently, xsk_socket__delete frees BPF resources regardless of ctx refcount. Xdpxceiver has a test to verify whether underlying BPF resources would not be wiped out after closing XSK socket that was bound to interface with other active sockets. From library's xsk part perspective it also means that the internal xsk context is shared and its refcount is bumped accordingly.
After a switch to loading XDP prog based on previously opened XSK socket, mentioned xdpxceiver test fails with:
not ok 16 [xdpxceiver.c:swap_xsk_resources:1334]: ERROR: 9/"Bad file descriptor
which means that in swap_xsk_resources(), xsk_socket__delete() released xskmap which in turn caused a failure of xsk_socket__update_xskmap().
To fix this, when deleting socket, decrement ctx refcount before releasing BPF resources and do so only when refcount dropped to 0 which means there are no more active sockets for this ctx so BPF resources can be freed safely.
Fixes: 2f6324a3937f ("libbpf: Support shared umems between queues and devices") Signed-off-by: Maciej Fijalkowski maciej.fijalkowski@intel.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Magnus Karlsson magnus.karlsson@intel.com Link: https://lore.kernel.org/bpf/20220629143458.934337-5-maciej.fijalkowski@intel... Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/xsk.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index af136f73b09d..67dc010e9fe3 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c @@ -1147,8 +1147,6 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr, goto out_mmap_tx; }
- ctx->prog_fd = -1; - if (!(xsk->config.libbpf_flags & XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD)) { err = __xsk_setup_xdp_prog(xsk, NULL); if (err) @@ -1229,7 +1227,10 @@ void xsk_socket__delete(struct xsk_socket *xsk)
ctx = xsk->ctx; umem = ctx->umem; - if (ctx->prog_fd != -1) { + + xsk_put_ctx(ctx, true); + + if (!ctx->refcount) { xsk_delete_bpf_maps(xsk); close(ctx->prog_fd); if (ctx->has_bpf_link) @@ -1248,8 +1249,6 @@ void xsk_socket__delete(struct xsk_socket *xsk) } }
- xsk_put_ctx(ctx, true); - umem->refcount--; /* Do not close an fd that also has an associated umem connected * to it.
From: Xiaoliang Yang xiaoliang.yang_1@nxp.com
[ Upstream commit 8670dc33f48bab4d7bb4b8d0232f17f4dae419ec ]
When adjusting the PTP clock, the base time of the TAS configuration will become unreliable. We need reset the TAS configuration by using a new base time.
For example, if the driver gets a base time 0 of Qbv configuration from user, and current time is 20000. The driver will set the TAS base time to be 20000. After the PTP clock adjustment, the current time becomes 10000. If the TAS base time is still 20000, it will be a future time, and TAS entry list will stop running. Another example, if the current time becomes to be 10000000 after PTP clock adjust, a large time offset can cause the hardware to hang.
This patch introduces a tas_clock_adjust() function to reset the TAS module by using a new base time after the PTP clock adjustment. This can avoid issues above.
Due to PTP clock adjustment can occur at any time, it may conflict with the TAS configuration. We introduce a new TAS lock to serialize the access to the TAS registers.
Signed-off-by: Xiaoliang Yang xiaoliang.yang_1@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/ocelot/felix_vsc9959.c | 83 ++++++++++++++++++++++++-- drivers/net/ethernet/mscc/ocelot.c | 1 + drivers/net/ethernet/mscc/ocelot_ptp.c | 8 +++ include/soc/mscc/ocelot.h | 7 +++ 4 files changed, 93 insertions(+), 6 deletions(-)
diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 9c27b9b0128d..693cd6ffbace 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -1196,10 +1196,13 @@ static void vsc9959_tas_gcl_set(struct ocelot *ocelot, const u32 gcl_ix, static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port, struct tc_taprio_qopt_offload *taprio) { + struct ocelot_port *ocelot_port = ocelot->ports[port]; struct timespec64 base_ts; int ret, i; u32 val;
+ mutex_lock(&ocelot->tas_lock); + if (!taprio->enable) { ocelot_rmw_rix(ocelot, QSYS_TAG_CONFIG_INIT_GATE_STATE(0xFF), @@ -1207,15 +1210,20 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port, QSYS_TAG_CONFIG_INIT_GATE_STATE_M, QSYS_TAG_CONFIG, port);
+ mutex_unlock(&ocelot->tas_lock); return 0; }
if (taprio->cycle_time > NSEC_PER_SEC || - taprio->cycle_time_extension >= NSEC_PER_SEC) - return -EINVAL; + taprio->cycle_time_extension >= NSEC_PER_SEC) { + ret = -EINVAL; + goto err; + }
- if (taprio->num_entries > VSC9959_TAS_GCL_ENTRY_MAX) - return -ERANGE; + if (taprio->num_entries > VSC9959_TAS_GCL_ENTRY_MAX) { + ret = -ERANGE; + goto err; + }
/* Enable guard band. The switch will schedule frames without taking * their length into account. Thus we'll always need to enable the @@ -1236,8 +1244,10 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port, * config is pending, need reset the TAS module */ val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8); - if (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING) - return -EBUSY; + if (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING) { + ret = -EBUSY; + goto err; + }
ocelot_rmw_rix(ocelot, QSYS_TAG_CONFIG_ENABLE | @@ -1248,6 +1258,8 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port, QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_M, QSYS_TAG_CONFIG, port);
+ ocelot_port->base_time = taprio->base_time; + vsc9959_new_base_time(ocelot, taprio->base_time, taprio->cycle_time, &base_ts); ocelot_write(ocelot, base_ts.tv_nsec, QSYS_PARAM_CFG_REG_1); @@ -1271,9 +1283,67 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port, !(val & QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE), 10, 100000);
+err: + mutex_unlock(&ocelot->tas_lock); + return ret; }
+static void vsc9959_tas_clock_adjust(struct ocelot *ocelot) +{ + struct ocelot_port *ocelot_port; + struct timespec64 base_ts; + u64 cycletime; + int port; + u32 val; + + mutex_lock(&ocelot->tas_lock); + + for (port = 0; port < ocelot->num_phys_ports; port++) { + val = ocelot_read_rix(ocelot, QSYS_TAG_CONFIG, port); + if (!(val & QSYS_TAG_CONFIG_ENABLE)) + continue; + + ocelot_rmw(ocelot, + QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(port), + QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M, + QSYS_TAS_PARAM_CFG_CTRL); + + ocelot_rmw_rix(ocelot, + QSYS_TAG_CONFIG_INIT_GATE_STATE(0xFF), + QSYS_TAG_CONFIG_ENABLE | + QSYS_TAG_CONFIG_INIT_GATE_STATE_M, + QSYS_TAG_CONFIG, port); + + cycletime = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_4); + ocelot_port = ocelot->ports[port]; + + vsc9959_new_base_time(ocelot, ocelot_port->base_time, + cycletime, &base_ts); + + ocelot_write(ocelot, base_ts.tv_nsec, QSYS_PARAM_CFG_REG_1); + ocelot_write(ocelot, lower_32_bits(base_ts.tv_sec), + QSYS_PARAM_CFG_REG_2); + val = upper_32_bits(base_ts.tv_sec); + ocelot_rmw(ocelot, + QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB(val), + QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB_M, + QSYS_PARAM_CFG_REG_3); + + ocelot_rmw(ocelot, QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE, + QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE, + QSYS_TAS_PARAM_CFG_CTRL); + + ocelot_rmw_rix(ocelot, + QSYS_TAG_CONFIG_INIT_GATE_STATE(0xFF) | + QSYS_TAG_CONFIG_ENABLE, + QSYS_TAG_CONFIG_ENABLE | + QSYS_TAG_CONFIG_INIT_GATE_STATE_M, + QSYS_TAG_CONFIG, port); + } + mutex_unlock(&ocelot->tas_lock); +} + static int vsc9959_qos_port_cbs_set(struct dsa_switch *ds, int port, struct tc_cbs_qopt_offload *cbs_qopt) { @@ -2214,6 +2284,7 @@ static const struct ocelot_ops vsc9959_ops = { .psfp_filter_del = vsc9959_psfp_filter_del, .psfp_stats_get = vsc9959_psfp_stats_get, .cut_through_fwd = vsc9959_cut_through_fwd, + .tas_clock_adjust = vsc9959_tas_clock_adjust, };
static const struct felix_info felix_info_vsc9959 = { diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index 8da7e25a47c9..d4649e4ee0e7 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -3367,6 +3367,7 @@ int ocelot_init(struct ocelot *ocelot) mutex_init(&ocelot->ptp_lock); mutex_init(&ocelot->mact_lock); mutex_init(&ocelot->fwd_domain_lock); + mutex_init(&ocelot->tas_lock); spin_lock_init(&ocelot->ptp_clock_lock); spin_lock_init(&ocelot->ts_id_lock); snprintf(queue_name, sizeof(queue_name), "%s-stats", diff --git a/drivers/net/ethernet/mscc/ocelot_ptp.c b/drivers/net/ethernet/mscc/ocelot_ptp.c index 87ad2137ba06..09c703efe946 100644 --- a/drivers/net/ethernet/mscc/ocelot_ptp.c +++ b/drivers/net/ethernet/mscc/ocelot_ptp.c @@ -72,6 +72,10 @@ int ocelot_ptp_settime64(struct ptp_clock_info *ptp, ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); + + if (ocelot->ops->tas_clock_adjust) + ocelot->ops->tas_clock_adjust(ocelot); + return 0; } EXPORT_SYMBOL(ocelot_ptp_settime64); @@ -105,6 +109,9 @@ int ocelot_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); + + if (ocelot->ops->tas_clock_adjust) + ocelot->ops->tas_clock_adjust(ocelot); } else { /* Fall back using ocelot_ptp_settime64 which is not exact. */ struct timespec64 ts; @@ -117,6 +124,7 @@ int ocelot_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
ocelot_ptp_settime64(ptp, &ts); } + return 0; } EXPORT_SYMBOL(ocelot_ptp_adjtime); diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index 5f88385a7748..3737570116c3 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -575,6 +575,7 @@ struct ocelot_ops { int (*psfp_stats_get)(struct ocelot *ocelot, struct flow_cls_offload *f, struct flow_stats *stats); void (*cut_through_fwd)(struct ocelot *ocelot); + void (*tas_clock_adjust)(struct ocelot *ocelot); };
struct ocelot_vcap_policer { @@ -691,6 +692,9 @@ struct ocelot_port { int bridge_num;
int speed; + + /* Store the AdminBaseTime of EST fetched from userspace. */ + s64 base_time; };
struct ocelot { @@ -757,6 +761,9 @@ struct ocelot { /* Lock for serializing forwarding domain changes */ struct mutex fwd_domain_lock;
+ /* Lock for serializing Time-Aware Shaper changes */ + struct mutex tas_lock; + struct workqueue_struct *owq;
u8 ptp:1;
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 1c9017e44af2eee94b1001af18c401ae440ad77c ]
In a future change we will need to remember the entire tc-taprio config on all ports rather than just the base time, so use the taprio_offload_get() helper function to replace ocelot_port->base_time with ocelot_port->taprio.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/ocelot/felix_vsc9959.c | 23 +++++++++++++---------- include/soc/mscc/ocelot.h | 5 ++--- 2 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 693cd6ffbace..12792362bbee 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -1210,6 +1210,9 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port, QSYS_TAG_CONFIG_INIT_GATE_STATE_M, QSYS_TAG_CONFIG, port);
+ taprio_offload_free(ocelot_port->taprio); + ocelot_port->taprio = NULL; + mutex_unlock(&ocelot->tas_lock); return 0; } @@ -1258,8 +1261,6 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port, QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_M, QSYS_TAG_CONFIG, port);
- ocelot_port->base_time = taprio->base_time; - vsc9959_new_base_time(ocelot, taprio->base_time, taprio->cycle_time, &base_ts); ocelot_write(ocelot, base_ts.tv_nsec, QSYS_PARAM_CFG_REG_1); @@ -1282,6 +1283,10 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port, ret = readx_poll_timeout(vsc9959_tas_read_cfg_status, ocelot, val, !(val & QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE), 10, 100000); + if (ret) + goto err; + + ocelot_port->taprio = taprio_offload_get(taprio);
err: mutex_unlock(&ocelot->tas_lock); @@ -1291,17 +1296,18 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
static void vsc9959_tas_clock_adjust(struct ocelot *ocelot) { + struct tc_taprio_qopt_offload *taprio; struct ocelot_port *ocelot_port; struct timespec64 base_ts; - u64 cycletime; int port; u32 val;
mutex_lock(&ocelot->tas_lock);
for (port = 0; port < ocelot->num_phys_ports; port++) { - val = ocelot_read_rix(ocelot, QSYS_TAG_CONFIG, port); - if (!(val & QSYS_TAG_CONFIG_ENABLE)) + ocelot_port = ocelot->ports[port]; + taprio = ocelot_port->taprio; + if (!taprio) continue;
ocelot_rmw(ocelot, @@ -1315,11 +1321,8 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot) QSYS_TAG_CONFIG_INIT_GATE_STATE_M, QSYS_TAG_CONFIG, port);
- cycletime = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_4); - ocelot_port = ocelot->ports[port]; - - vsc9959_new_base_time(ocelot, ocelot_port->base_time, - cycletime, &base_ts); + vsc9959_new_base_time(ocelot, taprio->base_time, + taprio->cycle_time, &base_ts);
ocelot_write(ocelot, base_ts.tv_nsec, QSYS_PARAM_CFG_REG_1); ocelot_write(ocelot, lower_32_bits(base_ts.tv_sec), diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index 3737570116c3..ac151ecc7f19 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -670,6 +670,8 @@ struct ocelot_port { /* VLAN that untagged frames are classified to, on ingress */ const struct ocelot_bridge_vlan *pvid_vlan;
+ struct tc_taprio_qopt_offload *taprio; + phy_interface_t phy_mode;
unsigned int ptp_skbs_in_flight; @@ -692,9 +694,6 @@ struct ocelot_port { int bridge_num;
int speed; - - /* Store the AdminBaseTime of EST fetched from userspace. */ - s64 base_time; };
struct ocelot {
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 55a515b1f5a97df5704a1788fe97a4a740be2b9e ]
Currently, sending a packet into a time gate too small for it (or always closed) causes the queue system to hold the frame forever. Even worse, this frame isn't subject to aging either, because for that to happen, it needs to be scheduled for transmission in the first place. But the frame will consume buffer memory and frame references while it is forever held in the queue system.
Before commit a4ae997adcbd ("net: mscc: ocelot: initialize watermarks to sane defaults"), this behavior was somewhat subtle, as the switch had a more intricately tuned default watermark configuration out of reset, which did not allow any single port and tc to consume the entire switch buffer space. Nonetheless, the held frames are still there, and they reduce the total backplane capacity of the switch.
However, after the aforementioned commit, the behavior can be very clearly seen, since we deliberately allow each {port, tc} to consume the entire shared buffer of the switch minus the reservations (and we disable all reservations by default). That is to say, we allow a permanently closed tc-taprio gate to hang the entire switch.
A careful inspection of the documentation shows that the QSYS:Q_MAX_SDU per-port-tc registers serve 2 purposes: one is for guard band calculation (when zero, this falls back to QSYS:PORT_MAX_SDU), and the other is to enable oversized frame dropping (when non-zero).
Currently the QSYS:Q_MAX_SDU registers are all zero, so oversized frame dropping is disabled. The goal of the change is to enable it seamlessly. For that, we need to hook into the MTU change, tc-taprio change, and port link speed change procedures, since we depend on these variables.
Frames are not dropped on egress due to a queue system oversize condition, instead that egress port is simply excluded from the mask of valid destination ports for the packet. If there are no destination ports at all, the ingress counter that increments is the generic "drop_tail" in ethtool -S.
The issue exists in various forms since the tc-taprio offload was introduced.
Fixes: de143c0e274b ("net: dsa: felix: Configure Time-Aware Scheduler via taprio offload") Reported-by: Richie Pearn richard.pearn@nxp.com Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/ocelot/felix.c | 9 ++ drivers/net/dsa/ocelot/felix.h | 1 + drivers/net/dsa/ocelot/felix_vsc9959.c | 201 +++++++++++++++++++++++++ 3 files changed, 211 insertions(+)
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 3e07dc39007a..859196898a7d 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -1553,9 +1553,18 @@ static void felix_txtstamp(struct dsa_switch *ds, int port, static int felix_change_mtu(struct dsa_switch *ds, int port, int new_mtu) { struct ocelot *ocelot = ds->priv; + struct ocelot_port *ocelot_port = ocelot->ports[port]; + struct felix *felix = ocelot_to_felix(ocelot);
ocelot_port_set_maxlen(ocelot, port, new_mtu);
+ mutex_lock(&ocelot->tas_lock); + + if (ocelot_port->taprio && felix->info->tas_guard_bands_update) + felix->info->tas_guard_bands_update(ocelot, port); + + mutex_unlock(&ocelot->tas_lock); + return 0; }
diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h index 9e07eb7ee28d..deb8dde1fc19 100644 --- a/drivers/net/dsa/ocelot/felix.h +++ b/drivers/net/dsa/ocelot/felix.h @@ -53,6 +53,7 @@ struct felix_info { struct phylink_link_state *state); int (*port_setup_tc)(struct dsa_switch *ds, int port, enum tc_setup_type type, void *type_data); + void (*tas_guard_bands_update)(struct ocelot *ocelot, int port); void (*port_sched_speed_set)(struct ocelot *ocelot, int port, u32 speed); struct regmap *(*init_regmap)(struct ocelot *ocelot, diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 12792362bbee..643f13702dc7 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -1127,9 +1127,199 @@ static void vsc9959_mdio_bus_free(struct ocelot *ocelot) mdiobus_free(felix->imdio); }
+/* Extract shortest continuous gate open intervals in ns for each traffic class + * of a cyclic tc-taprio schedule. If a gate is always open, the duration is + * considered U64_MAX. If the gate is always closed, it is considered 0. + */ +static void vsc9959_tas_min_gate_lengths(struct tc_taprio_qopt_offload *taprio, + u64 min_gate_len[OCELOT_NUM_TC]) +{ + struct tc_taprio_sched_entry *entry; + u64 gate_len[OCELOT_NUM_TC]; + int tc, i, n; + + /* Initialize arrays */ + for (tc = 0; tc < OCELOT_NUM_TC; tc++) { + min_gate_len[tc] = U64_MAX; + gate_len[tc] = 0; + } + + /* If we don't have taprio, consider all gates as permanently open */ + if (!taprio) + return; + + n = taprio->num_entries; + + /* Walk through the gate list twice to determine the length + * of consecutively open gates for a traffic class, including + * open gates that wrap around. We are just interested in the + * minimum window size, and this doesn't change what the + * minimum is (if the gate never closes, min_gate_len will + * remain U64_MAX). + */ + for (i = 0; i < 2 * n; i++) { + entry = &taprio->entries[i % n]; + + for (tc = 0; tc < OCELOT_NUM_TC; tc++) { + if (entry->gate_mask & BIT(tc)) { + gate_len[tc] += entry->interval; + } else { + /* Gate closes now, record a potential new + * minimum and reinitialize length + */ + if (min_gate_len[tc] > gate_len[tc]) + min_gate_len[tc] = gate_len[tc]; + gate_len[tc] = 0; + } + } + } +} + +/* Update QSYS_PORT_MAX_SDU to make sure the static guard bands added by the + * switch (see the ALWAYS_GUARD_BAND_SCH_Q comment) are correct at all MTU + * values (the default value is 1518). Also, for traffic class windows smaller + * than one MTU sized frame, update QSYS_QMAXSDU_CFG to enable oversized frame + * dropping, such that these won't hang the port, as they will never be sent. + */ +static void vsc9959_tas_guard_bands_update(struct ocelot *ocelot, int port) +{ + struct ocelot_port *ocelot_port = ocelot->ports[port]; + u64 min_gate_len[OCELOT_NUM_TC]; + int speed, picos_per_byte; + u64 needed_bit_time_ps; + u32 val, maxlen; + u8 tas_speed; + int tc; + + lockdep_assert_held(&ocelot->tas_lock); + + val = ocelot_read_rix(ocelot, QSYS_TAG_CONFIG, port); + tas_speed = QSYS_TAG_CONFIG_LINK_SPEED_X(val); + + switch (tas_speed) { + case OCELOT_SPEED_10: + speed = SPEED_10; + break; + case OCELOT_SPEED_100: + speed = SPEED_100; + break; + case OCELOT_SPEED_1000: + speed = SPEED_1000; + break; + case OCELOT_SPEED_2500: + speed = SPEED_2500; + break; + default: + return; + } + + picos_per_byte = (USEC_PER_SEC * 8) / speed; + + val = ocelot_port_readl(ocelot_port, DEV_MAC_MAXLEN_CFG); + /* MAXLEN_CFG accounts automatically for VLAN. We need to include it + * manually in the bit time calculation, plus the preamble and SFD. + */ + maxlen = val + 2 * VLAN_HLEN; + /* Consider the standard Ethernet overhead of 8 octets preamble+SFD, + * 4 octets FCS, 12 octets IFG. + */ + needed_bit_time_ps = (maxlen + 24) * picos_per_byte; + + dev_dbg(ocelot->dev, + "port %d: max frame size %d needs %llu ps at speed %d\n", + port, maxlen, needed_bit_time_ps, speed); + + vsc9959_tas_min_gate_lengths(ocelot_port->taprio, min_gate_len); + + for (tc = 0; tc < OCELOT_NUM_TC; tc++) { + u32 max_sdu; + + if (min_gate_len[tc] == U64_MAX /* Gate always open */ || + min_gate_len[tc] * 1000 > needed_bit_time_ps) { + /* Setting QMAXSDU_CFG to 0 disables oversized frame + * dropping. + */ + max_sdu = 0; + dev_dbg(ocelot->dev, + "port %d tc %d min gate len %llu" + ", sending all frames\n", + port, tc, min_gate_len[tc]); + } else { + /* If traffic class doesn't support a full MTU sized + * frame, make sure to enable oversize frame dropping + * for frames larger than the smallest that would fit. + */ + max_sdu = div_u64(min_gate_len[tc] * 1000, + picos_per_byte); + /* A TC gate may be completely closed, which is a + * special case where all packets are oversized. + * Any limit smaller than 64 octets accomplishes this + */ + if (!max_sdu) + max_sdu = 1; + /* Take L1 overhead into account, but just don't allow + * max_sdu to go negative or to 0. Here we use 20 + * because QSYS_MAXSDU_CFG_* already counts the 4 FCS + * octets as part of packet size. + */ + if (max_sdu > 20) + max_sdu -= 20; + dev_info(ocelot->dev, + "port %d tc %d min gate length %llu" + " ns not enough for max frame size %d at %d" + " Mbps, dropping frames over %d" + " octets including FCS\n", + port, tc, min_gate_len[tc], maxlen, speed, + max_sdu); + } + + /* ocelot_write_rix is a macro that concatenates + * QSYS_MAXSDU_CFG_* with _RSZ, so we need to spell out + * the writes to each traffic class + */ + switch (tc) { + case 0: + ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_0, + port); + break; + case 1: + ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_1, + port); + break; + case 2: + ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_2, + port); + break; + case 3: + ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_3, + port); + break; + case 4: + ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_4, + port); + break; + case 5: + ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_5, + port); + break; + case 6: + ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_6, + port); + break; + case 7: + ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_7, + port); + break; + } + } + + ocelot_write_rix(ocelot, maxlen, QSYS_PORT_MAX_SDU, port); +} + static void vsc9959_sched_speed_set(struct ocelot *ocelot, int port, u32 speed) { + struct ocelot_port *ocelot_port = ocelot->ports[port]; u8 tas_speed;
switch (speed) { @@ -1154,6 +1344,13 @@ static void vsc9959_sched_speed_set(struct ocelot *ocelot, int port, QSYS_TAG_CONFIG_LINK_SPEED(tas_speed), QSYS_TAG_CONFIG_LINK_SPEED_M, QSYS_TAG_CONFIG, port); + + mutex_lock(&ocelot->tas_lock); + + if (ocelot_port->taprio) + vsc9959_tas_guard_bands_update(ocelot, port); + + mutex_unlock(&ocelot->tas_lock); }
static void vsc9959_new_base_time(struct ocelot *ocelot, ktime_t base_time, @@ -1213,6 +1410,8 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port, taprio_offload_free(ocelot_port->taprio); ocelot_port->taprio = NULL;
+ vsc9959_tas_guard_bands_update(ocelot, port); + mutex_unlock(&ocelot->tas_lock); return 0; } @@ -1287,6 +1486,7 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port, goto err;
ocelot_port->taprio = taprio_offload_get(taprio); + vsc9959_tas_guard_bands_update(ocelot, port);
err: mutex_unlock(&ocelot->tas_lock); @@ -2314,6 +2514,7 @@ static const struct felix_info felix_info_vsc9959 = { .port_modes = vsc9959_port_modes, .port_setup_tc = vsc9959_port_setup_tc, .port_sched_speed_set = vsc9959_sched_speed_set, + .tas_guard_bands_update = vsc9959_tas_guard_bands_update, .init_regmap = ocelot_regmap_init, };
From: Alaa Mohamed eng.alaamohamedsoliman.am@gmail.com
[ Upstream commit 9c154ab47f5e5ff632d2b7af6342c027d7e04b92 ]
parsing and usage of -t got missed in the previous patch. this patch fixes it
Fixes: 816cda9ae531 ("selftests: net: fib_rule_tests: add support to select a test to run") Signed-off-by: Alaa Mohamed eng.alaamohamedsoliman.am@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/fib_rule_tests.sh | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/tools/testing/selftests/net/fib_rule_tests.sh b/tools/testing/selftests/net/fib_rule_tests.sh index bbe3b379927a..c245476fa29d 100755 --- a/tools/testing/selftests/net/fib_rule_tests.sh +++ b/tools/testing/selftests/net/fib_rule_tests.sh @@ -303,6 +303,29 @@ run_fibrule_tests() log_section "IPv6 fib rule" fib_rule6_test } +################################################################################ +# usage + +usage() +{ + cat <<EOF +usage: ${0##*/} OPTS + + -t <test> Test(s) to run (default: all) + (options: $TESTS) +EOF +} + +################################################################################ +# main + +while getopts ":t:h" opt; do + case $opt in + t) TESTS=$OPTARG;; + h) usage; exit 0;; + *) usage; exit 1;; + esac +done
if [ "$(id -u)" -ne 0 ];then echo "SKIP: Need root privileges"
From: Brian Norris briannorris@chromium.org
[ Upstream commit 1449110b0dade8b638d2c17ab7c5b0ff696bfccb ]
It's possible for users to try to duplicate the CRTC state even when the state doesn't exist. drm_atomic_helper_crtc_duplicate_state() (and other users of __drm_atomic_helper_crtc_duplicate_state()) already guard this with a WARN_ON() instead of crashing, so let's do that here too.
Fixes: 4e257d9eee23 ("drm/rockchip: get rid of rockchip_drm_crtc_mode_config") Signed-off-by: Brian Norris briannorris@chromium.org Reviewed-by: Sean Paul seanpaul@chromium.org Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Heiko Stuebner heiko@sntech.de Link: https://patchwork.freedesktop.org/patch/msgid/20220617172623.1.I62db228170b1... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 74562d40f639..daf192881353 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1570,6 +1570,9 @@ static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc) { struct rockchip_crtc_state *rockchip_state;
+ if (WARN_ON(!crtc->state)) + return NULL; + rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL); if (!rockchip_state) return NULL;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 5074376822fe99fa4ce344b851c5016d00c0444f ]
Should component_add() fail, we should call analogix_dp_remove() in the error handling path, as already done in the remove function.
Fixes: 152cce0006ab ("drm/bridge: analogix_dp: Split bind() into probe() and real bind()") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Heiko Stuebner heiko@sntech.de Link: https://patchwork.freedesktop.org/patch/msgid/b719d9061bb97eb85145fbd3c5e63f... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 70be64ca0a00..ad2d3ae7e621 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -408,7 +408,15 @@ static int rockchip_dp_probe(struct platform_device *pdev) if (IS_ERR(dp->adp)) return PTR_ERR(dp->adp);
- return component_add(dev, &rockchip_dp_component_ops); + ret = component_add(dev, &rockchip_dp_component_ops); + if (ret) + goto err_dp_remove; + + return 0; + +err_dp_remove: + analogix_dp_remove(dp->adp); + return ret; }
static int rockchip_dp_remove(struct platform_device *pdev)
From: Bo-Chen Chen rex-bc.chen@mediatek.com
[ Upstream commit c9ed0713b3c35fc45677707ba47f432cad95da56 ]
DPI is not support output format as YUV, but there is the setting of configuring output YUV. Therefore, remove them in this patch.
Fixes: 9e629c17aa8d ("drm/mediatek: Add DPI sub driver") Signed-off-by: Bo-Chen Chen rex-bc.chen@mediatek.com Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220701035845.164... Signed-off-by: Chun-Kuang Hu chunkuang.hu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/mediatek/mtk_dpi.c | 31 ++++++------------------------ 1 file changed, 6 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index e61cd67b978f..675e2e4072df 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -54,13 +54,7 @@ enum mtk_dpi_out_channel_swap { };
enum mtk_dpi_out_color_format { - MTK_DPI_COLOR_FORMAT_RGB, - MTK_DPI_COLOR_FORMAT_RGB_FULL, - MTK_DPI_COLOR_FORMAT_YCBCR_444, - MTK_DPI_COLOR_FORMAT_YCBCR_422, - MTK_DPI_COLOR_FORMAT_XV_YCC, - MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL, - MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL + MTK_DPI_COLOR_FORMAT_RGB };
struct mtk_dpi { @@ -364,24 +358,11 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi) static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, enum mtk_dpi_out_color_format format) { - if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) || - (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) { - mtk_dpi_config_yuv422_enable(dpi, false); - mtk_dpi_config_csc_enable(dpi, true); - mtk_dpi_config_swap_input(dpi, false); - mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR); - } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) || - (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) { - mtk_dpi_config_yuv422_enable(dpi, true); - mtk_dpi_config_csc_enable(dpi, true); - mtk_dpi_config_swap_input(dpi, true); - mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); - } else { - mtk_dpi_config_yuv422_enable(dpi, false); - mtk_dpi_config_csc_enable(dpi, false); - mtk_dpi_config_swap_input(dpi, false); - mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); - } + /* only support RGB888 */ + mtk_dpi_config_yuv422_enable(dpi, false); + mtk_dpi_config_csc_enable(dpi, false); + mtk_dpi_config_swap_input(dpi, false); + mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); }
static void mtk_dpi_dual_edge(struct mtk_dpi *dpi)
From: Guillaume Ranquet granquet@baylibre.com
[ Upstream commit aed61ef6beb911cc043af0f2f291167663995065 ]
Enabling the dpi too early causes glitches on screen.
Move the call to mtk_dpi_enable() at the end of the bridge_enable callback to ensure everything is setup properly before enabling dpi.
Fixes: 9e629c17aa8d ("drm/mediatek: Add DPI sub driver") Signed-off-by: Guillaume Ranquet granquet@baylibre.com Signed-off-by: Bo-Chen Chen rex-bc.chen@mediatek.com Tested-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220701035845.164... Signed-off-by: Chun-Kuang Hu chunkuang.hu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 675e2e4072df..41c783349321 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -417,7 +417,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi) if (dpi->pinctrl && dpi->pins_dpi) pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
- mtk_dpi_enable(dpi); return 0;
err_pixel: @@ -639,6 +638,7 @@ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
mtk_dpi_power_on(dpi); mtk_dpi_set_display_mode(dpi, &dpi->mode); + mtk_dpi_enable(dpi); }
static enum drm_mode_status
From: Abhinav Kumar quic_abhinavk@quicinc.com
[ Upstream commit b4a624acabe99f2ea912e895529b8b37d1fa909d ]
intf and wb resources are not dependent on the rm global state so need not be allocated during dpu_encoder_virt_atomic_mode_set().
Move the allocation of intf and wb resources to dpu_encoder_setup_display() so that we can utilize the hw caps even during atomic_check() phase.
Since dpu_encoder_setup_display() already has protection against setting invalid intf_idx and wb_idx, these checks can now be dropped as well.
changes in v2: - add phys->hw_intf and phys->hw_wb checks back
changes in v3: - correct the Fixes tag
Fixes: e02a559a720f ("drm/msm/dpu: make changes to dpu_encoder to support virtual encoder") Signed-off-by: Abhinav Kumar quic_abhinavk@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/489885/ Link: https://lore.kernel.org/r/1655406084-17407-1-git-send-email-quic_abhinavk@qu... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 36 ++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index a1b8c4592943..9b4df3084366 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1048,24 +1048,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, phys->hw_pp = dpu_enc->hw_pp[i]; phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
- if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) - phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); - - if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) - phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); - - if (!phys->hw_intf && !phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "no intf or wb block assigned at idx: %d\n", i); - return; - } - - if (phys->hw_intf && phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "invalid phys both intf and wb block at idx: %d\n", i); - return; - } - phys->cached_mode = crtc_state->adjusted_mode; if (phys->ops.atomic_mode_set) phys->ops.atomic_mode_set(phys, crtc_state, conn_state); @@ -2294,7 +2276,25 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; atomic_set(&phys->vsync_cnt, 0); atomic_set(&phys->underrun_cnt, 0); + + if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) + phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); + + if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) + phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); + + if (!phys->hw_intf && !phys->hw_wb) { + DPU_ERROR_ENC(dpu_enc, "no intf or wb block assigned at idx: %d\n", i); + ret = -EINVAL; + } + + if (phys->hw_intf && phys->hw_wb) { + DPU_ERROR_ENC(dpu_enc, + "invalid phys both intf and wb block at idx: %d\n", i); + ret = -EINVAL; + } } + mutex_unlock(&dpu_enc->enc_lock);
return ret;
From: Abhinav Kumar quic_abhinavk@quicinc.com
[ Upstream commit a370cc392e075de5a4b7f3fb27cdeec0d70b5893 ]
Writeback block for sm8250 was using the default maxlinewidth of 2048. But this is not right as it supports upto 4096.
This should have no effect on most resolutions as we are still limiting upto maxlinewidth of SSPP for adding the modes.
Fix the maxlinewidth for writeback block on sm8250.
changes in v3: - correct the Fixes tag
Fixes: 53324b99bd7b ("drm/msm/dpu: add writeback blocks to the sm8250 DPU catalog") Signed-off-by: Abhinav Kumar quic_abhinavk@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/489887/ Link: https://lore.kernel.org/r/1655406084-17407-2-git-send-email-quic_abhinavk@qu... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 6 +++--- 1 file changed, 3 insertions(+), 3 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 400ebceb56bb..dd7537e32f88 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -1285,7 +1285,7 @@ static const struct dpu_intf_cfg qcm2290_intf[] = { * Writeback blocks config *************************************************************/ #define WB_BLK(_name, _id, _base, _features, _clk_ctrl, \ - __xin_id, vbif_id, _reg, _wb_done_bit) \ + __xin_id, vbif_id, _reg, _max_linewidth, _wb_done_bit) \ { \ .name = _name, .id = _id, \ .base = _base, .len = 0x2c8, \ @@ -1295,13 +1295,13 @@ static const struct dpu_intf_cfg qcm2290_intf[] = { .clk_ctrl = _clk_ctrl, \ .xin_id = __xin_id, \ .vbif_idx = vbif_id, \ - .maxlinewidth = DEFAULT_DPU_LINE_WIDTH, \ + .maxlinewidth = _max_linewidth, \ .intr_wb_done = DPU_IRQ_IDX(_reg, _wb_done_bit) \ }
static const struct dpu_wb_cfg sm8250_wb[] = { WB_BLK("wb_2", WB_2, 0x65000, WB_SM8250_MASK, DPU_CLK_CTRL_WB2, 6, - VBIF_RT, MDP_SSPP_TOP0_INTR, 4), + VBIF_RT, MDP_SSPP_TOP0_INTR, 4096, 4), };
/*************************************************************
From: Abhinav Kumar quic_abhinavk@quicinc.com
[ Upstream commit 4edea8d305873336a626c5f4ce17cb8751059054 ]
Remove the hard-coded limit for writeback and lets start using the one from catalog instead.
changes in v3: - correct the Fixes tag
Fixes: d7d0e73f7de3 ("drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback") Signed-off-by: Abhinav Kumar quic_abhinavk@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/489888/ Link: https://lore.kernel.org/r/1655406084-17407-3-git-send-email-quic_abhinavk@qu... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index 0ec809ab06e7..15919e1a8dc3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -20,8 +20,6 @@ #include "dpu_crtc.h" #include "disp/msm_disp_snapshot.h"
-#define DEFAULT_MAX_WRITEBACK_WIDTH 2048 - #define to_dpu_encoder_phys_wb(x) \ container_of(x, struct dpu_encoder_phys_wb, base)
@@ -278,9 +276,9 @@ static int dpu_encoder_phys_wb_atomic_check( DPU_ERROR("invalid fb h=%d, mode h=%d\n", fb->height, mode->vdisplay); return -EINVAL; - } else if (fb->width > DEFAULT_MAX_WRITEBACK_WIDTH) { + } else if (fb->width > phys_enc->hw_wb->caps->maxlinewidth) { DPU_ERROR("invalid fb w=%d, maxlinewidth=%u\n", - fb->width, DEFAULT_MAX_WRITEBACK_WIDTH); + fb->width, phys_enc->hw_wb->caps->maxlinewidth); return -EINVAL; }
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit a18a44e9262d5c7f7fbccbc9458df64d69185d41 ]
Conversion to use bulk regulator API omitted filling the pwr_regs with proper regulator IDs. This was left unnoticed, since none of my testing platforms has used the pwr_regs. Fix this by propagating regulator ids properly.
Fixes: 31b3b1f5e352 ("drm/msm/hdmi: use bulk regulator API") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Stephen Boyd swboyd@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/488847/ Link: https://lore.kernel.org/r/20220609113148.3149194-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/hdmi/hdmi.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index cf24e68864ba..73070ec1a936 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -180,6 +180,9 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) goto fail; }
+ for (i = 0; i < config->pwr_reg_cnt; i++) + hdmi->pwr_regs[i].supply = config->pwr_reg_names[i]; + ret = devm_regulator_bulk_get(&pdev->dev, config->pwr_reg_cnt, hdmi->pwr_regs); if (ret) { DRM_DEV_ERROR(&pdev->dev, "failed to get pwr regulator: %d\n", ret);
From: Hangyu Hua hbh25y@gmail.com
[ Upstream commit 21779cc21c732c5eff8ea1624be6590450baa30f ]
The next call to sii8620_burst_get_tx_buf will result in off-by-one When ctx->burst.tx_count + size == ARRAY_SIZE(ctx->burst.tx_buf). The same thing happens in sii8620_burst_get_rx_buf.
This patch also change tx_count and tx_buf to rx_count and rx_buf in sii8620_burst_get_rx_buf. It is unreasonable to check tx_buf's size and use rx_buf.
Fixes: e19e9c692f81 ("drm/bridge/sii8620: add support for burst eMSC transmissions") Signed-off-by: Hangyu Hua hbh25y@gmail.com Reviewed-by: Andrzej Hajda andrzej.hajda@intel.com Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220518065856.18936-1-hbh25y@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/sil-sii8620.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index ec7745c31da0..ab0bce4a988c 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -605,7 +605,7 @@ static void *sii8620_burst_get_tx_buf(struct sii8620 *ctx, int len) u8 *buf = &ctx->burst.tx_buf[ctx->burst.tx_count]; int size = len + 2;
- if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) { + if (ctx->burst.tx_count + size >= ARRAY_SIZE(ctx->burst.tx_buf)) { dev_err(ctx->dev, "TX-BLK buffer exhausted\n"); ctx->error = -EINVAL; return NULL; @@ -622,7 +622,7 @@ static u8 *sii8620_burst_get_rx_buf(struct sii8620 *ctx, int len) u8 *buf = &ctx->burst.rx_buf[ctx->burst.rx_count]; int size = len + 1;
- if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) { + if (ctx->burst.rx_count + size >= ARRAY_SIZE(ctx->burst.rx_buf)) { dev_err(ctx->dev, "RX-BLK buffer exhausted\n"); ctx->error = -EINVAL; return NULL;
From: Rob Clark robdclark@chromium.org
[ Upstream commit 2311720a0182756f175fbf4afc1fb76ac487b587 ]
And while we are at it, let's start the fence counter close to the rollover point so that if issues slip in, they are more obvious.
Signed-off-by: Rob Clark robdclark@chromium.org Fixes: fde5de6cb461 ("drm/msm: move fence code to it's own file") Fixes: 5f3aee4ceb5b ("drm/msm: Handle fence rollover") Patchwork: https://patchwork.freedesktop.org/patch/489619/ Link: https://lore.kernel.org/r/20220615162435.3011793-1-robdclark@gmail.com [DB: fixed the conflict while applying the patch] Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_fence.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index 38e3323bc232..a47e5837c528 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -28,6 +28,14 @@ msm_fence_context_alloc(struct drm_device *dev, volatile uint32_t *fenceptr, fctx->fenceptr = fenceptr; spin_lock_init(&fctx->spinlock);
+ /* + * Start out close to the 32b fence rollover point, so we can + * catch bugs with fence comparisons. + */ + fctx->last_fence = 0xffffff00; + fctx->completed_fence = fctx->last_fence; + *fctx->fenceptr = fctx->last_fence; + return fctx; }
@@ -52,7 +60,8 @@ void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence) unsigned long flags;
spin_lock_irqsave(&fctx->spinlock, flags); - fctx->completed_fence = max(fence, fctx->completed_fence); + if (fence_after(fence, fctx->completed_fence)) + fctx->completed_fence = fence; spin_unlock_irqrestore(&fctx->spinlock, flags); }
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit d7be266adbfd3aca6965ea6a0c36b2c3d8fc9fc8 ]
All callers of taprio_offload_get() and taprio_offload_free() prior to the blamed commit are conditionally compiled based on CONFIG_NET_SCH_TAPRIO.
felix_vsc9959.c is different; it provides vsc9959_qos_port_tas_set() even when taprio is compiled out.
Provide shim definitions for the functions exported by taprio so that felix_vsc9959.c is able to compile. vsc9959_qos_port_tas_set() in that case is dead code anyway, and ocelot_port->taprio remains NULL, which is fine for the rest of the logic.
Fixes: 1c9017e44af2 ("net: dsa: felix: keep reference on entire tc-taprio config") Reported-by: Colin Foster colin.foster@in-advantage.com Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Tested-by: Colin Foster colin.foster@in-advantage.com Acked-by: Vinicius Costa Gomes vinicius.gomes@intel.com Link: https://lore.kernel.org/r/20220704190241.1288847-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/pkt_sched.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 44a35531952e..3372a1f67cf4 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -173,11 +173,28 @@ struct tc_taprio_qopt_offload { struct tc_taprio_sched_entry entries[]; };
+#if IS_ENABLED(CONFIG_NET_SCH_TAPRIO) + /* Reference counting */ struct tc_taprio_qopt_offload *taprio_offload_get(struct tc_taprio_qopt_offload *offload); void taprio_offload_free(struct tc_taprio_qopt_offload *offload);
+#else + +/* Reference counting */ +static inline struct tc_taprio_qopt_offload * +taprio_offload_get(struct tc_taprio_qopt_offload *offload) +{ + return NULL; +} + +static inline void taprio_offload_free(struct tc_taprio_qopt_offload *offload) +{ +} + +#endif + /* Ensure skb_mstamp_ns, which might have been populated with the txtime, is * not mistaken for a software timestamp, because this will otherwise prevent * the dispatch of hardware timestamps to the socket.
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 10ed11ab6399813eb652137db9c378433c28a95c ]
felix_vsc9959.c calls taprio_offload_get() and taprio_offload_free(), symbols exported by net/sched/sch_taprio.c. As such, we must disallow building the Felix driver as built-in when the symbol exported by tc-taprio isn't present in the kernel image.
Fixes: 1c9017e44af2 ("net: dsa: felix: keep reference on entire tc-taprio config") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Link: https://lore.kernel.org/r/20220704190241.1288847-2-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/ocelot/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/dsa/ocelot/Kconfig b/drivers/net/dsa/ocelot/Kconfig index 220b0b027b55..08db9cf76818 100644 --- a/drivers/net/dsa/ocelot/Kconfig +++ b/drivers/net/dsa/ocelot/Kconfig @@ -6,6 +6,7 @@ config NET_DSA_MSCC_FELIX depends on NET_VENDOR_FREESCALE depends on HAS_IOMEM depends on PTP_1588_CLOCK_OPTIONAL + depends on NET_SCH_TAPRIO || NET_SCH_TAPRIO=n select MSCC_OCELOT_SWITCH_LIB select NET_DSA_TAG_OCELOT_8021Q select NET_DSA_TAG_OCELOT
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 7c2c57263af41cfd8b5022274e6801542831bb69 ]
'vlan_bitmap' is a bitmap and is used as such. So allocate it with devm_bitmap_zalloc() and its explicit bit size (i.e. VLAN_N_VID).
This avoids the need of the VLAN_BITMAP_SIZE macro which: - needlessly has a 'nic_dev' parameter - should be "long" (and not byte) aligned, so that the bitmap semantic is respected
This is in fact not an issue because VLAN_N_VID is 4096 at the time being, but devm_bitmap_zalloc() is less verbose and easier to understand.
Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/6ff7b7d21414240794a77dc2456914412718a145.165626084... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/huawei/hinic/hinic_main.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index 05329292d940..56a89793f47d 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -62,8 +62,6 @@ MODULE_PARM_DESC(rx_weight, "Number Rx packets for NAPI budget (default=64)");
#define HINIC_LRO_RX_TIMER_DEFAULT 16
-#define VLAN_BITMAP_SIZE(nic_dev) (ALIGN(VLAN_N_VID, 8) / 8) - #define work_to_rx_mode_work(work) \ container_of(work, struct hinic_rx_mode_work, work)
@@ -1242,9 +1240,8 @@ static int nic_dev_init(struct pci_dev *pdev) u64_stats_init(&tx_stats->syncp); u64_stats_init(&rx_stats->syncp);
- nic_dev->vlan_bitmap = devm_kzalloc(&pdev->dev, - VLAN_BITMAP_SIZE(nic_dev), - GFP_KERNEL); + nic_dev->vlan_bitmap = devm_bitmap_zalloc(&pdev->dev, VLAN_N_VID, + GFP_KERNEL); if (!nic_dev->vlan_bitmap) { err = -ENOMEM; goto err_vlan_bitmap;
From: Qiao Ma mqaio@linux.alibaba.com
[ Upstream commit 67dffd3db98570af8ff54c934f7d14664c0d182a ]
Function hinic_get_stats64() will do two operations: 1. reads stats from every hinic_rxq/txq and accumulates them 2. calls hinic_rxq/txq_clean_stats() to clean every rxq/txq's stats
For hinic_get_stats64(), it could get right data, because it sums all data to nic_dev->rx_stats/tx_stats. But it is wrong for get_drv_queue_stats(), this function will read hinic_rxq's stats, which have been cleared to zero by hinic_get_stats64().
I have observed hinic's cleanup operation by using such command:
watch -n 1 "cat ethtool -S eth4 | tail -40"
Result before: ... rxq7_pkts: 1 rxq7_bytes: 90 rxq7_errors: 0 rxq7_csum_errors: 0 rxq7_other_errors: 0 ... rxq9_pkts: 11 rxq9_bytes: 726 rxq9_errors: 0 rxq9_csum_errors: 0 rxq9_other_errors: 0 ... rxq11_pkts: 0 rxq11_bytes: 0 rxq11_errors: 0 rxq11_csum_errors: 0 rxq11_other_errors: 0
Result after a few seconds: ... rxq7_pkts: 0 rxq7_bytes: 0 rxq7_errors: 0 rxq7_csum_errors: 0 rxq7_other_errors: 0 ... rxq9_pkts: 2 rxq9_bytes: 132 rxq9_errors: 0 rxq9_csum_errors: 0 rxq9_other_errors: 0 ... rxq11_pkts: 1 rxq11_bytes: 170 rxq11_errors: 0 rxq11_csum_errors: 0 rxq11_other_errors: 0
To solve this problem, we just keep every queue's total stats in their own queue (aka hinic_{rxq|txq}), and simply sum all per-queue stats every time calling hinic_get_stats64(). With that solution, there is no need to clean per-queue stats now, and there is no need to maintain global hinic_dev.{tx|rx}_stats, too.
Fixes: edd384f682cc ("net-next/hinic: Add ethtool and stats") Signed-off-by: Qiao Ma mqaio@linux.alibaba.com Reported-by: kernel test robot lkp@intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/huawei/hinic/hinic_dev.h | 3 - .../net/ethernet/huawei/hinic/hinic_main.c | 57 ++++++------------- drivers/net/ethernet/huawei/hinic/hinic_rx.c | 2 - drivers/net/ethernet/huawei/hinic/hinic_tx.c | 2 - 4 files changed, 16 insertions(+), 48 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_dev.h index fb3e89141a0d..a4fbf44f944c 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_dev.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_dev.h @@ -95,9 +95,6 @@ struct hinic_dev { u16 sq_depth; u16 rq_depth;
- struct hinic_txq_stats tx_stats; - struct hinic_rxq_stats rx_stats; - u8 rss_tmpl_idx; u8 rss_hash_engine; u16 num_rss; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index 56a89793f47d..89dc52510fdc 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -80,56 +80,44 @@ static int set_features(struct hinic_dev *nic_dev, netdev_features_t pre_features, netdev_features_t features, bool force_change);
-static void update_rx_stats(struct hinic_dev *nic_dev, struct hinic_rxq *rxq) +static void gather_rx_stats(struct hinic_rxq_stats *nic_rx_stats, struct hinic_rxq *rxq) { - struct hinic_rxq_stats *nic_rx_stats = &nic_dev->rx_stats; struct hinic_rxq_stats rx_stats;
- u64_stats_init(&rx_stats.syncp); - hinic_rxq_get_stats(rxq, &rx_stats);
- u64_stats_update_begin(&nic_rx_stats->syncp); nic_rx_stats->bytes += rx_stats.bytes; nic_rx_stats->pkts += rx_stats.pkts; nic_rx_stats->errors += rx_stats.errors; nic_rx_stats->csum_errors += rx_stats.csum_errors; nic_rx_stats->other_errors += rx_stats.other_errors; - u64_stats_update_end(&nic_rx_stats->syncp); - - hinic_rxq_clean_stats(rxq); }
-static void update_tx_stats(struct hinic_dev *nic_dev, struct hinic_txq *txq) +static void gather_tx_stats(struct hinic_txq_stats *nic_tx_stats, struct hinic_txq *txq) { - struct hinic_txq_stats *nic_tx_stats = &nic_dev->tx_stats; struct hinic_txq_stats tx_stats;
- u64_stats_init(&tx_stats.syncp); - hinic_txq_get_stats(txq, &tx_stats);
- u64_stats_update_begin(&nic_tx_stats->syncp); nic_tx_stats->bytes += tx_stats.bytes; nic_tx_stats->pkts += tx_stats.pkts; nic_tx_stats->tx_busy += tx_stats.tx_busy; nic_tx_stats->tx_wake += tx_stats.tx_wake; nic_tx_stats->tx_dropped += tx_stats.tx_dropped; nic_tx_stats->big_frags_pkts += tx_stats.big_frags_pkts; - u64_stats_update_end(&nic_tx_stats->syncp); - - hinic_txq_clean_stats(txq); }
-static void update_nic_stats(struct hinic_dev *nic_dev) +static void gather_nic_stats(struct hinic_dev *nic_dev, + struct hinic_rxq_stats *nic_rx_stats, + struct hinic_txq_stats *nic_tx_stats) { int i, num_qps = hinic_hwdev_num_qps(nic_dev->hwdev);
for (i = 0; i < num_qps; i++) - update_rx_stats(nic_dev, &nic_dev->rxqs[i]); + gather_rx_stats(nic_rx_stats, &nic_dev->rxqs[i]);
for (i = 0; i < num_qps; i++) - update_tx_stats(nic_dev, &nic_dev->txqs[i]); + gather_tx_stats(nic_tx_stats, &nic_dev->txqs[i]); }
/** @@ -558,8 +546,6 @@ int hinic_close(struct net_device *netdev) netif_carrier_off(netdev); netif_tx_disable(netdev);
- update_nic_stats(nic_dev); - up(&nic_dev->mgmt_lock);
if (!HINIC_IS_VF(nic_dev->hwdev->hwif)) @@ -853,26 +839,23 @@ static void hinic_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) { struct hinic_dev *nic_dev = netdev_priv(netdev); - struct hinic_rxq_stats *nic_rx_stats; - struct hinic_txq_stats *nic_tx_stats; - - nic_rx_stats = &nic_dev->rx_stats; - nic_tx_stats = &nic_dev->tx_stats; + struct hinic_rxq_stats nic_rx_stats = {}; + struct hinic_txq_stats nic_tx_stats = {};
down(&nic_dev->mgmt_lock);
if (nic_dev->flags & HINIC_INTF_UP) - update_nic_stats(nic_dev); + gather_nic_stats(nic_dev, &nic_rx_stats, &nic_tx_stats);
up(&nic_dev->mgmt_lock);
- stats->rx_bytes = nic_rx_stats->bytes; - stats->rx_packets = nic_rx_stats->pkts; - stats->rx_errors = nic_rx_stats->errors; + stats->rx_bytes = nic_rx_stats.bytes; + stats->rx_packets = nic_rx_stats.pkts; + stats->rx_errors = nic_rx_stats.errors;
- stats->tx_bytes = nic_tx_stats->bytes; - stats->tx_packets = nic_tx_stats->pkts; - stats->tx_errors = nic_tx_stats->tx_dropped; + stats->tx_bytes = nic_tx_stats.bytes; + stats->tx_packets = nic_tx_stats.pkts; + stats->tx_errors = nic_tx_stats.tx_dropped; }
static int hinic_set_features(struct net_device *netdev, @@ -1171,8 +1154,6 @@ static void hinic_free_intr_coalesce(struct hinic_dev *nic_dev) static int nic_dev_init(struct pci_dev *pdev) { struct hinic_rx_mode_work *rx_mode_work; - struct hinic_txq_stats *tx_stats; - struct hinic_rxq_stats *rx_stats; struct hinic_dev *nic_dev; struct net_device *netdev; struct hinic_hwdev *hwdev; @@ -1234,12 +1215,6 @@ static int nic_dev_init(struct pci_dev *pdev)
sema_init(&nic_dev->mgmt_lock, 1);
- tx_stats = &nic_dev->tx_stats; - rx_stats = &nic_dev->rx_stats; - - u64_stats_init(&tx_stats->syncp); - u64_stats_init(&rx_stats->syncp); - nic_dev->vlan_bitmap = devm_bitmap_zalloc(&pdev->dev, VLAN_N_VID, GFP_KERNEL); if (!nic_dev->vlan_bitmap) { diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c index 24b7b819dbfb..a866bea65110 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c @@ -73,7 +73,6 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq, struct hinic_rxq_stats *stats) struct hinic_rxq_stats *rxq_stats = &rxq->rxq_stats; unsigned int start;
- u64_stats_update_begin(&stats->syncp); do { start = u64_stats_fetch_begin(&rxq_stats->syncp); stats->pkts = rxq_stats->pkts; @@ -83,7 +82,6 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq, struct hinic_rxq_stats *stats) stats->csum_errors = rxq_stats->csum_errors; stats->other_errors = rxq_stats->other_errors; } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); - u64_stats_update_end(&stats->syncp); }
/** diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.c b/drivers/net/ethernet/huawei/hinic/hinic_tx.c index 87408e7bb809..5051cdff2384 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c @@ -98,7 +98,6 @@ void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats) struct hinic_txq_stats *txq_stats = &txq->txq_stats; unsigned int start;
- u64_stats_update_begin(&stats->syncp); do { start = u64_stats_fetch_begin(&txq_stats->syncp); stats->pkts = txq_stats->pkts; @@ -108,7 +107,6 @@ void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats) stats->tx_dropped = txq_stats->tx_dropped; stats->big_frags_pkts = txq_stats->big_frags_pkts; } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); - u64_stats_update_end(&stats->syncp); }
/**
From: Qiao Ma mqaio@linux.alibaba.com
[ Upstream commit 98f9fcdee35add80505b6c73f72de5f750d5c03c ]
When using hinic device as a bond slave device, and reading device stats of master bond device, the kernel may hung.
The kernel panic calltrace as follows: Kernel panic - not syncing: softlockup: hung tasks Call trace: native_queued_spin_lock_slowpath+0x1ec/0x31c dev_get_stats+0x60/0xcc dev_seq_printf_stats+0x40/0x120 dev_seq_show+0x1c/0x40 seq_read_iter+0x3c8/0x4dc seq_read+0xe0/0x130 proc_reg_read+0xa8/0xe0 vfs_read+0xb0/0x1d4 ksys_read+0x70/0xfc __arm64_sys_read+0x20/0x30 el0_svc_common+0x88/0x234 do_el0_svc+0x2c/0x90 el0_svc+0x1c/0x30 el0_sync_handler+0xa8/0xb0 el0_sync+0x148/0x180
And the calltrace of task that actually caused kernel hungs as follows: __switch_to+124 __schedule+548 schedule+72 schedule_timeout+348 __down_common+188 __down+24 down+104 hinic_get_stats64+44 [hinic] dev_get_stats+92 bond_get_stats+172 [bonding] dev_get_stats+92 dev_seq_printf_stats+60 dev_seq_show+24 seq_read_iter+964 seq_read+220 proc_reg_read+164 vfs_read+172 ksys_read+108 __arm64_sys_read+28 el0_svc_common+132 do_el0_svc+40 el0_svc+24 el0_sync_handler+164 el0_sync+324
When getting device stats from bond, kernel will call bond_get_stats(). It first holds the spinlock bond->stats_lock, and then call hinic_get_stats64() to collect hinic device's stats. However, hinic_get_stats64() calls `down(&nic_dev->mgmt_lock)` to protect its critical section, which may schedule current task out. And if system is under high pressure, the task cannot be woken up immediately, which eventually triggers kernel hung panic.
Since previous patch has replaced hinic_dev.tx_stats/rx_stats with local variable in hinic_get_stats64(), there is nothing need to be protected by lock, so just removing down()/up() is ok.
Fixes: edd384f682cc ("net-next/hinic: Add ethtool and stats") Signed-off-by: Qiao Ma mqaio@linux.alibaba.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/huawei/hinic/hinic_main.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index 89dc52510fdc..c23ee2ddbce3 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -842,13 +842,9 @@ static void hinic_get_stats64(struct net_device *netdev, struct hinic_rxq_stats nic_rx_stats = {}; struct hinic_txq_stats nic_tx_stats = {};
- down(&nic_dev->mgmt_lock); - if (nic_dev->flags & HINIC_INTF_UP) gather_nic_stats(nic_dev, &nic_rx_stats, &nic_tx_stats);
- up(&nic_dev->mgmt_lock); - stats->rx_bytes = nic_rx_stats.bytes; stats->rx_packets = nic_rx_stats.pkts; stats->rx_errors = nic_rx_stats.errors;
From: Hsin-Yi Wang hsinyi@chromium.org
[ Upstream commit dfb02eb6bdf84697dbadd69a7df12db612ce4ed0 ]
Move devm_of_dp_aux_populate_ep_devices() after pm runtime and i2c setup to avoid NULL pointer crash.
edp-panel probe (generic_edp_panel_probe) calls pm_runtime_get_sync() to read EDID. At this time, bridge should have pm runtime enabled and i2c clients ready.
Fixes: adca62ec370c ("drm/bridge: anx7625: Support reading edid through aux channel") Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org Reviewed-by: Xin Ji xji@analogixsemi.com Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220706125254.2474095-4-hsiny... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/anx7625.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 0117fd8c62ae..183bd065c494 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -2656,14 +2656,6 @@ static int anx7625_i2c_probe(struct i2c_client *client, platform->aux.dev = dev; platform->aux.transfer = anx7625_aux_transfer; drm_dp_aux_init(&platform->aux); - devm_of_dp_aux_populate_ep_devices(&platform->aux); - - ret = anx7625_parse_dt(dev, pdata); - if (ret) { - if (ret != -EPROBE_DEFER) - DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret); - goto free_wq; - }
if (anx7625_register_i2c_dummy_clients(platform, client) != 0) { ret = -ENOMEM; @@ -2679,6 +2671,15 @@ static int anx7625_i2c_probe(struct i2c_client *client, if (ret) goto free_wq;
+ devm_of_dp_aux_populate_ep_devices(&platform->aux); + + ret = anx7625_parse_dt(dev, pdata); + if (ret) { + if (ret != -EPROBE_DEFER) + DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret); + goto free_wq; + } + if (!platform->pdata.low_power_mode) { anx7625_disable_pd_protocol(platform); pm_runtime_get_sync(dev);
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 6694482a70e9536efbf2ac233cbf0c302d6e2dae ]
From testing on sc7180-trogdor devices, reading the GMU registers
needs the GMU clocks to be enabled. Those clocks get turned on in a6xx_gmu_resume(). Confusingly enough, that function is called as a result of the runtime_pm of the GPU "struct device", not the GMU "struct device". Unfortunately the current a6xx_gpu_busy() grabs a reference to the GMU's "struct device".
The fact that we were grabbing the wrong reference was easily seen to cause crashes that happen if we change the GPU's pm_runtime usage to not use autosuspend. It's also believed to cause some long tail GPU crashes even with autosuspend.
We could look at changing it so that we do pm_runtime_get_if_in_use() on the GPU's "struct device", but then we run into a different problem. pm_runtime_get_if_in_use() will return 0 for the GPU's "struct device" the whole time when we're in the "autosuspend delay". That is, when we drop the last reference to the GPU but we're waiting a period before actually suspending then we'll think the GPU is off. One reason that's bad is that if the GPU didn't actually turn off then the cycle counter doesn't lose state and that throws off all of our calculations.
Let's change the code to keep track of the suspend state of devfreq. msm_devfreq_suspend() is always called before we actually suspend the GPU and msm_devfreq_resume() after we resume it. This means we can use the suspended state to know if we're powered or not.
NOTE: one might wonder when exactly our status function is called when devfreq is supposed to be disabled. The stack crawl I captured was: msm_devfreq_get_dev_status devfreq_simple_ondemand_func devfreq_update_target qos_notifier_call qos_max_notifier_call blocking_notifier_call_chain pm_qos_update_target freq_qos_apply apply_constraint __dev_pm_qos_update_request dev_pm_qos_update_request msm_devfreq_idle_work
Fixes: eadf79286a4b ("drm/msm: Check for powered down HW in the devfreq callbacks") Signed-off-by: Douglas Anderson dianders@chromium.org Reviewed-by: Rob Clark robdclark@gmail.com Patchwork: https://patchwork.freedesktop.org/patch/489124/ Link: https://lore.kernel.org/r/20220610124639.v4.1.Ie846c5352bc307ee4248d7cab998a... Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 ------ drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 13 ++++----- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 12 +++------ drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 3 ++- drivers/gpu/drm/msm/msm_gpu.h | 11 +++++++- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 39 +++++++++++++++++++++------ 6 files changed, 53 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index c424e9a37669..3dcec7acb384 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1666,18 +1666,10 @@ static u64 a5xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate) { u64 busy_cycles;
- /* Only read the gpu busy if the hardware is already active */ - if (pm_runtime_get_if_in_use(&gpu->pdev->dev) == 0) { - *out_sample_rate = 1; - return 0; - } - busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO, REG_A5XX_RBBM_PERFCTR_RBBM_0_HI); *out_sample_rate = clk_get_rate(gpu->core_clk);
- pm_runtime_put(&gpu->pdev->dev); - return busy_cycles; }
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 9f76f5b15759..dc715d88ff21 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -102,7 +102,8 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu) A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF)); }
-void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp) +void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp, + bool suspended) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); @@ -127,15 +128,16 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
/* * This can get called from devfreq while the hardware is idle. Don't - * bring up the power if it isn't already active + * bring up the power if it isn't already active. All we're doing here + * is updating the frequency so that when we come back online we're at + * the right rate. */ - if (pm_runtime_get_if_in_use(gmu->dev) == 0) + if (suspended) return;
if (!gmu->legacy) { a6xx_hfi_set_freq(gmu, perf_index); dev_pm_opp_set_opp(&gpu->pdev->dev, opp); - pm_runtime_put(gmu->dev); return; }
@@ -159,7 +161,6 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp) dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
dev_pm_opp_set_opp(&gpu->pdev->dev, opp); - pm_runtime_put(gmu->dev); }
unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu) @@ -895,7 +896,7 @@ static void a6xx_gmu_set_initial_freq(struct msm_gpu *gpu, struct a6xx_gmu *gmu) return;
gmu->freq = 0; /* so a6xx_gmu_set_freq() doesn't exit early */ - a6xx_gmu_set_freq(gpu, gpu_opp); + a6xx_gmu_set_freq(gpu, gpu_opp, false); dev_pm_opp_put(gpu_opp); }
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 42ed9a3c4905..8c02a67f29f2 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1658,27 +1658,21 @@ static u64 a6xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate) /* 19.2MHz */ *out_sample_rate = 19200000;
- /* Only read the gpu busy if the hardware is already active */ - if (pm_runtime_get_if_in_use(a6xx_gpu->gmu.dev) == 0) - return 0; - busy_cycles = gmu_read64(&a6xx_gpu->gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H);
- - pm_runtime_put(a6xx_gpu->gmu.dev); - return busy_cycles; }
-static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp) +static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp, + bool suspended) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
mutex_lock(&a6xx_gpu->gmu.lock); - a6xx_gmu_set_freq(gpu, opp); + a6xx_gmu_set_freq(gpu, opp, suspended); mutex_unlock(&a6xx_gpu->gmu.lock); }
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index 86e0a7c3fe6d..ab853f61db63 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -77,7 +77,8 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state); int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node); void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu);
-void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp); +void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp, + bool suspended); unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu);
void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state, diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 6def00883046..31269c1c896b 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -64,11 +64,14 @@ struct msm_gpu_funcs { /* for generation specific debugfs: */ void (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor); #endif + /* note: gpu_busy() can assume that we have been pm_resumed */ u64 (*gpu_busy)(struct msm_gpu *gpu, unsigned long *out_sample_rate); struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu); int (*gpu_state_put)(struct msm_gpu_state *state); unsigned long (*gpu_get_freq)(struct msm_gpu *gpu); - void (*gpu_set_freq)(struct msm_gpu *gpu, struct dev_pm_opp *opp); + /* note: gpu_set_freq() can assume that we have been pm_resumed */ + void (*gpu_set_freq)(struct msm_gpu *gpu, struct dev_pm_opp *opp, + bool suspended); struct msm_gem_address_space *(*create_address_space) (struct msm_gpu *gpu, struct platform_device *pdev); struct msm_gem_address_space *(*create_private_address_space) @@ -92,6 +95,9 @@ struct msm_gpu_devfreq { /** devfreq: devfreq instance */ struct devfreq *devfreq;
+ /** lock: lock for "suspended", "busy_cycles", and "time" */ + struct mutex lock; + /** * idle_constraint: * @@ -135,6 +141,9 @@ struct msm_gpu_devfreq { * elapsed */ struct msm_hrtimer_work boost_work; + + /** suspended: tracks if we're suspended */ + bool suspended; };
struct msm_gpu { diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index d2539ca78c29..ea94bc18e72e 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -20,6 +20,7 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, u32 flags) { struct msm_gpu *gpu = dev_to_gpu(dev); + struct msm_gpu_devfreq *df = &gpu->devfreq; struct dev_pm_opp *opp;
/* @@ -32,10 +33,13 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq,
trace_msm_gpu_freq_change(dev_pm_opp_get_freq(opp));
- if (gpu->funcs->gpu_set_freq) - gpu->funcs->gpu_set_freq(gpu, opp); - else + if (gpu->funcs->gpu_set_freq) { + mutex_lock(&df->lock); + gpu->funcs->gpu_set_freq(gpu, opp, df->suspended); + mutex_unlock(&df->lock); + } else { clk_set_rate(gpu->core_clk, *freq); + }
dev_pm_opp_put(opp);
@@ -58,15 +62,24 @@ static void get_raw_dev_status(struct msm_gpu *gpu, unsigned long sample_rate; ktime_t time;
+ mutex_lock(&df->lock); + status->current_frequency = get_freq(gpu); - busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate); time = ktime_get(); - - busy_time = busy_cycles - df->busy_cycles; status->total_time = ktime_us_delta(time, df->time); + df->time = time;
+ if (df->suspended) { + mutex_unlock(&df->lock); + status->busy_time = 0; + return; + } + + busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate); + busy_time = busy_cycles - df->busy_cycles; df->busy_cycles = busy_cycles; - df->time = time; + + mutex_unlock(&df->lock);
busy_time *= USEC_PER_SEC; do_div(busy_time, sample_rate); @@ -175,6 +188,8 @@ void msm_devfreq_init(struct msm_gpu *gpu) if (!gpu->funcs->gpu_busy) return;
+ mutex_init(&df->lock); + dev_pm_qos_add_request(&gpu->pdev->dev, &df->idle_freq, DEV_PM_QOS_MAX_FREQUENCY, PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE); @@ -244,12 +259,16 @@ void msm_devfreq_cleanup(struct msm_gpu *gpu) void msm_devfreq_resume(struct msm_gpu *gpu) { struct msm_gpu_devfreq *df = &gpu->devfreq; + unsigned long sample_rate;
if (!has_devfreq(gpu)) return;
- df->busy_cycles = 0; + mutex_lock(&df->lock); + df->busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate); df->time = ktime_get(); + df->suspended = false; + mutex_unlock(&df->lock);
devfreq_resume_device(df->devfreq); } @@ -261,6 +280,10 @@ void msm_devfreq_suspend(struct msm_gpu *gpu) if (!has_devfreq(gpu)) return;
+ mutex_lock(&df->lock); + df->suspended = true; + mutex_unlock(&df->lock); + devfreq_suspend_device(df->devfreq);
cancel_idle_work(df);
From: Yixun Lan dlan@gentoo.org
[ Upstream commit 935dc35c75318fa213d26808ad8bb130fb0b486e ]
According to the RISC-V calling convention register usage here [0], a0 is used as return value register, so rename it to make it consistent with the spec.
[0] section 18.2, table 18.2 https://riscv.org/wp-content/uploads/2015/01/riscv-calling.pdf
Fixes: 589fed479ba1 ("riscv, libbpf: Add RISC-V (RV64) support to bpf_tracing.h") Signed-off-by: Yixun Lan dlan@gentoo.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Björn Töpel bjorn@kernel.org Acked-by: Amjad OULED-AMEUR ouledameur.amjad@gmail.com Link: https://lore.kernel.org/bpf/20220706140204.47926-1-dlan@gentoo.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/bpf_tracing.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/lib/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h index 01ce121c302d..11f9096407fc 100644 --- a/tools/lib/bpf/bpf_tracing.h +++ b/tools/lib/bpf/bpf_tracing.h @@ -233,7 +233,7 @@ struct pt_regs___arm64 { #define __PT_PARM5_REG a4 #define __PT_RET_REG ra #define __PT_FP_REG s0 -#define __PT_RC_REG a5 +#define __PT_RC_REG a0 #define __PT_SP_REG sp #define __PT_IP_REG pc /* riscv does not select ARCH_HAS_SYSCALL_WRAPPER. */
From: Rob Clark robdclark@chromium.org
[ Upstream commit 92ef86ab513593c6329d04146e61f9a670e72fc5 ]
We need to grab the lock after the early return for !hwpipe case. Otherwise, we could have hit contention yet still returned 0.
Fixes an issue that the new CONFIG_DRM_DEBUG_MODESET_LOCK stuff flagged in CI:
WARNING: CPU: 0 PID: 282 at drivers/gpu/drm/drm_modeset_lock.c:296 drm_modeset_lock+0xf8/0x154 Modules linked in: CPU: 0 PID: 282 Comm: kms_cursor_lega Tainted: G W 5.19.0-rc2-15930-g875cc8bc536a #1 Hardware name: Qualcomm Technologies, Inc. DB820c (DT) pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : drm_modeset_lock+0xf8/0x154 lr : drm_atomic_get_private_obj_state+0x84/0x170 sp : ffff80000cfab6a0 x29: ffff80000cfab6a0 x28: 0000000000000000 x27: ffff000083bc4d00 x26: 0000000000000038 x25: 0000000000000000 x24: ffff80000957ca58 x23: 0000000000000000 x22: ffff000081ace080 x21: 0000000000000001 x20: ffff000081acec18 x19: ffff80000cfabb80 x18: 0000000000000038 x17: 0000000000000000 x16: 0000000000000000 x15: fffffffffffea0d0 x14: 0000000000000000 x13: 284e4f5f4e524157 x12: 5f534b434f4c5f47 x11: ffff80000a386aa8 x10: 0000000000000029 x9 : ffff80000cfab610 x8 : 0000000000000029 x7 : 0000000000000014 x6 : 0000000000000000 x5 : 0000000000000001 x4 : ffff8000081ad904 x3 : 0000000000000029 x2 : ffff0000801db4c0 x1 : ffff80000cfabb80 x0 : ffff000081aceb58 Call trace: drm_modeset_lock+0xf8/0x154 drm_atomic_get_private_obj_state+0x84/0x170 mdp5_get_global_state+0x54/0x6c mdp5_pipe_release+0x2c/0xd4 mdp5_plane_atomic_check+0x2ec/0x414 drm_atomic_helper_check_planes+0xd8/0x210 drm_atomic_helper_check+0x54/0xb0 ... ---[ end trace 0000000000000000 ]--- drm_modeset_lock attempting to lock a contended lock without backoff: drm_modeset_lock+0x148/0x154 mdp5_get_global_state+0x30/0x6c mdp5_pipe_release+0x2c/0xd4 mdp5_plane_atomic_check+0x290/0x414 drm_atomic_helper_check_planes+0xd8/0x210 drm_atomic_helper_check+0x54/0xb0 drm_atomic_check_only+0x4b0/0x8f4 drm_atomic_commit+0x68/0xe0
Fixes: d59be579fa93 ("drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is detected") Signed-off-by: Rob Clark robdclark@chromium.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Patchwork: https://patchwork.freedesktop.org/patch/492701/ Link: https://lore.kernel.org/r/20220707162040.1594855-1-robdclark@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c index a4f5cb90f3e8..e4b8a789835a 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c @@ -123,12 +123,13 @@ int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) { struct msm_drm_private *priv = s->dev->dev_private; struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); - struct mdp5_global_state *state = mdp5_get_global_state(s); + struct mdp5_global_state *state; struct mdp5_hw_pipe_state *new_state;
if (!hwpipe) return 0;
+ state = mdp5_get_global_state(s); if (IS_ERR(state)) return PTR_ERR(state);
From: Mateusz Jończyk mat.jonczyk@o2.pl
[ Upstream commit 9da2902609f7519c48eda84f953f72fee53f2b71 ]
I was getting the following message on boot on Linux 5.19-rc5: radeon 0000:01:05.0: vram limit (0) must be a power of 2 (I didn't use any radeon.vramlimit commandline parameter).
This is caused by commit 8c2d34eb53b9 ("drm/radeon: use kernel is_power_of_2 rather than local version") which removed radeon_check_pot_argument() and converted its users to is_power_of_2(). The two functions differ in its handling of 0, which is the default value of radeon_vram_limit: radeon_check_pot_argument() "incorrectly" considered it a power of 2, while is_power_of_2() does not.
An appropriate conditional silences the warning message.
It is not necessary to add a similar test to other callers of is_power_of_2() in radeon_device.c. The matching commit in amdgpu: commit 761175078466 ("drm/amdgpu: use kernel is_power_of_2 rather than local version") is unaffected by this bug.
Tested on Radeon HD 3200.
Not ccing stable, this is not serious enough.
Fixes: 8c2d34eb53b9 ("drm/radeon: use kernel is_power_of_2 rather than local version") Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: "Pan, Xinhui" Xinhui.Pan@amd.com Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: Jonathan Gray jsg@jsg.id.au Signed-off-by: Mateusz Jończyk mat.jonczyk@o2.pl Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/radeon/radeon_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 15692cb241fc..429644d5ddc6 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1113,7 +1113,7 @@ static int radeon_gart_size_auto(enum radeon_family family) static void radeon_check_arguments(struct radeon_device *rdev) { /* vramlimit must be a power of two */ - if (!is_power_of_2(radeon_vram_limit)) { + if (radeon_vram_limit != 0 && !is_power_of_2(radeon_vram_limit)) { dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n", radeon_vram_limit); radeon_vram_limit = 0;
From: Zhengchao Shao shaozhengchao@huawei.com
[ Upstream commit 02884a4f12de11f54d4ca67a07dd1f111d96fdbd ]
When kunpeng920 encryption driver is used to deencrypt and decrypt packets during the softirq, it is not allowed to use mutex lock. The kernel will report the following error:
BUG: scheduling while atomic: swapper/57/0/0x00000300 Call trace: dump_backtrace+0x0/0x1e4 show_stack+0x20/0x2c dump_stack+0xd8/0x140 __schedule_bug+0x68/0x80 __schedule+0x728/0x840 schedule+0x50/0xe0 schedule_preempt_disabled+0x18/0x24 __mutex_lock.constprop.0+0x594/0x5dc __mutex_lock_slowpath+0x1c/0x30 mutex_lock+0x50/0x60 sec_request_init+0x8c/0x1a0 [hisi_sec2] sec_process+0x28/0x1ac [hisi_sec2] sec_skcipher_crypto+0xf4/0x1d4 [hisi_sec2] sec_skcipher_encrypt+0x1c/0x30 [hisi_sec2] crypto_skcipher_encrypt+0x2c/0x40 crypto_authenc_encrypt+0xc8/0xfc [authenc] crypto_aead_encrypt+0x2c/0x40 echainiv_encrypt+0x144/0x1a0 [echainiv] crypto_aead_encrypt+0x2c/0x40 esp_output_tail+0x348/0x5c0 [esp4] esp_output+0x120/0x19c [esp4] xfrm_output_one+0x25c/0x4d4 xfrm_output_resume+0x6c/0x1fc xfrm_output+0xac/0x3c0 xfrm4_output+0x64/0x130 ip_build_and_send_pkt+0x158/0x20c tcp_v4_send_synack+0xdc/0x1f0 tcp_conn_request+0x7d0/0x994 tcp_v4_conn_request+0x58/0x6c tcp_v6_conn_request+0xf0/0x100 tcp_rcv_state_process+0x1cc/0xd60 tcp_v4_do_rcv+0x10c/0x250 tcp_v4_rcv+0xfc4/0x10a4 ip_protocol_deliver_rcu+0xf4/0x200 ip_local_deliver_finish+0x58/0x70 ip_local_deliver+0x68/0x120 ip_sublist_rcv_finish+0x70/0x94 ip_list_rcv_finish.constprop.0+0x17c/0x1d0 ip_sublist_rcv+0x40/0xb0 ip_list_rcv+0x140/0x1dc __netif_receive_skb_list_core+0x154/0x28c __netif_receive_skb_list+0x120/0x1a0 netif_receive_skb_list_internal+0xe4/0x1f0 napi_complete_done+0x70/0x1f0 gro_cell_poll+0x9c/0xb0 napi_poll+0xcc/0x264 net_rx_action+0xd4/0x21c __do_softirq+0x130/0x358 irq_exit+0x11c/0x13c __handle_domain_irq+0x88/0xf0 gic_handle_irq+0x78/0x2c0 el1_irq+0xb8/0x140 arch_cpu_idle+0x18/0x40 default_idle_call+0x5c/0x1c0 cpuidle_idle_call+0x174/0x1b0 do_idle+0xc8/0x160 cpu_startup_entry+0x30/0x11c secondary_start_kernel+0x158/0x1e4 softirq: huh, entered softirq 3 NET_RX 0000000093774ee4 with preempt_count 00000100, exited with fffffe00?
Fixes: 416d82204df4 ("crypto: hisilicon - add HiSilicon SEC V2 driver") Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/hisilicon/sec2/sec.h | 2 +- drivers/crypto/hisilicon/sec2/sec_crypto.c | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h index c2e9b01187a7..a44c8dba3cda 100644 --- a/drivers/crypto/hisilicon/sec2/sec.h +++ b/drivers/crypto/hisilicon/sec2/sec.h @@ -119,7 +119,7 @@ struct sec_qp_ctx { struct idr req_idr; struct sec_alg_res res[QM_Q_DEPTH]; struct sec_ctx *ctx; - struct mutex req_lock; + spinlock_t req_lock; struct list_head backlog; struct hisi_acc_sgl_pool *c_in_pool; struct hisi_acc_sgl_pool *c_out_pool; diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c index 6eebe739893c..71dfa7db6394 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -127,11 +127,11 @@ static int sec_alloc_req_id(struct sec_req *req, struct sec_qp_ctx *qp_ctx) { int req_id;
- mutex_lock(&qp_ctx->req_lock); + spin_lock_bh(&qp_ctx->req_lock);
req_id = idr_alloc_cyclic(&qp_ctx->req_idr, NULL, 0, QM_Q_DEPTH, GFP_ATOMIC); - mutex_unlock(&qp_ctx->req_lock); + spin_unlock_bh(&qp_ctx->req_lock); if (unlikely(req_id < 0)) { dev_err(req->ctx->dev, "alloc req id fail!\n"); return req_id; @@ -156,9 +156,9 @@ static void sec_free_req_id(struct sec_req *req) qp_ctx->req_list[req_id] = NULL; req->qp_ctx = NULL;
- mutex_lock(&qp_ctx->req_lock); + spin_lock_bh(&qp_ctx->req_lock); idr_remove(&qp_ctx->req_idr, req_id); - mutex_unlock(&qp_ctx->req_lock); + spin_unlock_bh(&qp_ctx->req_lock); }
static u8 pre_parse_finished_bd(struct bd_status *status, void *resp) @@ -273,7 +273,7 @@ static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req) !(req->flag & CRYPTO_TFM_REQ_MAY_BACKLOG)) return -EBUSY;
- mutex_lock(&qp_ctx->req_lock); + spin_lock_bh(&qp_ctx->req_lock); ret = hisi_qp_send(qp_ctx->qp, &req->sec_sqe);
if (ctx->fake_req_limit <= @@ -281,10 +281,10 @@ static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req) list_add_tail(&req->backlog_head, &qp_ctx->backlog); atomic64_inc(&ctx->sec->debug.dfx.send_cnt); atomic64_inc(&ctx->sec->debug.dfx.send_busy_cnt); - mutex_unlock(&qp_ctx->req_lock); + spin_unlock_bh(&qp_ctx->req_lock); return -EBUSY; } - mutex_unlock(&qp_ctx->req_lock); + spin_unlock_bh(&qp_ctx->req_lock);
if (unlikely(ret == -EBUSY)) return -ENOBUFS; @@ -487,7 +487,7 @@ static int sec_create_qp_ctx(struct hisi_qm *qm, struct sec_ctx *ctx,
qp->req_cb = sec_req_cb;
- mutex_init(&qp_ctx->req_lock); + spin_lock_init(&qp_ctx->req_lock); idr_init(&qp_ctx->req_idr); INIT_LIST_HEAD(&qp_ctx->backlog);
@@ -1382,7 +1382,7 @@ static struct sec_req *sec_back_req_clear(struct sec_ctx *ctx, { struct sec_req *backlog_req = NULL;
- mutex_lock(&qp_ctx->req_lock); + spin_lock_bh(&qp_ctx->req_lock); if (ctx->fake_req_limit >= atomic_read(&qp_ctx->qp->qp_status.used) && !list_empty(&qp_ctx->backlog)) { @@ -1390,7 +1390,7 @@ static struct sec_req *sec_back_req_clear(struct sec_ctx *ctx, typeof(*backlog_req), backlog_head); list_del(&backlog_req->backlog_head); } - mutex_unlock(&qp_ctx->req_lock); + spin_unlock_bh(&qp_ctx->req_lock);
return backlog_req; }
From: Zhengchao Shao shaozhengchao@huawei.com
[ Upstream commit 68740ab505431f268dc1ee26a54b871e75f0ddaa ]
When kunpeng916 encryption driver is used to deencrypt and decrypt packets during the softirq, it is not allowed to use mutex lock.
Fixes: 915e4e8413da ("crypto: hisilicon - SEC security accelerator driver") Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/hisilicon/sec/sec_algs.c | 14 +++++++------- drivers/crypto/hisilicon/sec/sec_drv.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/crypto/hisilicon/sec/sec_algs.c b/drivers/crypto/hisilicon/sec/sec_algs.c index 0a3c8f019b02..490e1542305e 100644 --- a/drivers/crypto/hisilicon/sec/sec_algs.c +++ b/drivers/crypto/hisilicon/sec/sec_algs.c @@ -449,7 +449,7 @@ static void sec_skcipher_alg_callback(struct sec_bd_info *sec_resp, */ }
- mutex_lock(&ctx->queue->queuelock); + spin_lock_bh(&ctx->queue->queuelock); /* Put the IV in place for chained cases */ switch (ctx->cipher_alg) { case SEC_C_AES_CBC_128: @@ -509,7 +509,7 @@ static void sec_skcipher_alg_callback(struct sec_bd_info *sec_resp, list_del(&backlog_req->backlog_head); } } - mutex_unlock(&ctx->queue->queuelock); + spin_unlock_bh(&ctx->queue->queuelock);
mutex_lock(&sec_req->lock); list_del(&sec_req_el->head); @@ -798,7 +798,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, */
/* Grab a big lock for a long time to avoid concurrency issues */ - mutex_lock(&queue->queuelock); + spin_lock_bh(&queue->queuelock);
/* * Can go on to queue if we have space in either: @@ -814,15 +814,15 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, ret = -EBUSY; if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { list_add_tail(&sec_req->backlog_head, &ctx->backlog); - mutex_unlock(&queue->queuelock); + spin_unlock_bh(&queue->queuelock); goto out; }
- mutex_unlock(&queue->queuelock); + spin_unlock_bh(&queue->queuelock); goto err_free_elements; } ret = sec_send_request(sec_req, queue); - mutex_unlock(&queue->queuelock); + spin_unlock_bh(&queue->queuelock); if (ret) goto err_free_elements;
@@ -881,7 +881,7 @@ static int sec_alg_skcipher_init(struct crypto_skcipher *tfm) if (IS_ERR(ctx->queue)) return PTR_ERR(ctx->queue);
- mutex_init(&ctx->queue->queuelock); + spin_lock_init(&ctx->queue->queuelock); ctx->queue->havesoftqueue = false;
return 0; diff --git a/drivers/crypto/hisilicon/sec/sec_drv.h b/drivers/crypto/hisilicon/sec/sec_drv.h index 179a8250d691..e2a50bf2234b 100644 --- a/drivers/crypto/hisilicon/sec/sec_drv.h +++ b/drivers/crypto/hisilicon/sec/sec_drv.h @@ -347,7 +347,7 @@ struct sec_queue { DECLARE_BITMAP(unprocessed, SEC_QUEUE_LEN); DECLARE_KFIFO_PTR(softqueue, typeof(struct sec_request_el *)); bool havesoftqueue; - struct mutex queuelock; + spinlock_t queuelock; void *shadow[SEC_QUEUE_LEN]; };
From: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com
[ Upstream commit ab14c99c035da7156a3b66fa171171295bc4b89a ]
The mdp_ipi_comm structure defines a command that is either PROCESS (start processing) or DEINIT (destroy instance); we are using this one to send PROCESS or DEINIT commands from Linux to an MDP instance through a VPU write but, while the first wants us to stay 4-bytes aligned, the VPU instead requires an 8-bytes data alignment.
Keeping in mind that these commands are executed immediately after sending them (hence not chained with others before the VPU/MDP "actually" start executing), it is fine to simply add a padding of 4 bytes to this structure: this keeps the same performance as before, as we're still stack-allocating it, while avoiding hackery inside of mtk-vpu to ensure alignment bringing a definitely bigger performance impact.
Fixes: c8eb2d7e8202 ("[media] media: Add Mediatek MDP Driver") Signed-off-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Houlong Wei houlong.wei@mediatek.com Reviewed-by: Irui Wang irui.wang@mediatek.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h b/drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h index 2cb8cecb3077..b810c96695c8 100644 --- a/drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h +++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h @@ -40,12 +40,14 @@ struct mdp_ipi_init { * @ipi_id : IPI_MDP * @ap_inst : AP mtk_mdp_vpu address * @vpu_inst_addr : VPU MDP instance address + * @padding : Alignment padding */ struct mdp_ipi_comm { uint32_t msg_id; uint32_t ipi_id; uint64_t ap_inst; uint32_t vpu_inst_addr; + uint32_t padding; };
/**
From: Ming Qian ming.qian@nxp.com
[ Upstream commit a621cc4bed97e49f5a8019f5215dec7e208a7c4d ]
In reset vpu core, driver will wait for a response event, but if there are still some events unhandled, they will be handled first, driver may acquire core lock for that. So if we do reset in core lock, it may led to reset timeout.
Fixes: 9f599f351e86a ("media: amphion: add vpu core driver") Signed-off-by: Ming Qian ming.qian@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/amphion/vpu_core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c index 68ad183925fd..51a764713159 100644 --- a/drivers/media/platform/amphion/vpu_core.c +++ b/drivers/media/platform/amphion/vpu_core.c @@ -455,8 +455,13 @@ int vpu_inst_unregister(struct vpu_inst *inst) } vpu_core_check_hang(core); if (core->state == VPU_CORE_HANG && !core->instance_mask) { + int err; + dev_info(core->dev, "reset hang core\n"); - if (!vpu_core_sw_reset(core)) { + mutex_unlock(&core->lock); + err = vpu_core_sw_reset(core); + mutex_lock(&core->lock); + if (!err) { core->state = VPU_CORE_ACTIVE; core->hang_mask = 0; }
From: Rob Clark robdclark@chromium.org
[ Upstream commit cb77085b1f0a86ef9dfba86b5f3ed6c3340c2ea3 ]
Fixes `kms_cursor_crc --run-subtest cursor-offscreen`.. when the cursor moves offscreen the plane becomes non-visible, so we need to skip over it in crtc atomic test and mixer setup.
Signed-off-by: Rob Clark robdclark@chromium.org Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Patchwork: https://patchwork.freedesktop.org/patch/492819/ Link: https://lore.kernel.org/r/20220707212003.1710163-1-robdclark@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index b56f777dbd0e..4c5c1f627cb8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -361,6 +361,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, if (!state) continue;
+ if (!state->visible) + continue; + pstate = to_dpu_plane_state(state); fb = state->fb;
@@ -1134,6 +1137,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, if (cnt >= DPU_STAGE_MAX * 4) continue;
+ if (!pstate->visible) + continue; + pstates[cnt].dpu_pstate = dpu_pstate; pstates[cnt].drm_pstate = pstate; pstates[cnt].stage = pstate->normalized_zpos;
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit a3b36a8ce3d0c277fe243fa1be6bd3f606ed130f ]
The gcc is warning about returning a pointer to a local variable is a false positive.
The type of handle is "struct ia_css_rmgr_vbuf_handle **" and "h.vptr" is left to NULL, so the "if ((*handle)->vptr == 0x0)" check always succeeds when the "*handle = &h;" statement which gcc warns about executes. Leading to this statement being executed:
rmgr_pop_handle(pool, handle);
If that succeeds, then *handle has been set to point to one of the pre-allocated array of handles, so it no longer points to h.
If that fails the following statement will be executed:
/* Note that handle will change to an internally maintained one */ ia_css_rmgr_refcount_retain_vbuf(handle);
Which allocated a new handle from the array of pre-allocated handles and then makes *handle point to this. So the address of h is actually never returned.
The fix for the false-postive compiler warning actually breaks the code, the new:
**handle = h;
is part of a "if (pool->copy_on_write) { ... }" which means that the handle where *handle points to should be treated read-only, IOW **handle must never be set, instead *handle must be set to point to a new handle (with a copy of the contents of the old handle).
The old code correctly did this and the new fixed code gets this wrong.
Note there is another patch in this series, which fixes the warning in another way.
Link: https://lore.kernel.org/linux-media/20220612160556.108264-2-hdegoede@redhat.... Fixes: fa1451374ebf ("media: atomisp: don't pass a pointer to a local variable") 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 --- .../staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c index 39604752785b..d96aaa4bc75d 100644 --- a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c +++ b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c @@ -254,7 +254,7 @@ void rmgr_pop_handle(struct ia_css_rmgr_vbuf_pool *pool, void ia_css_rmgr_acq_vbuf(struct ia_css_rmgr_vbuf_pool *pool, struct ia_css_rmgr_vbuf_handle **handle) { - struct ia_css_rmgr_vbuf_handle h = { 0 }; + struct ia_css_rmgr_vbuf_handle h;
if ((!pool) || (!handle) || (!*handle)) { IA_CSS_LOG("Invalid inputs"); @@ -272,7 +272,7 @@ void ia_css_rmgr_acq_vbuf(struct ia_css_rmgr_vbuf_pool *pool, h.size = (*handle)->size; /* release ref to current buffer */ ia_css_rmgr_refcount_release_vbuf(handle); - **handle = h; + *handle = &h; } /* get new buffer for needed size */ if ((*handle)->vptr == 0x0) {
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit f1748f8f8174a65a885a8e6c0dc11658a6705ac2 ]
This partially reverts commit b018be06f3c7 ("media: mediatek: vcodec: Read max resolution from dec_capability"). In this commit, the maximum resolution ended up being a function of both the firmware capability and the current set format.
However, frame size enumeration for output (coded) formats should not depend on the format set, but should return supported resolutions for the format requested by userspace.
Fix this so that the driver returns the supported resolutions correctly, even if the instance only has default settings, or if the output format is currently set to VP8F, which does not support 4K.
This adds an copy of special casing for !VP8 and 4K support. The other existing copy will be removed when .max_{width,height} are removed from |struct mtk_vcodec_ctx| in a subsequent patch.
Fixes: b018be06f3c7 ("media: mediatek: vcodec: Read max resolution from dec_capability") Signed-off-by: Chen-Yu Tsai wenst@chromium.org Tested-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c | 2 -- .../platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c | 7 +++++++ 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c index 01836a1c7d3f..393b127138f3 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c @@ -536,8 +536,6 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; fsize->stepwise = dec_pdata->vdec_framesizes[i].stepwise;
- fsize->stepwise.max_width = ctx->max_width; - fsize->stepwise.max_height = ctx->max_height; mtk_v4l2_debug(1, "%x, %d %d %d %d %d %d", ctx->dev->dec_capability, fsize->stepwise.min_width, diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c index 16d55785d84b..9a4d3e3658aa 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c @@ -360,6 +360,13 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
mtk_vdec_framesizes[count_framesizes].fourcc = fourcc; mtk_vdec_framesizes[count_framesizes].stepwise = stepwise_fhd; + if (!(ctx->dev->dec_capability & VCODEC_CAPABILITY_4K_DISABLED) && + fourcc != V4L2_PIX_FMT_VP8_FRAME) { + mtk_vdec_framesizes[count_framesizes].stepwise.max_width = + VCODEC_DEC_4K_CODED_WIDTH; + mtk_vdec_framesizes[count_framesizes].stepwise.max_height = + VCODEC_DEC_4K_CODED_HEIGHT; + } num_framesizes++; break; case V4L2_PIX_FMT_MM21:
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit d7abd054201377aa441411ca081bd903fba82ce0 ]
In commit b018be06f3c7 ("media: mediatek: vcodec: Read max resolution from dec_capability"), TRY_FMT clamps the resolution to the maximum that was previously set either by default 1080p or the limit set by a previous S_FMT call. This does not make sense when doing TRY_FMT for the output side, which may have different capabilities.
Instead, for the output side, find the maximum resolution based on the pixel format requested. For the capture side, find the maximum resolution based on the currently set output format.
The maximum resolution is found from the list of per-format frame sizes, so the patch "media: mediatek: vcodec: dec: Fix 4K frame size enumeration" is needed.
Fixes: b018be06f3c7 ("media: mediatek: vcodec: Read max resolution from dec_capability") Signed-off-by: Chen-Yu Tsai wenst@chromium.org Tested-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../platform/mediatek/vcodec/mtk_vcodec_dec.c | 48 ++++++++++++++----- 1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c index 393b127138f3..42b29f0a7436 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c @@ -211,17 +211,44 @@ static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh, } }
+static const struct v4l2_frmsize_stepwise *mtk_vdec_get_frmsize(struct mtk_vcodec_ctx *ctx, + u32 pixfmt) +{ + const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata; + int i; + + for (i = 0; i < *dec_pdata->num_framesizes; ++i) + if (pixfmt == dec_pdata->vdec_framesizes[i].fourcc) + return &dec_pdata->vdec_framesizes[i].stepwise; + + /* + * This should never happen since vidioc_try_fmt_vid_out_mplane() + * always passes through a valid format for the output side, and + * for the capture side, a valid output format should already have + * been set. + */ + WARN_ONCE(1, "Unsupported format requested.\n"); + return &dec_pdata->vdec_framesizes[0].stepwise; +} + static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f, const struct mtk_video_fmt *fmt) { struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; + const struct v4l2_frmsize_stepwise *frmsize; + u32 fourcc;
pix_fmt_mp->field = V4L2_FIELD_NONE;
- pix_fmt_mp->width = - clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, ctx->max_width); - pix_fmt_mp->height = - clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, ctx->max_height); + /* Always apply frame size constraints from the coded side */ + if (V4L2_TYPE_IS_OUTPUT(f->type)) + fourcc = f->fmt.pix_mp.pixelformat; + else + fourcc = ctx->q_data[MTK_Q_DATA_SRC].fmt->fourcc; + + frmsize = mtk_vdec_get_frmsize(ctx, fourcc); + pix_fmt_mp->width = clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, frmsize->max_width); + pix_fmt_mp->height = clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, frmsize->max_height);
if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { pix_fmt_mp->num_planes = 1; @@ -237,18 +264,15 @@ static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f, */ tmp_w = pix_fmt_mp->width; tmp_h = pix_fmt_mp->height; - v4l_bound_align_image(&pix_fmt_mp->width, - MTK_VDEC_MIN_W, - ctx->max_width, 6, - &pix_fmt_mp->height, - MTK_VDEC_MIN_H, - ctx->max_height, 6, 9); + v4l_bound_align_image(&pix_fmt_mp->width, MTK_VDEC_MIN_W, frmsize->max_width, 6, + &pix_fmt_mp->height, MTK_VDEC_MIN_H, frmsize->max_height, 6, + 9);
if (pix_fmt_mp->width < tmp_w && - (pix_fmt_mp->width + 64) <= ctx->max_width) + (pix_fmt_mp->width + 64) <= frmsize->max_width) pix_fmt_mp->width += 64; if (pix_fmt_mp->height < tmp_h && - (pix_fmt_mp->height + 64) <= ctx->max_height) + (pix_fmt_mp->height + 64) <= frmsize->max_height) pix_fmt_mp->height += 64;
mtk_v4l2_debug(0,
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit 3b6a81a31370539f1fd0e9bdd315503aa154285e ]
The default resolution of 64x64 is already aligned, according to the call to v4l_bound_align_image() in mtk_vcodec_dec_set_default_params().
Drop the redundant v4l_bound_align_image() call. This also removes one usage of ctx->max_{width,height}.
Signed-off-by: Chen-Yu Tsai wenst@chromium.org Tested-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c index 42b29f0a7436..7d654efabdfe 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c @@ -142,13 +142,6 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx) ctx->max_width = MTK_VDEC_MAX_W; ctx->max_height = MTK_VDEC_MAX_H;
- v4l_bound_align_image(&q_data->coded_width, - MTK_VDEC_MIN_W, - ctx->max_width, 4, - &q_data->coded_height, - MTK_VDEC_MIN_H, - ctx->max_height, 5, 6); - q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height; q_data->bytesperline[0] = q_data->coded_width; q_data->sizeimage[1] = q_data->sizeimage[0] / 2;
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit e8d266d533b171387945f8a0bad1944a5609f63b ]
This partially reverts commit b018be06f3c7 ("media: mediatek: vcodec: Read max resolution from dec_capability").
After the previous patches:
- media: mediatek: vcodec: decoder: Fix 4K frame size enumeration - media: mediatek: vcodec: decoder: Skip alignment for default resolution - media: mediatek: vcodec: decoder: Fix resolution clamping in TRY_FMT
the max_{width,height} fields in |struct mtk_vcodec_ctx| no longer have any real users. Remove them.
Fixes: b018be06f3c7 ("media: mediatek: vcodec: Read max resolution from dec_capability") Signed-off-by: Chen-Yu Tsai wenst@chromium.org Tested-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c | 9 --------- drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h | 4 ---- 2 files changed, 13 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c index 7d654efabdfe..af3cd2e36451 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c @@ -139,8 +139,6 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx) q_data->coded_height = DFT_CFG_HEIGHT; q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt; q_data->field = V4L2_FIELD_NONE; - ctx->max_width = MTK_VDEC_MAX_W; - ctx->max_height = MTK_VDEC_MAX_H;
q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height; q_data->bytesperline[0] = q_data->coded_width; @@ -455,13 +453,6 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, if (fmt == NULL) return -EINVAL;
- if (!(ctx->dev->dec_capability & VCODEC_CAPABILITY_4K_DISABLED) && - fmt->fourcc != V4L2_PIX_FMT_VP8_FRAME) { - mtk_v4l2_debug(3, "4K is enabled"); - ctx->max_width = VCODEC_DEC_4K_CODED_WIDTH; - ctx->max_height = VCODEC_DEC_4K_CODED_HEIGHT; - } - q_data->fmt = fmt; vidioc_try_fmt(ctx, f, q_data->fmt); if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h index a29041a0b7e0..16e91d9568e9 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h @@ -285,8 +285,6 @@ struct vdec_pic_info { * mtk_video_dec_buf. * @hw_id: hardware index used to identify different hardware. * - * @max_width: hardware supported max width - * @max_height: hardware supported max height * @msg_queue: msg queue used to store lat buffer information. */ struct mtk_vcodec_ctx { @@ -333,8 +331,6 @@ struct mtk_vcodec_ctx { struct mutex lock; int hw_id;
- unsigned int max_width; - unsigned int max_height; struct vdec_msg_queue msg_queue; };
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit fe3d651627d61210c6905339e5281d3b9db75033 ]
The decoder parameters are stored in each instance's context data. This needs to be initialized per-instance, but a previous fix incorrectly changed it to only be initialized for the first opened instance. This resulted in subsequent instances not correctly signaling the requirement for the Requests API.
Fix this by calling the initializing function outside of the v4l2_fh_is_singular() conditional block.
Fixes: faddaa735c20 ("media: mediatek: vcodec: Initialize decoder parameters after getting dec_capability") Signed-off-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: Yunfei Dong yunfei.dong@mediatek.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c index 99d7b15f2b9d..eed11a62febf 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c @@ -208,11 +208,12 @@ static int fops_vcodec_open(struct file *file)
dev->dec_capability = mtk_vcodec_fw_get_vdec_capa(dev->fw_handler); - ctx->dev->vdec_pdata->init_vdec_params(ctx);
mtk_v4l2_debug(0, "decoder capability %x", dev->dec_capability); }
+ ctx->dev->vdec_pdata->init_vdec_params(ctx); + list_add(&ctx->list, &dev->ctx_list);
mutex_unlock(&dev->dev_mutex);
From: Ming Qian ming.qian@nxp.com
[ Upstream commit afba6e20801ad9a2f863c52c21e609e021269d83 ]
Don't set last_buffer_dequeued during dynamic resolution change, otherwise it may be cleared in handling resolution change, as streamoff may be called in dynamic resolution change.
Normally, this does not happen. But we encounter a special testcase, User issue V4L2_DEC_CMD_STOP after enqueue one buffer that only contains codec config header, but not any frame data. So VPU report the parsed resolution, then report the eos event.
So driver should notify user to handle resolution change first, after it's handled, set the last_buffer_dequeued. then the user can exit decoding normally.
Otherwise the user may be stalled.
Fixes: 6de8d628df6ef ("media: amphion: add v4l2 m2m vpu decoder stateful driver") Signed-off-by: Ming Qian ming.qian@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/amphion/vdec.c | 36 ++++++++++++++--------- drivers/media/platform/amphion/vpu_v4l2.c | 2 +- 2 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c index 3c02aa2a54aa..a5bb997b000b 100644 --- a/drivers/media/platform/amphion/vdec.c +++ b/drivers/media/platform/amphion/vdec.c @@ -178,16 +178,6 @@ static int vdec_ctrl_init(struct vpu_inst *inst) return 0; }
-static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst) -{ - struct vdec_t *vdec = inst->priv; - - if (vdec->eos_received) { - if (!vpu_set_last_buffer_dequeued(inst)) - vdec->eos_received--; - } -} - static void vdec_handle_resolution_change(struct vpu_inst *inst) { struct vdec_t *vdec = inst->priv; @@ -234,6 +224,21 @@ static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state, return 0; }
+static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst) +{ + struct vdec_t *vdec = inst->priv; + + if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) + return; + + if (vdec->eos_received) { + if (!vpu_set_last_buffer_dequeued(inst)) { + vdec->eos_received--; + vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0); + } + } +} + static int vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver)); @@ -493,6 +498,8 @@ static int vdec_drain(struct vpu_inst *inst)
static int vdec_cmd_start(struct vpu_inst *inst) { + struct vdec_t *vdec = inst->priv; + switch (inst->state) { case VPU_CODEC_STATE_STARTED: case VPU_CODEC_STATE_DRAIN: @@ -503,6 +510,8 @@ static int vdec_cmd_start(struct vpu_inst *inst) break; } vpu_process_capture_buffer(inst); + if (vdec->eos_received) + vdec_set_last_buffer_dequeued(inst); return 0; }
@@ -1203,7 +1212,6 @@ static void vdec_event_eos(struct vpu_inst *inst) vdec->eos_received++; vdec->fixed_fmt = false; inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP; - vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0); vdec_set_last_buffer_dequeued(inst); vpu_inst_unlock(inst); } @@ -1480,10 +1488,10 @@ static int vdec_stop_session(struct vpu_inst *inst, u32 type) vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0); vdec->drain = 0; } else { - if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) + if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) { vdec_abort(inst); - - vdec->eos_received = 0; + vdec->eos_received = 0; + } vdec_clear_slots(inst); }
diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c index da455e5ab337..8a3eed957ae6 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.c +++ b/drivers/media/platform/amphion/vpu_v4l2.c @@ -500,8 +500,8 @@ static int vpu_vb2_start_streaming(struct vb2_queue *q, unsigned int count) fmt->sizeimage[1], fmt->bytesperline[1], fmt->sizeimage[2], fmt->bytesperline[2], q->num_buffers); - ret = call_vop(inst, start, q->type); vb2_clear_last_buffer_dequeued(q); + ret = call_vop(inst, start, q->type); if (ret) vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_QUEUED);
From: Benjamin Gaignard benjamin.gaignard@collabora.com
[ Upstream commit 135ad96cb4d6bd6dace030846fe5c7ea890411ab ]
On Hantro G2 decoder on IMX8MQ strides requirements aren't the same for NV12_4L4 and NV12 pixel formats. The first one use a 4 bytes padding while the last one needs 16 bytes. To be sure to provide the correct stride in all cases we need: - to relax the constraints on codec formats so set step_width to 4 - use capture queue format and not the output queue format when applying the pixel format constraints. - put the correct step_width constraints on each pixel format.
Move HEVC SPS validation in hantro_hevc.c to be able to perform it when setting sps control and when starting to decode the bitstream. Add a new test in HEVC SPS validation function to check if resolution is still matching the hardware constraints.
With this SAODBLK_A_MainConcept_4 and SAODBLK_B_MainConcept_4 conformance tests files are correctly decoded with both NV12 and NV12_4L4 pixel formats. These two files have a resolution of 1016x760.
Add defines for the various used resolutions. For other variants than Hantro G2 on IMX8M keep the same step_width to avoid regressions.
Fluster HEVC test score is now 128/147 vs 126/147 with the both pixel formats as decoder output. Fluster VP9 test score stay at 147/303.
[hverkuil: fix trivial checkpatch warnings]
Signed-off-by: Benjamin Gaignard benjamin.gaignard@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/hantro/hantro_drv.c | 12 +- drivers/staging/media/hantro/hantro_hevc.c | 30 +++++ drivers/staging/media/hantro/hantro_hw.h | 14 +++ drivers/staging/media/hantro/hantro_v4l2.c | 2 +- drivers/staging/media/hantro/imx8m_vpu_hw.c | 80 ++++++++++---- .../staging/media/hantro/rockchip_vpu_hw.c | 104 ++++++++++++------ .../staging/media/hantro/sama5d4_vdec_hw.c | 40 +++++-- drivers/staging/media/hantro/sunxi_vpu_hw.c | 24 +++- 8 files changed, 223 insertions(+), 83 deletions(-)
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index ac232b5f7825..01d33dcb0467 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -253,6 +253,11 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
static int hantro_try_ctrl(struct v4l2_ctrl *ctrl) { + struct hantro_ctx *ctx; + + ctx = container_of(ctrl->handler, + struct hantro_ctx, ctrl_handler); + if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) { const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
@@ -268,12 +273,7 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl) } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_SPS) { const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
- if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) - /* Luma and chroma bit depth mismatch */ - return -EINVAL; - if (sps->bit_depth_luma_minus8 != 0) - /* Only 8-bit is supported */ - return -EINVAL; + return hantro_hevc_validate_sps(ctx, sps); } else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) { const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame;
diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c index f86c98e19177..bd924896e409 100644 --- a/drivers/staging/media/hantro/hantro_hevc.c +++ b/drivers/staging/media/hantro/hantro_hevc.c @@ -154,6 +154,32 @@ static int tile_buffer_reallocate(struct hantro_ctx *ctx) return -ENOMEM; }
+int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps) +{ + if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) + /* Luma and chroma bit depth mismatch */ + return -EINVAL; + if (sps->bit_depth_luma_minus8 != 0) + /* Only 8-bit is supported */ + return -EINVAL; + + /* + * for tile pixel format check if the width and height match + * hardware constraints + */ + if (ctx->vpu_dst_fmt->fourcc == V4L2_PIX_FMT_NV12_4L4) { + if (ctx->dst_fmt.width != + ALIGN(sps->pic_width_in_luma_samples, ctx->vpu_dst_fmt->frmsize.step_width)) + return -EINVAL; + + if (ctx->dst_fmt.height != + ALIGN(sps->pic_height_in_luma_samples, ctx->vpu_dst_fmt->frmsize.step_height)) + return -EINVAL; + } + + return 0; +} + int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx) { struct hantro_hevc_dec_hw_ctx *hevc_ctx = &ctx->hevc_dec; @@ -177,6 +203,10 @@ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx) if (WARN_ON(!ctrls->sps)) return -EINVAL;
+ ret = hantro_hevc_validate_sps(ctx, ctrls->sps); + if (ret) + return ret; + ctrls->pps = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_PPS); if (WARN_ON(!ctrls->pps)) diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 52a960f6fa4a..a2e0f0836281 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -18,9 +18,21 @@ #define DEC_8190_ALIGN_MASK 0x07U
#define MB_DIM 16 +#define TILE_MB_DIM 4 #define MB_WIDTH(w) DIV_ROUND_UP(w, MB_DIM) #define MB_HEIGHT(h) DIV_ROUND_UP(h, MB_DIM)
+#define FMT_MIN_WIDTH 48 +#define FMT_MIN_HEIGHT 48 +#define FMT_HD_WIDTH 1280 +#define FMT_HD_HEIGHT 720 +#define FMT_FHD_WIDTH 1920 +#define FMT_FHD_HEIGHT 1088 +#define FMT_UHD_WIDTH 3840 +#define FMT_UHD_HEIGHT 2160 +#define FMT_4K_WIDTH 4096 +#define FMT_4K_HEIGHT 2304 + #define NUM_REF_PICTURES (V4L2_HEVC_DPB_ENTRIES_NUM_MAX + 1)
struct hantro_dev; @@ -347,6 +359,8 @@ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx); void hantro_hevc_ref_init(struct hantro_ctx *ctx); dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc); int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr); +int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps); +
static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension) { diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c index 22ad182ee972..29cc61d53b71 100644 --- a/drivers/staging/media/hantro/hantro_v4l2.c +++ b/drivers/staging/media/hantro/hantro_v4l2.c @@ -259,7 +259,7 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx, } else if (ctx->is_encoder) { vpu_fmt = ctx->vpu_dst_fmt; } else { - vpu_fmt = ctx->vpu_src_fmt; + vpu_fmt = fmt; /* * Width/height on the CAPTURE end of a decoder are ignored and * replaced by the OUTPUT ones. diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c index 9802508bade2..77f574fdfa77 100644 --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c @@ -83,6 +83,14 @@ static const struct hantro_fmt imx8m_vpu_postproc_fmts[] = { .fourcc = V4L2_PIX_FMT_YUYV, .codec_mode = HANTRO_MODE_NONE, .postprocessed = true, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = MB_DIM, + }, }, };
@@ -90,17 +98,25 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, .codec_mode = HANTRO_MODE_MPEG2_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -109,11 +125,11 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_VP8_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -122,11 +138,11 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_H264_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -137,6 +153,14 @@ static const struct hantro_fmt imx8m_vpu_g2_postproc_fmts[] = { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, .postprocessed = true, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = MB_DIM, + }, }, };
@@ -144,18 +168,26 @@ static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12_4L4, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = TILE_MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = TILE_MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_HEVC_SLICE, .codec_mode = HANTRO_MODE_HEVC_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, - .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, - .step_height = MB_DIM, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = TILE_MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = TILE_MB_DIM, }, }, { @@ -163,12 +195,12 @@ static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = { .codec_mode = HANTRO_MODE_VP9_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, - .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, - .step_height = MB_DIM, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = TILE_MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = TILE_MB_DIM, }, }, }; diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c index fc96501f3bc8..098486b9ec27 100644 --- a/drivers/staging/media/hantro/rockchip_vpu_hw.c +++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c @@ -63,6 +63,14 @@ static const struct hantro_fmt rockchip_vpu1_postproc_fmts[] = { .fourcc = V4L2_PIX_FMT_YUYV, .codec_mode = HANTRO_MODE_NONE, .postprocessed = true, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, + .step_height = MB_DIM, + }, }, };
@@ -70,17 +78,25 @@ static const struct hantro_fmt rk3066_vpu_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, + .step_height = MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_H264_SLICE, .codec_mode = HANTRO_MODE_H264_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -89,11 +105,11 @@ static const struct hantro_fmt rk3066_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_MPEG2_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -102,11 +118,11 @@ static const struct hantro_fmt rk3066_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_VP8_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -116,17 +132,25 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_4K_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_4K_HEIGHT, + .step_height = MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_H264_SLICE, .codec_mode = HANTRO_MODE_H264_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 4096, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_4K_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 2304, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_4K_HEIGHT, .step_height = MB_DIM, }, }, @@ -135,11 +159,11 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_MPEG2_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -148,11 +172,11 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_VP8_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -162,17 +186,25 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, + .step_height = MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_H264_SLICE, .codec_mode = HANTRO_MODE_H264_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -181,11 +213,11 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_MPEG2_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -194,11 +226,11 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_VP8_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, .step_height = MB_DIM, }, }, diff --git a/drivers/staging/media/hantro/sama5d4_vdec_hw.c b/drivers/staging/media/hantro/sama5d4_vdec_hw.c index b2fc1c5613e1..b205e2db5b04 100644 --- a/drivers/staging/media/hantro/sama5d4_vdec_hw.c +++ b/drivers/staging/media/hantro/sama5d4_vdec_hw.c @@ -16,6 +16,14 @@ static const struct hantro_fmt sama5d4_vdec_postproc_fmts[] = { .fourcc = V4L2_PIX_FMT_YUYV, .codec_mode = HANTRO_MODE_NONE, .postprocessed = true, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_HD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_HD_HEIGHT, + .step_height = MB_DIM, + }, }, };
@@ -23,17 +31,25 @@ static const struct hantro_fmt sama5d4_vdec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_HD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_HD_HEIGHT, + .step_height = MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, .codec_mode = HANTRO_MODE_MPEG2_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1280, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_HD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 720, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_HD_HEIGHT, .step_height = MB_DIM, }, }, @@ -42,11 +58,11 @@ static const struct hantro_fmt sama5d4_vdec_fmts[] = { .codec_mode = HANTRO_MODE_VP8_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1280, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_HD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 720, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_HD_HEIGHT, .step_height = MB_DIM, }, }, @@ -55,11 +71,11 @@ static const struct hantro_fmt sama5d4_vdec_fmts[] = { .codec_mode = HANTRO_MODE_H264_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1280, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_HD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 720, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_HD_HEIGHT, .step_height = MB_DIM, }, }, diff --git a/drivers/staging/media/hantro/sunxi_vpu_hw.c b/drivers/staging/media/hantro/sunxi_vpu_hw.c index c0edd5856a0c..fbeac81e59e1 100644 --- a/drivers/staging/media/hantro/sunxi_vpu_hw.c +++ b/drivers/staging/media/hantro/sunxi_vpu_hw.c @@ -14,6 +14,14 @@ static const struct hantro_fmt sunxi_vpu_postproc_fmts[] = { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, .postprocessed = true, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = 32, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = 32, + }, }, };
@@ -21,17 +29,25 @@ static const struct hantro_fmt sunxi_vpu_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12_4L4, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = 32, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = 32, + }, }, { .fourcc = V4L2_PIX_FMT_VP9_FRAME, .codec_mode = HANTRO_MODE_VP9_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, .step_width = 32, - .min_height = 48, - .max_height = 2160, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, .step_height = 32, }, },
From: Ezequiel Garcia ezequiel@vanguardiasur.com.ar
[ Upstream commit 177d841fa19542eb35aa5ec9579c4abb989c9255 ]
Commit 1f82f2df523cb ("media: hantro: Enable H.264 on Rockchip VDPU2") enabled H.264 on some SoCs with VDPU2 cores. This had the side-effect of exposing H.264 coded format as supported on RK3399.
Fix this and clarify how the codec is explicitly disabled on RK3399 on this driver.
Fixes: 1f82f2df523cb ("media: hantro: Enable H.264 on Rockchip VDPU2") Signed-off-by: Ezequiel Garcia ezequiel@vanguardiasur.com.ar Tested-by: Nicolas Dufresne nicolas.dufresne@collabora.com Reviewed-by: Nicolas Dufresne nicolas.dufresne@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../staging/media/hantro/rockchip_vpu_hw.c | 60 ++++++++++++++++--- 1 file changed, 53 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c index 098486b9ec27..26e16b5a6a70 100644 --- a/drivers/staging/media/hantro/rockchip_vpu_hw.c +++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c @@ -182,7 +182,7 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = { }, };
-static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { +static const struct hantro_fmt rockchip_vdpu2_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, @@ -236,6 +236,47 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { }, };
+static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_NV12, + .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, + .step_height = MB_DIM, + }, + }, + { + .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, + .codec_mode = HANTRO_MODE_MPEG2_DEC, + .max_depth = 2, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, + .step_height = MB_DIM, + }, + }, + { + .fourcc = V4L2_PIX_FMT_VP8_FRAME, + .codec_mode = HANTRO_MODE_VP8_DEC, + .max_depth = 2, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = MB_DIM, + }, + }, +}; + static irqreturn_t rockchip_vpu1_vepu_irq(int irq, void *dev_id) { struct hantro_dev *vpu = dev_id; @@ -548,8 +589,8 @@ const struct hantro_variant rk3288_vpu_variant = {
const struct hantro_variant rk3328_vpu_variant = { .dec_offset = 0x400, - .dec_fmts = rk3399_vpu_dec_fmts, - .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), + .dec_fmts = rockchip_vdpu2_dec_fmts, + .num_dec_fmts = ARRAY_SIZE(rockchip_vdpu2_dec_fmts), .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER | HANTRO_H264_DECODER, .codec_ops = rk3399_vpu_codec_ops, @@ -560,6 +601,11 @@ const struct hantro_variant rk3328_vpu_variant = { .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names), };
+/* + * H.264 decoding explicitly disabled in RK3399. + * This ensures userspace applications use the Rockchip VDEC core, + * which has better performance. + */ const struct hantro_variant rk3399_vpu_variant = { .enc_offset = 0x0, .enc_fmts = rockchip_vpu_enc_fmts, @@ -579,8 +625,8 @@ const struct hantro_variant rk3399_vpu_variant = {
const struct hantro_variant rk3568_vpu_variant = { .dec_offset = 0x400, - .dec_fmts = rk3399_vpu_dec_fmts, - .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), + .dec_fmts = rockchip_vdpu2_dec_fmts, + .num_dec_fmts = ARRAY_SIZE(rockchip_vdpu2_dec_fmts), .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER | HANTRO_H264_DECODER, .codec_ops = rk3399_vpu_codec_ops, @@ -596,8 +642,8 @@ const struct hantro_variant px30_vpu_variant = { .enc_fmts = rockchip_vpu_enc_fmts, .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts), .dec_offset = 0x400, - .dec_fmts = rk3399_vpu_dec_fmts, - .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), + .dec_fmts = rockchip_vdpu2_dec_fmts, + .num_dec_fmts = ARRAY_SIZE(rockchip_vdpu2_dec_fmts), .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER | HANTRO_H264_DECODER, .codec_ops = rk3399_vpu_codec_ops,
From: Ming Qian ming.qian@nxp.com
[ Upstream commit d8f1eb105eab7aab36323c6b488dda479d5bd2da ]
1. prevent to allocate buffer to firmware during abort 2. release buffer when clear the slots
Fixes: 6de8d628df6ef ("media: amphion: add v4l2 m2m vpu decoder stateful driver") Signed-off-by: Ming Qian ming.qian@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/amphion/vdec.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c index a5bb997b000b..5e3b08d07abd 100644 --- a/drivers/media/platform/amphion/vdec.c +++ b/drivers/media/platform/amphion/vdec.c @@ -63,6 +63,7 @@ struct vdec_t { bool is_source_changed; u32 source_change; u32 drain; + bool aborting; };
static const struct vpu_format vdec_formats[] = { @@ -948,6 +949,9 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb if (inst->state != VPU_CODEC_STATE_ACTIVE) return -EINVAL;
+ if (vdec->aborting) + return -EINVAL; + if (!vdec->req_frame_count) return -EINVAL;
@@ -1057,6 +1061,8 @@ static void vdec_clear_slots(struct vpu_inst *inst) vpu_buf = vdec->slots[i]; vbuf = &vpu_buf->m2m_buf.vb;
+ vpu_trace(inst->dev, "clear slot %d\n", i); + vdec_response_fs_release(inst, i, vpu_buf->tag); vdec_recycle_buffer(inst, vbuf); vdec->slots[i]->state = VPU_BUF_STATE_IDLE; vdec->slots[i] = NULL; @@ -1318,6 +1324,8 @@ static void vdec_abort(struct vpu_inst *inst) int ret;
vpu_trace(inst->dev, "[%d] state = %d\n", inst->id, inst->state); + + vdec->aborting = true; vpu_iface_add_scode(inst, SCODE_PADDING_ABORT); vdec->params.end_flag = 1; vpu_iface_set_decode_params(inst, &vdec->params, 1); @@ -1341,6 +1349,7 @@ static void vdec_abort(struct vpu_inst *inst) vdec->decoded_frame_count = 0; vdec->display_frame_count = 0; vdec->sequence = 0; + vdec->aborting = false; }
static void vdec_stop(struct vpu_inst *inst, bool free)
From: Ming Qian ming.qian@nxp.com
[ Upstream commit e670f5d672ef3d00b0b8c69eff09a019e6dd4ef9 ]
For format V4L2_PIX_FMT_VC1_ANNEX_L, the amphion vpu requires driver to help insert some custom startcode before sequence and frame. but only the first sequence startcode is needed, the extra startcode will cause decoding error. So after seek, we don't need to insert the sequence startcode.
In other words, for V4L2_PIX_FMT_VC1_ANNEX_L, the vpu doesn't support dynamic resolution change.
Fixes: 145e936380edb ("media: amphion: implement malone decoder rpc interface") Signed-off-by: Ming Qian ming.qian@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/amphion/vdec.c | 2 +- drivers/media/platform/amphion/vpu.h | 1 + drivers/media/platform/amphion/vpu_malone.c | 2 ++ drivers/media/platform/amphion/vpu_rpc.h | 7 ++++++- 4 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c index 5e3b08d07abd..44dbca0fe17f 100644 --- a/drivers/media/platform/amphion/vdec.c +++ b/drivers/media/platform/amphion/vdec.c @@ -105,7 +105,6 @@ static const struct vpu_format vdec_formats[] = { .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - .flags = V4L2_FMT_FLAG_DYN_RESOLUTION }, { .pixfmt = V4L2_PIX_FMT_MPEG2, @@ -741,6 +740,7 @@ static void vdec_stop_done(struct vpu_inst *inst) vdec->eos_received = 0; vdec->is_source_changed = false; vdec->source_change = 0; + inst->total_input_count = 0; vpu_inst_unlock(inst); }
diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h index e56b96a7e5d3..f914de6ed81e 100644 --- a/drivers/media/platform/amphion/vpu.h +++ b/drivers/media/platform/amphion/vpu.h @@ -258,6 +258,7 @@ struct vpu_inst { struct vpu_format cap_format; u32 min_buffer_cap; u32 min_buffer_out; + u32 total_input_count;
struct v4l2_rect crop; u32 colorspace; diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c index 40267c73b1f9..542bbe361bd8 100644 --- a/drivers/media/platform/amphion/vpu_malone.c +++ b/drivers/media/platform/amphion/vpu_malone.c @@ -1298,6 +1298,8 @@ static int vpu_malone_insert_scode_vc1_l_seq(struct malone_scode_t *scode) int size = 0; u8 rcv_seqhdr[MALONE_VC1_RCV_SEQ_HEADER_LEN];
+ if (scode->inst->total_input_count) + return 0; scode->need_data = 0;
ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VC1_SIMPLE, sizeof(rcv_seqhdr)); diff --git a/drivers/media/platform/amphion/vpu_rpc.h b/drivers/media/platform/amphion/vpu_rpc.h index 25119e5e807e..7eb6f01e6ab5 100644 --- a/drivers/media/platform/amphion/vpu_rpc.h +++ b/drivers/media/platform/amphion/vpu_rpc.h @@ -312,11 +312,16 @@ static inline int vpu_iface_input_frame(struct vpu_inst *inst, struct vb2_buffer *vb) { struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core); + int ret;
if (!ops || !ops->input_frame) return -EINVAL;
- return ops->input_frame(inst->core->iface, inst, vb); + ret = ops->input_frame(inst->core->iface, inst, vb); + if (ret < 0) + return ret; + inst->total_input_count++; + return ret; }
static inline int vpu_iface_config_memory_resource(struct vpu_inst *inst,
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 63907290faa916ffab1c8455141c79ca8e3a79bb ]
Fix the following sparse warning in mt7915_rf_regval_get routine: drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c:979:16: warning: cast to restricted __le32
Fixes: 0a17329ae9c1f ("mt76: mt7915: add debugfs knob for RF registers read/write") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c index cab6e02e1f8c..d0c719ecacd0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -976,7 +976,7 @@ mt7915_rf_regval_get(void *data, u64 *val) if (ret) return ret;
- *val = le32_to_cpu(regval); + *val = regval;
return 0; }
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit cffd93411575afd987788e2ec3cb8eaff70f0215 ]
Free the skb if mt76u_bulk_msg fails in __mt76x02u_mcu_send_msg routine.
Fixes: 4c89ff2c74e39 ("mt76: split __mt76u_mcu_send_msg and mt76u_mcu_send_msg routines") Co-developed-by: Gergo Koteles soyer@irl.hu Signed-off-by: Gergo Koteles soyer@irl.hu Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c index 2953df7d8388..c6c16fe8ee85 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c @@ -108,7 +108,7 @@ __mt76x02u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb, ret = mt76u_bulk_msg(dev, skb->data, skb->len, NULL, 500, MT_EP_OUT_INBAND_CMD); if (ret) - return ret; + goto out;
if (wait_resp) ret = mt76x02u_mcu_wait_resp(dev, seq);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit f572dc969a59a80baa22bf2f7c9af0064402652f ]
This code is supposed to set a u32 value, but casting will not work on big endian systems.
Fixes: 0a17329ae9c1 ("mt76: mt7915: add debugfs knob for RF registers read/write") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c index d0c719ecacd0..fd76db8f5269 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -985,8 +985,9 @@ static int mt7915_rf_regval_set(void *data, u64 val) { struct mt7915_dev *dev = data; + u32 val32 = val;
- return mt7915_mcu_rf_regval(dev, dev->mt76.debugfs_reg, (u32 *)&val, true); + return mt7915_mcu_rf_regval(dev, dev->mt76.debugfs_reg, &val32, true); }
DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, mt7915_rf_regval_get,
From: YN Chen yn.chen@mediatek.com
[ Upstream commit a55a0c701c129f8e448f0ec1eb811dba728ace64 ]
To avoid racing problems in chip, mt7921s should reacquire drv-own after firmware semaphore is released.
Fixes: 78b217580c509 ("mt76: mt7921s: fix bus hang with wrong privilege") Signed-off-by: YN Chen yn.chen@mediatek.com Signed-off-by: Deren Wu deren.wu@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 12bab18c4171..71cbb9073485 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -582,13 +582,6 @@ static int mt7921_load_patch(struct mt7921_dev *dev) if (ret) dev_err(dev->mt76.dev, "Failed to start patch\n");
- if (mt76_is_sdio(&dev->mt76)) { - /* activate again */ - ret = __mt7921_mcu_fw_pmctrl(dev); - if (!ret) - ret = __mt7921_mcu_drv_pmctrl(dev); - } - out: sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, false); switch (sem) { @@ -599,6 +592,14 @@ static int mt7921_load_patch(struct mt7921_dev *dev) dev_err(dev->mt76.dev, "Failed to release patch semaphore\n"); break; } + + if (!ret && mt76_is_sdio(&dev->mt76)) { + /* activate again */ + ret = __mt7921_mcu_fw_pmctrl(dev); + if (!ret) + ret = __mt7921_mcu_drv_pmctrl(dev); + } + release_firmware(fw);
return ret;
From: Deren Wu deren.wu@mediatek.com
[ Upstream commit c149d3a9058616ff942a6e44b6e968e18a84dd5a ]
Beacon disable flow would be handled in bss stop handler automatically. Force return -EOPNOTSUPP in disable case.
Fixes: 116c69603b01 ("mt76: mt7921: Add AP mode support") Reviewed-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Deren Wu deren.wu@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 71cbb9073485..3765b345b741 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -1256,8 +1256,11 @@ mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, }; struct sk_buff *skb;
+ /* support enable/update process only + * disable flow would be handled in bss stop handler automatically + */ if (!enable) - goto out; + return -EOPNOTSUPP;
skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs); if (!skb) @@ -1283,7 +1286,6 @@ mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, } dev_kfree_skb(skb);
-out: return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE), &req, sizeof(req), true); }
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 92ea8df110b8ca92f9664ec7bd76dea109115348 ]
We don't really care too much right now since our data structures are set up to not have a problem with this, but clearly it's wrong to accept WEP and pairwise keys with key ID > 3.
However, with MLD we need to split into per-link (GTK, IGTK, BIGTK) and per interface/MLD (including WEP) keys so make sure this is not a problem.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/key.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 0fcf8aebedc4..047a06b857c9 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -433,13 +433,25 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, int idx; int ret = 0; bool defunikey, defmultikey, defmgmtkey, defbeaconkey; + bool is_wep;
/* caller must provide at least one old/new */ if (WARN_ON(!new && !old)) return 0;
- if (new) + if (new) { + idx = new->conf.keyidx; list_add_tail_rcu(&new->list, &sdata->key_list); + is_wep = new->conf.cipher == WLAN_CIPHER_SUITE_WEP40 || + new->conf.cipher == WLAN_CIPHER_SUITE_WEP104; + } else { + idx = old->conf.keyidx; + is_wep = old->conf.cipher == WLAN_CIPHER_SUITE_WEP40 || + old->conf.cipher == WLAN_CIPHER_SUITE_WEP104; + } + + if ((is_wep || pairwise) && idx >= NUM_DEFAULT_KEYS) + return -EINVAL;
WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
@@ -451,8 +463,6 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, }
if (old) { - idx = old->conf.keyidx; - if (old->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { ieee80211_key_disable_hw_accel(old);
@@ -460,8 +470,6 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, ret = ieee80211_key_enable_hw_accel(new); } } else { - /* new must be provided in case old is not */ - idx = new->conf.keyidx; if (!new->local->wowlan) ret = ieee80211_key_enable_hw_accel(new); }
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 7b0a0e3c3a88260b6fcb017e49f198463aa62ed1 ]
In order to support multi-link operation with multiple links, start adding some APIs. The notable addition here is to have the link ID in a new nl80211 attribute, that will be used to differentiate the links in many nl80211 operations.
So far, this patch adds the netlink NL80211_ATTR_MLO_LINK_ID attribute (as well as the NL80211_ATTR_MLO_LINKS attribute) and plugs it through the system in some places, checking the validity etc. along with other infrastructure needed for it.
For now, I've decided to include only the over-the-air link ID in the API. I know we discussed that we eventually need to have to have other ways of identifying a link, but for local AP mode and auth/assoc commands as well as set_key etc. we'll use the OTA ID.
Also included in this patch is some refactoring of the data structures in struct wireless_dev, splitting for the first time the data into type dependent pieces, to make reasoning about these things easier.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 6 +- drivers/net/wireless/ath/wil6210/cfg80211.c | 9 +- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 4 +- drivers/net/wireless/marvell/libertas/mesh.c | 10 +- drivers/net/wireless/marvell/mwifiex/11h.c | 2 +- .../net/wireless/marvell/mwifiex/cfg80211.c | 18 +- .../wireless/microchip/wilc1000/cfg80211.c | 3 +- .../net/wireless/quantenna/qtnfmac/cfg80211.c | 14 +- .../net/wireless/quantenna/qtnfmac/commands.c | 2 +- .../net/wireless/quantenna/qtnfmac/event.c | 15 +- .../staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 4 +- include/linux/ieee80211.h | 3 + include/net/cfg80211.h | 99 ++- include/uapi/linux/nl80211.h | 28 + net/mac80211/cfg.c | 8 +- net/mac80211/mlme.c | 2 +- net/wireless/ap.c | 46 +- net/wireless/chan.c | 196 ++++-- net/wireless/core.c | 28 +- net/wireless/core.h | 13 +- net/wireless/ibss.c | 57 +- net/wireless/mesh.c | 31 +- net/wireless/mlme.c | 74 ++- net/wireless/nl80211.c | 623 +++++++++++++----- net/wireless/ocb.c | 5 +- net/wireless/rdev-ops.h | 32 +- net/wireless/reg.c | 139 ++-- net/wireless/scan.c | 8 +- net/wireless/sme.c | 102 +-- net/wireless/trace.h | 86 ++- net/wireless/util.c | 44 +- net/wireless/wext-compat.c | 48 +- net/wireless/wext-sme.c | 29 +- 33 files changed, 1255 insertions(+), 533 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index bd1183830e91..33ed54738d47 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1119,7 +1119,7 @@ void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
mutex_lock(&vif->wdev.mtx); - cfg80211_ch_switch_notify(vif->ndev, &chandef); + cfg80211_ch_switch_notify(vif->ndev, &chandef, 0); mutex_unlock(&vif->wdev.mtx); }
@@ -2967,7 +2967,8 @@ static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev, return ath6kl_set_ies(vif, beacon); }
-static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev) +static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev, + unsigned int link_id) { struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev); @@ -3368,6 +3369,7 @@ static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy, struct net_device *dev, + unsigned int link_id, const u8 *addr, const struct cfg80211_bitrate_mask *mask) { diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 8f2638f5b87b..f93bdffa4d1d 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -2098,8 +2098,8 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy, bcon->tail_len)) privacy = 1;
- memcpy(vif->ssid, wdev->ssid, wdev->ssid_len); - vif->ssid_len = wdev->ssid_len; + memcpy(vif->ssid, wdev->u.ap.ssid, wdev->u.ap.ssid_len); + vif->ssid_len = wdev->u.ap.ssid_len;
/* in case privacy has changed, need to restart the AP */ if (vif->privacy != privacy) { @@ -2108,7 +2108,7 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
rc = _wil_cfg80211_start_ap(wiphy, ndev, vif->ssid, vif->ssid_len, privacy, - wdev->beacon_interval, + wdev->links[0].ap.beacon_interval, vif->channel, vif->wmi_edmg_channel, bcon, vif->hidden_ssid, @@ -2186,7 +2186,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy, }
static int wil_cfg80211_stop_ap(struct wiphy *wiphy, - struct net_device *ndev) + struct net_device *ndev, + unsigned int link_id) { struct wil6210_priv *wil = wiphy_to_wil(wiphy); struct wil6210_vif *vif = ndev_to_vif(ndev); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 605206abe424..11e1f07f83e0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -4965,7 +4965,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, return err; }
-static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) +static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev, + unsigned int link_id) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_if *ifp = netdev_priv(ndev); @@ -5302,6 +5303,7 @@ brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
static int brcmf_cfg80211_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, + unsigned int link_id, struct cfg80211_chan_def *chandef) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); diff --git a/drivers/net/wireless/marvell/libertas/mesh.c b/drivers/net/wireless/marvell/libertas/mesh.c index a58c1e141f2c..90ffe8d1e0e8 100644 --- a/drivers/net/wireless/marvell/libertas/mesh.c +++ b/drivers/net/wireless/marvell/libertas/mesh.c @@ -109,9 +109,9 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
if (priv->mesh_dev) { mesh_wdev = priv->mesh_dev->ieee80211_ptr; - ie->val.mesh_id_len = mesh_wdev->mesh_id_up_len; - memcpy(ie->val.mesh_id, mesh_wdev->ssid, - mesh_wdev->mesh_id_up_len); + ie->val.mesh_id_len = mesh_wdev->u.mesh.id_up_len; + memcpy(ie->val.mesh_id, mesh_wdev->u.mesh.id, + mesh_wdev->u.mesh.id_up_len); }
ie->len = sizeof(struct mrvl_meshie_val) - @@ -986,8 +986,8 @@ static int lbs_add_mesh(struct lbs_private *priv) mesh_wdev->wiphy = priv->wdev->wiphy;
if (priv->mesh_tlv) { - sprintf(mesh_wdev->ssid, "mesh"); - mesh_wdev->mesh_id_up_len = 4; + sprintf(mesh_wdev->u.mesh.id, "mesh"); + mesh_wdev->u.mesh.id_up_len = 4; }
mesh_wdev->netdev = mesh_dev; diff --git a/drivers/net/wireless/marvell/mwifiex/11h.c b/drivers/net/wireless/marvell/mwifiex/11h.c index 3fa25cd64cda..4ca8d0135708 100644 --- a/drivers/net/wireless/marvell/mwifiex/11h.c +++ b/drivers/net/wireless/marvell/mwifiex/11h.c @@ -304,6 +304,6 @@ void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work) mwifiex_dbg(priv->adapter, MSG, "indicating channel switch completion to kernel\n"); mutex_lock(&priv->wdev.mtx); - cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef); + cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef, 0); mutex_unlock(&priv->wdev.mtx); } diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 6f23ec34e2e2..d68c40e0e122 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -1753,10 +1753,12 @@ mwifiex_mgmt_stypes[NUM_NL80211_IFTYPES] = { * Function configures data rates to firmware using bitrate mask * provided by cfg80211. */ -static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, - struct net_device *dev, - const u8 *peer, - const struct cfg80211_bitrate_mask *mask) +static int +mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, + struct net_device *dev, + unsigned int link_id, + const u8 *peer, + const struct cfg80211_bitrate_mask *mask) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); u16 bitmap_rates[MAX_BITMAP_RATES_SIZE]; @@ -1998,7 +2000,8 @@ mwifiex_cfg80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant) /* cfg80211 operation handler for stop ap. * Function stops BSS running at uAP interface. */ -static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) +static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev, + unsigned int link_id) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
@@ -2421,7 +2424,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return -EINVAL; }
- if (priv->wdev.current_bss) { + if (priv->wdev.connected) { mwifiex_dbg(adapter, ERROR, "%s: already connected\n", dev->name); return -EALREADY; @@ -2649,7 +2652,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, return -EBUSY; }
- if (!priv->wdev.current_bss && priv->scan_block) + if (!priv->wdev.connected && priv->scan_block) priv->scan_block = false;
if (!mwifiex_stop_bg_scan(priv)) @@ -4025,6 +4028,7 @@ mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, + unsigned int link_id, struct cfg80211_chan_def *chandef) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c index 8d8378bafd9b..269748b9a1c4 100644 --- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c @@ -1378,7 +1378,8 @@ static int change_beacon(struct wiphy *wiphy, struct net_device *dev, return wilc_add_beacon(vif, 0, 0, beacon); }
-static int stop_ap(struct wiphy *wiphy, struct net_device *dev) +static int stop_ap(struct wiphy *wiphy, struct net_device *dev, + unsigned int link_id) { int ret; struct wilc_vif *vif = netdev_priv(dev); diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c index 84b15a655eab..1593e810b3ca 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c +++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c @@ -352,7 +352,8 @@ static int qtnf_start_ap(struct wiphy *wiphy, struct net_device *dev, return ret; }
-static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev) +static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev, + unsigned int link_id) { struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); int ret; @@ -500,7 +501,7 @@ qtnf_dump_station(struct wiphy *wiphy, struct net_device *dev,
switch (vif->wdev.iftype) { case NL80211_IFTYPE_STATION: - if (idx != 0 || !vif->wdev.current_bss) + if (idx != 0 || !vif->wdev.connected) return -ENOENT;
ether_addr_copy(mac, vif->bssid); @@ -729,7 +730,7 @@ qtnf_disconnect(struct wiphy *wiphy, struct net_device *dev, pr_err("VIF%u.%u: failed to disconnect\n", mac->macid, vif->vifid);
- if (vif->wdev.current_bss) { + if (vif->wdev.connected) { netif_carrier_off(vif->netdev); cfg80211_disconnected(vif->netdev, reason_code, NULL, 0, true, GFP_KERNEL); @@ -745,10 +746,11 @@ qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev, struct qtnf_wmac *mac = wiphy_priv(wiphy); struct wireless_dev *wdev = dev->ieee80211_ptr; struct ieee80211_supported_band *sband; - const struct cfg80211_chan_def *chandef = &wdev->chandef; + const struct cfg80211_chan_def *chandef = wdev_chandef(wdev, 0); struct ieee80211_channel *chan; int ret;
+ sband = wiphy->bands[NL80211_BAND_2GHZ]; if (sband && idx >= sband->n_channels) { idx -= sband->n_channels; @@ -765,7 +767,7 @@ qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev, survey->channel = chan; survey->filled = 0x0;
- if (chan == chandef->chan) + if (chandef && chan == chandef->chan) survey->filled = SURVEY_INFO_IN_USE;
ret = qtnf_cmd_get_chan_stats(mac, chan->center_freq, survey); @@ -778,7 +780,7 @@ qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev,
static int qtnf_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, - struct cfg80211_chan_def *chandef) + unsigned int link_id, struct cfg80211_chan_def *chandef) { struct net_device *ndev = wdev->netdev; struct qtnf_vif *vif; diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c index c68563c83098..3d734a7a5ba8 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c @@ -2005,7 +2005,7 @@ int qtnf_cmd_send_scan(struct qtnf_wmac *mac) dwell_active = scan_req->duration; dwell_passive = scan_req->duration; } else if (wdev->iftype == NL80211_IFTYPE_STATION && - wdev->current_bss) { + wdev->connected) { /* let device select dwell based on traffic conditions */ dwell_active = QTNF_SCAN_TIME_AUTO; dwell_passive = QTNF_SCAN_TIME_AUTO; diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c index 8dc80574d08d..4fafe370101a 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/event.c +++ b/drivers/net/wireless/quantenna/qtnfmac/event.c @@ -189,7 +189,7 @@ qtnf_event_handle_bss_join(struct qtnf_vif *vif, vif->mac->macid, vif->vifid, join_info->bssid, chandef.chan->hw_value);
- if (!vif->wdev.ssid_len) { + if (!vif->wdev.u.client.ssid_len) { pr_warn("VIF%u.%u: SSID unknown for BSS:%pM\n", vif->mac->macid, vif->vifid, join_info->bssid); @@ -197,7 +197,7 @@ qtnf_event_handle_bss_join(struct qtnf_vif *vif, goto done; }
- ie = kzalloc(2 + vif->wdev.ssid_len, GFP_KERNEL); + ie = kzalloc(2 + vif->wdev.u.client.ssid_len, GFP_KERNEL); if (!ie) { pr_warn("VIF%u.%u: IE alloc failed for BSS:%pM\n", vif->mac->macid, vif->vifid, @@ -207,14 +207,15 @@ qtnf_event_handle_bss_join(struct qtnf_vif *vif, }
ie[0] = WLAN_EID_SSID; - ie[1] = vif->wdev.ssid_len; - memcpy(ie + 2, vif->wdev.ssid, vif->wdev.ssid_len); + ie[1] = vif->wdev.u.client.ssid_len; + memcpy(ie + 2, vif->wdev.u.client.ssid, + vif->wdev.u.client.ssid_len);
bss = cfg80211_inform_bss(wiphy, chandef.chan, CFG80211_BSS_FTYPE_UNKNOWN, join_info->bssid, 0, WLAN_CAPABILITY_ESS, 100, - ie, 2 + vif->wdev.ssid_len, + ie, 2 + vif->wdev.u.client.ssid_len, 0, GFP_KERNEL); if (!bss) { pr_warn("VIF%u.%u: can't connect to unknown BSS: %pM\n", @@ -470,14 +471,14 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac, continue;
if (vif->wdev.iftype == NL80211_IFTYPE_STATION && - !vif->wdev.current_bss) + !vif->wdev.connected) continue;
if (!vif->netdev) continue;
mutex_lock(&vif->wdev.mtx); - cfg80211_ch_switch_notify(vif->netdev, &chandef); + cfg80211_ch_switch_notify(vif->netdev, &chandef, 0); mutex_unlock(&vif->wdev.mtx); }
diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index 43b5604c0bca..349aa3c4b668 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -2086,6 +2086,7 @@ static u8 rtw_get_chan_type(struct adapter *adapter) }
static int cfg80211_rtw_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, + unsigned int link_id, struct cfg80211_chan_def *chandef) { struct adapter *adapter = wiphy_to_adapter(wiphy); @@ -2446,7 +2447,8 @@ static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *nd return rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len); }
-static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev) +static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev, + unsigned int link_id) { return 0; } diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 75d40acb60c1..5f66d5c9e3de 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -4345,4 +4345,7 @@ enum ieee80211_range_params_max_total_ltf { IEEE80211_RANGE_PARAMS_MAX_TOTAL_LTF_UNSPECIFIED, };
+/* multi-link device */ +#define IEEE80211_MLD_MAX_NUM_LINKS 15 + #endif /* LINUX_IEEE80211_H */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 80f41446b1f0..b3afb02c8a4e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1158,6 +1158,7 @@ struct cfg80211_mbssid_elems {
/** * struct cfg80211_beacon_data - beacon data + * @link_id: the link ID for the AP MLD link sending this beacon * @head: head portion of beacon (before TIM IE) * or %NULL if not changed * @tail: tail portion of beacon (after TIM IE) @@ -1188,6 +1189,8 @@ struct cfg80211_mbssid_elems { * attribute is present in beacon data or not. */ struct cfg80211_beacon_data { + unsigned int link_id; + const u8 *head, *tail; const u8 *beacon_ies; const u8 *proberesp_ies; @@ -4201,7 +4204,8 @@ struct cfg80211_ops { struct cfg80211_ap_settings *settings); int (*change_beacon)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info); - int (*stop_ap)(struct wiphy *wiphy, struct net_device *dev); + int (*stop_ap)(struct wiphy *wiphy, struct net_device *dev, + unsigned int link_id);
int (*add_station)(struct wiphy *wiphy, struct net_device *dev, @@ -4309,6 +4313,7 @@ struct cfg80211_ops {
int (*set_bitrate_mask)(struct wiphy *wiphy, struct net_device *dev, + unsigned int link_id, const u8 *peer, const struct cfg80211_bitrate_mask *mask);
@@ -4384,6 +4389,7 @@ struct cfg80211_ops {
int (*get_channel)(struct wiphy *wiphy, struct wireless_dev *wdev, + unsigned int link_id, struct cfg80211_chan_def *chandef);
int (*start_p2p_device)(struct wiphy *wiphy, @@ -4420,6 +4426,7 @@ struct cfg80211_ops { struct cfg80211_qos_map *qos_map);
int (*set_ap_chanwidth)(struct wiphy *wiphy, struct net_device *dev, + unsigned int link_id, struct cfg80211_chan_def *chandef);
int (*add_tx_ts)(struct wiphy *wiphy, struct net_device *dev, @@ -4545,10 +4552,14 @@ struct cfg80211_ops { * @WIPHY_FLAG_HAS_STATIC_WEP: The device supports static WEP key installation * before connection. * @WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK: The device supports bigger kek and kck keys + * @WIPHY_FLAG_SUPPORTS_MLO: This is a temporary flag gating the MLO APIs, + * in order to not have them reachable in normal drivers, until we have + * complete feature/interface combinations/etc. advertisement. No driver + * should set this flag for now. */ enum wiphy_flags { WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK = BIT(0), - /* use hole at 1 */ + WIPHY_FLAG_SUPPORTS_MLO = BIT(1), WIPHY_FLAG_SPLIT_SCAN_6GHZ = BIT(2), WIPHY_FLAG_NETNS_OK = BIT(3), WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), @@ -5505,6 +5516,8 @@ static inline void wiphy_unlock(struct wiphy *wiphy) * @netdev: (private) Used to reference back to the netdev, may be %NULL * @identifier: (private) Identifier used in nl80211 to identify this * wireless device if it has no netdev + * @connected_addr: (private) BSSID or AP MLD address if connected + * @connected: indicates if connected or not (STA mode) * @current_bss: (private) Used by the internal configuration code * @chandef: (private) Used by the internal configuration code to track * the user-set channel definition. @@ -5585,8 +5598,6 @@ struct wireless_dev { u8 address[ETH_ALEN] __aligned(sizeof(u16));
/* currently used for IBSS and SME - might be rearranged later */ - u8 ssid[IEEE80211_MAX_SSID_LEN]; - u8 ssid_len, mesh_id_len, mesh_id_up_len; struct cfg80211_conn *conn; struct cfg80211_cached_keys *connect_keys; enum ieee80211_bss_type conn_bss_type; @@ -5598,20 +5609,17 @@ struct wireless_dev { struct list_head event_list; spinlock_t event_lock;
- struct cfg80211_internal_bss *current_bss; /* associated / joined */ - struct cfg80211_chan_def preset_chandef; - struct cfg80211_chan_def chandef; + u8 connected:1;
bool ps; int ps_timeout;
- int beacon_interval; - u32 ap_unexpected_nlportid;
u32 owner_nlportid; bool nl_owner_dead;
+ /* FIXME: need to rework radar detection for MLO */ bool cac_started; unsigned long cac_start_time; unsigned int cac_time_ms; @@ -5639,6 +5647,50 @@ struct wireless_dev { struct work_struct pmsr_free_wk;
unsigned long unprot_beacon_reported; + + union { + struct { + u8 connected_addr[ETH_ALEN] __aligned(2); + u8 ssid[IEEE80211_MAX_SSID_LEN]; + u8 ssid_len; + } client; + struct { + int beacon_interval; + struct cfg80211_chan_def preset_chandef; + struct cfg80211_chan_def chandef; + u8 id[IEEE80211_MAX_SSID_LEN]; + u8 id_len, id_up_len; + } mesh; + struct { + struct cfg80211_chan_def preset_chandef; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + u8 ssid_len; + } ap; + struct { + struct cfg80211_internal_bss *current_bss; + struct cfg80211_chan_def chandef; + int beacon_interval; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + u8 ssid_len; + } ibss; + struct { + struct cfg80211_chan_def chandef; + } ocb; + } u; + + struct { + u8 addr[ETH_ALEN] __aligned(2); + union { + struct { + unsigned int beacon_interval; + struct cfg80211_chan_def chandef; + } ap; + struct { + struct cfg80211_internal_bss *current_bss; + } client; + }; + } links[IEEE80211_MLD_MAX_NUM_LINKS]; + u16 valid_links; };
static inline const u8 *wdev_address(struct wireless_dev *wdev) @@ -5667,6 +5719,31 @@ static inline void *wdev_priv(struct wireless_dev *wdev) return wiphy_priv(wdev->wiphy); }
+/** + * wdev_chandef - return chandef pointer from wireless_dev + * @wdev: the wdev + * @link_id: the link ID for MLO + * + * Return: The chandef depending on the mode, or %NULL. + */ +struct cfg80211_chan_def *wdev_chandef(struct wireless_dev *wdev, + unsigned int link_id); + +static inline void WARN_INVALID_LINK_ID(struct wireless_dev *wdev, + unsigned int link_id) +{ + WARN_ON(link_id && !wdev->valid_links); + WARN_ON(wdev->valid_links && + !(wdev->valid_links & BIT(link_id))); +} + +#define for_each_valid_link(wdev, link_id) \ + for (link_id = 0; \ + link_id < ((wdev)->valid_links ? ARRAY_SIZE((wdev)->links) : 1); \ + link_id++) \ + if (!(wdev)->valid_links || \ + ((wdev)->valid_links & BIT(link_id))) + /** * DOC: Utility functions * @@ -7882,12 +7959,14 @@ bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy, * cfg80211_ch_switch_notify - update wdev channel and notify userspace * @dev: the device which switched channels * @chandef: the new channel definition + * @link_id: the link ID for MLO, must be 0 for non-MLO * * Caller must acquire wdev_lock, therefore must only be called from sleepable * driver context! */ void cfg80211_ch_switch_notify(struct net_device *dev, - struct cfg80211_chan_def *chandef); + struct cfg80211_chan_def *chandef, + unsigned int link_id);
/* * cfg80211_ch_switch_started_notify - notify channel switch start diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index d9490e3062a7..509253bf4d11 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -323,6 +323,17 @@ * Once the association is done, the driver cleans the FILS AAD data. */
+/** + * DOC: Multi-Link Operation + * + * In Multi-Link Operation, a connection between to MLDs utilizes multiple + * links. To use this in nl80211, various commands and responses now need + * to or will include the new %NL80211_ATTR_MLO_LINKS attribute. + * Additionally, various commands that need to operate on a specific link + * now need to be given the %NL80211_ATTR_MLO_LINK_ID attribute, e.g. to + * use %NL80211_CMD_START_AP or similar functions. + */ + /** * enum nl80211_commands - supported nl80211 commands * @@ -1237,6 +1248,12 @@ * to describe the BSSID address of the AP and %NL80211_ATTR_TIMEOUT to * specify the timeout value. * + * @NL80211_CMD_ADD_LINK: Add a new link to an interface. The + * %NL80211_ATTR_MLO_LINK_ID attribute is used for the new link. + * @NL80211_CMD_REMOVE_LINK: Remove a link from an interface. This may come + * without %NL80211_ATTR_MLO_LINK_ID as an easy way to remove all links + * in preparation for e.g. roaming to a regular (non-MLO) AP. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -1481,6 +1498,9 @@ enum nl80211_commands {
NL80211_CMD_ASSOC_COMEBACK,
+ NL80211_CMD_ADD_LINK, + NL80211_CMD_REMOVE_LINK, + /* add new commands above here */
/* used to define NL80211_CMD_MAX below */ @@ -2663,6 +2683,11 @@ enum nl80211_commands { * association request when used with NL80211_CMD_NEW_STATION). Can be set * only if %NL80211_STA_FLAG_WME is set. * + * @NL80211_ATTR_MLO_LINK_ID: A (u8) link ID for use with MLO, to be used with + * various commands that need a link ID to operate. + * @NL80211_ATTR_MLO_LINKS: A nested array of links, each containing some + * per-link information and a link ID. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3177,6 +3202,9 @@ enum nl80211_attrs {
NL80211_ATTR_DISABLE_EHT,
+ NL80211_ATTR_MLO_LINKS, + NL80211_ATTR_MLO_LINK_ID, + /* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 4ddf297f40f2..30ccaa6cb9f3 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1358,7 +1358,8 @@ static void ieee80211_free_next_beacon(struct ieee80211_sub_if_data *sdata) sdata->u.ap.next_beacon = NULL; }
-static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) +static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev, + unsigned int link_id) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_sub_if_data *vlan; @@ -3065,6 +3066,7 @@ static int ieee80211_set_cqm_rssi_range_config(struct wiphy *wiphy,
static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, + unsigned int link_id, const u8 *addr, const struct cfg80211_bitrate_mask *mask) { @@ -3406,7 +3408,7 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) if (err) return err;
- cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); + cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef, 0);
return 0; } @@ -3914,6 +3916,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
static int ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, + unsigned int link_id, struct cfg80211_chan_def *chandef) { struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); @@ -3974,6 +3977,7 @@ static int ieee80211_set_qos_map(struct wiphy *wiphy,
static int ieee80211_set_ap_chanwidth(struct wiphy *wiphy, struct net_device *dev, + unsigned int link_id, struct cfg80211_chan_def *chandef) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 58d48dcae030..62fa93f2636e 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1314,7 +1314,7 @@ static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata) return; }
- cfg80211_ch_switch_notify(sdata->dev, &sdata->reserved_chandef); + cfg80211_ch_switch_notify(sdata->dev, &sdata->reserved_chandef, 0); }
void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) diff --git a/net/wireless/ap.c b/net/wireless/ap.c index 550ac9d827fe..e68923200018 100644 --- a/net/wireless/ap.c +++ b/net/wireless/ap.c @@ -1,4 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 +/* + * Parts of this file are + * Copyright (C) 2022 Intel Corporation + */ #include <linux/ieee80211.h> #include <linux/export.h> #include <net/cfg80211.h> @@ -7,8 +11,9 @@ #include "rdev-ops.h"
-int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, - struct net_device *dev, bool notify) +static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev, + struct net_device *dev, unsigned int link_id, + bool notify) { struct wireless_dev *wdev = dev->ieee80211_ptr; int err; @@ -22,15 +27,16 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) return -EOPNOTSUPP;
- if (!wdev->beacon_interval) + if (!wdev->links[link_id].ap.beacon_interval) return -ENOENT;
- err = rdev_stop_ap(rdev, dev); + err = rdev_stop_ap(rdev, dev, link_id); if (!err) { wdev->conn_owner_nlportid = 0; - wdev->beacon_interval = 0; - memset(&wdev->chandef, 0, sizeof(wdev->chandef)); - wdev->ssid_len = 0; + wdev->links[link_id].ap.beacon_interval = 0; + memset(&wdev->links[link_id].ap.chandef, 0, + sizeof(wdev->links[link_id].ap.chandef)); + wdev->u.ap.ssid_len = 0; rdev_set_qos_map(rdev, dev, NULL); if (notify) nl80211_send_ap_stopped(wdev); @@ -46,14 +52,36 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, return err; }
+int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, + struct net_device *dev, int link_id, + bool notify) +{ + unsigned int link; + int ret = 0; + + if (link_id >= 0) + return ___cfg80211_stop_ap(rdev, dev, link_id, notify); + + for_each_valid_link(dev->ieee80211_ptr, link) { + int ret1 = ___cfg80211_stop_ap(rdev, dev, link, notify); + + if (ret1) + ret = ret1; + /* try the next one also if one errored */ + } + + return ret; +} + int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, - struct net_device *dev, bool notify) + struct net_device *dev, int link_id, + bool notify) { struct wireless_dev *wdev = dev->ieee80211_ptr; int err;
wdev_lock(wdev); - err = __cfg80211_stop_ap(rdev, dev, notify); + err = __cfg80211_stop_ap(rdev, dev, link_id, notify); wdev_unlock(wdev);
return err; diff --git a/net/wireless/chan.c b/net/wireless/chan.c index f74f176e0d9d..efc2de4bab57 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -672,14 +672,21 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy, * range of chandef. */ bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef, - struct ieee80211_channel *chan) + struct ieee80211_channel *chan, + bool primary_only) { int width; u32 freq;
+ if (!chandef->chan) + return false; + if (chandef->chan->center_freq == chan->center_freq) return true;
+ if (primary_only) + return false; + width = cfg80211_chandef_get_width(chandef); if (width <= 20) return false; @@ -704,23 +711,25 @@ bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev) { - bool active = false; + unsigned int link;
ASSERT_WDEV_LOCK(wdev);
- if (!wdev->chandef.chan) - return false; - switch (wdev->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: - active = wdev->beacon_interval != 0; + for_each_valid_link(wdev, link) { + if (wdev->links[link].ap.beacon_interval) + return true; + } break; case NL80211_IFTYPE_ADHOC: - active = wdev->ssid_len != 0; + if (wdev->u.ibss.ssid_len) + return true; break; case NL80211_IFTYPE_MESH_POINT: - active = wdev->mesh_id_len != 0; + if (wdev->u.mesh.id_len) + return true; break; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_OCB: @@ -737,7 +746,35 @@ bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev) WARN_ON(1); }
- return active; + return false; +} + +bool cfg80211_wdev_on_sub_chan(struct wireless_dev *wdev, + struct ieee80211_channel *chan, + bool primary_only) +{ + unsigned int link; + + switch (wdev->iftype) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + for_each_valid_link(wdev, link) { + if (cfg80211_is_sub_chan(&wdev->links[link].ap.chandef, + chan, primary_only)) + return true; + } + break; + case NL80211_IFTYPE_ADHOC: + return cfg80211_is_sub_chan(&wdev->u.ibss.chandef, chan, + primary_only); + case NL80211_IFTYPE_MESH_POINT: + return cfg80211_is_sub_chan(&wdev->u.mesh.chandef, chan, + primary_only); + default: + break; + } + + return false; }
static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy, @@ -752,7 +789,7 @@ static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy, continue; }
- if (cfg80211_is_sub_chan(&wdev->chandef, chan)) { + if (cfg80211_wdev_on_sub_chan(wdev, chan, false)) { wdev_unlock(wdev); return true; } @@ -772,7 +809,8 @@ cfg80211_offchan_chain_is_active(struct cfg80211_registered_device *rdev, if (!cfg80211_chandef_valid(&rdev->background_radar_chandef)) return false;
- return cfg80211_is_sub_chan(&rdev->background_radar_chandef, channel); + return cfg80211_is_sub_chan(&rdev->background_radar_chandef, channel, + false); }
bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, @@ -1176,6 +1214,68 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, } EXPORT_SYMBOL(cfg80211_chandef_usable);
+static bool cfg80211_ir_permissive_check_wdev(enum nl80211_iftype iftype, + struct wireless_dev *wdev, + struct ieee80211_channel *chan) +{ + struct ieee80211_channel *other_chan = NULL; + unsigned int link_id; + int r1, r2; + + for_each_valid_link(wdev, link_id) { + if (wdev->iftype == NL80211_IFTYPE_STATION && + wdev->links[link_id].client.current_bss) + other_chan = wdev->links[link_id].client.current_bss->pub.channel; + + /* + * If a GO already operates on the same GO_CONCURRENT channel, + * this one (maybe the same one) can beacon as well. We allow + * the operation even if the station we relied on with + * GO_CONCURRENT is disconnected now. But then we must make sure + * we're not outdoor on an indoor-only channel. + */ + if (iftype == NL80211_IFTYPE_P2P_GO && + wdev->iftype == NL80211_IFTYPE_P2P_GO && + wdev->links[link_id].ap.beacon_interval && + !(chan->flags & IEEE80211_CHAN_INDOOR_ONLY)) + other_chan = wdev->links[link_id].ap.chandef.chan; + + if (!other_chan) + continue; + + if (chan == other_chan) + return true; + + if (chan->band != NL80211_BAND_5GHZ && + chan->band != NL80211_BAND_6GHZ) + continue; + + r1 = cfg80211_get_unii(chan->center_freq); + r2 = cfg80211_get_unii(other_chan->center_freq); + + if (r1 != -EINVAL && r1 == r2) { + /* + * At some locations channels 149-165 are considered a + * bundle, but at other locations, e.g., Indonesia, + * channels 149-161 are considered a bundle while + * channel 165 is left out and considered to be in a + * different bundle. Thus, in case that there is a + * station interface connected to an AP on channel 165, + * it is assumed that channels 149-161 are allowed for + * GO operations. However, having a station interface + * connected to an AP on channels 149-161, does not + * allow GO operation on channel 165. + */ + if (chan->center_freq == 5825 && + other_chan->center_freq != 5825) + continue; + return true; + } + } + + return false; +} + /* * Check if the channel can be used under permissive conditions mandated by * some regulatory bodies, i.e., the channel is marked with @@ -1219,59 +1319,14 @@ static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy, * the current registered device. */ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { - struct ieee80211_channel *other_chan = NULL; - int r1, r2; + bool ret;
wdev_lock(wdev); - if (wdev->iftype == NL80211_IFTYPE_STATION && - wdev->current_bss) - other_chan = wdev->current_bss->pub.channel; - - /* - * If a GO already operates on the same GO_CONCURRENT channel, - * this one (maybe the same one) can beacon as well. We allow - * the operation even if the station we relied on with - * GO_CONCURRENT is disconnected now. But then we must make sure - * we're not outdoor on an indoor-only channel. - */ - if (iftype == NL80211_IFTYPE_P2P_GO && - wdev->iftype == NL80211_IFTYPE_P2P_GO && - wdev->beacon_interval && - !(chan->flags & IEEE80211_CHAN_INDOOR_ONLY)) - other_chan = wdev->chandef.chan; + ret = cfg80211_ir_permissive_check_wdev(iftype, wdev, chan); wdev_unlock(wdev);
- if (!other_chan) - continue; - - if (chan == other_chan) - return true; - - if (chan->band != NL80211_BAND_5GHZ && - chan->band != NL80211_BAND_6GHZ) - continue; - - r1 = cfg80211_get_unii(chan->center_freq); - r2 = cfg80211_get_unii(other_chan->center_freq); - - if (r1 != -EINVAL && r1 == r2) { - /* - * At some locations channels 149-165 are considered a - * bundle, but at other locations, e.g., Indonesia, - * channels 149-161 are considered a bundle while - * channel 165 is left out and considered to be in a - * different bundle. Thus, in case that there is a - * station interface connected to an AP on channel 165, - * it is assumed that channels 149-161 are allowed for - * GO operations. However, having a station interface - * connected to an AP on channels 149-161, does not - * allow GO operation on channel 165. - */ - if (chan->center_freq == 5825 && - other_chan->center_freq != 5825) - continue; - return true; - } + if (ret) + return ret; }
return false; @@ -1374,3 +1429,24 @@ bool cfg80211_any_usable_channels(struct wiphy *wiphy, return false; } EXPORT_SYMBOL(cfg80211_any_usable_channels); + +struct cfg80211_chan_def *wdev_chandef(struct wireless_dev *wdev, + unsigned int link_id) +{ + ASSERT_WDEV_LOCK(wdev); + + switch (wdev->iftype) { + case NL80211_IFTYPE_MESH_POINT: + return &wdev->u.mesh.chandef; + case NL80211_IFTYPE_ADHOC: + return &wdev->u.ibss.chandef; + case NL80211_IFTYPE_OCB: + return &wdev->u.ocb.chandef; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + return &wdev->links[link_id].ap.chandef; + default: + return NULL; + } +} +EXPORT_SYMBOL(wdev_chandef); diff --git a/net/wireless/core.c b/net/wireless/core.c index f08d4b3bb148..3e5d12040726 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1118,6 +1118,7 @@ static void _cfg80211_unregister_wdev(struct wireless_dev *wdev, bool unregister_netdev) { struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); + unsigned int link_id;
ASSERT_RTNL(); lockdep_assert_held(&rdev->wiphy.mtx); @@ -1167,11 +1168,22 @@ static void _cfg80211_unregister_wdev(struct wireless_dev *wdev, */ cfg80211_process_wdev_events(wdev);
- if (WARN_ON(wdev->current_bss)) { - cfg80211_unhold_bss(wdev->current_bss); - cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); - wdev->current_bss = NULL; + if (wdev->iftype == NL80211_IFTYPE_STATION || + wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) { + for (link_id = 0; link_id < ARRAY_SIZE(wdev->links); link_id++) { + struct cfg80211_internal_bss *curbss; + + curbss = wdev->links[link_id].client.current_bss; + + if (WARN_ON(curbss)) { + cfg80211_unhold_bss(curbss); + cfg80211_put_bss(wdev->wiphy, &curbss->pub); + wdev->links[link_id].client.current_bss = NULL; + } + } } + + wdev->connected = false; }
void cfg80211_unregister_wdev(struct wireless_dev *wdev) @@ -1233,7 +1245,7 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev, break; case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: - __cfg80211_stop_ap(rdev, dev, true); + __cfg80211_stop_ap(rdev, dev, -1, true); break; case NL80211_IFTYPE_OCB: __cfg80211_leave_ocb(rdev, dev); @@ -1463,9 +1475,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, memcpy(&setup, &default_mesh_setup, sizeof(setup)); /* back compat only needed for mesh_id */ - setup.mesh_id = wdev->ssid; - setup.mesh_id_len = wdev->mesh_id_up_len; - if (wdev->mesh_id_up_len) + setup.mesh_id = wdev->u.mesh.id; + setup.mesh_id_len = wdev->u.mesh.id_up_len; + if (wdev->u.mesh.id_up_len) __cfg80211_join_mesh(rdev, dev, &setup, &default_mesh_config); diff --git a/net/wireless/core.h b/net/wireless/core.h index 5436ada91b1a..2c195067ddff 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -307,6 +307,7 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *rdev); void cfg80211_bss_age(struct cfg80211_registered_device *rdev, unsigned long age_secs); void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev, + unsigned int link, struct ieee80211_channel *channel);
/* IBSS */ @@ -353,9 +354,11 @@ int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
/* AP */ int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, - struct net_device *dev, bool notify); + struct net_device *dev, int link, + bool notify); int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, - struct net_device *dev, bool notify); + struct net_device *dev, int link, + bool notify);
/* MLME */ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, @@ -507,7 +510,11 @@ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev);
bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef, - struct ieee80211_channel *chan); + struct ieee80211_channel *chan, + bool primary_only); +bool cfg80211_wdev_on_sub_chan(struct wireless_dev *wdev, + struct ieee80211_channel *chan, + bool primary_only);
static inline unsigned int elapsed_jiffies_msecs(unsigned long start) { diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 5d89eec2869a..4935f94d1acc 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -28,7 +28,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) return;
- if (!wdev->ssid_len) + if (!wdev->u.ibss.ssid_len) return;
bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0, @@ -37,13 +37,13 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, if (WARN_ON(!bss)) return;
- if (wdev->current_bss) { - cfg80211_unhold_bss(wdev->current_bss); - cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); + if (wdev->u.ibss.current_bss) { + cfg80211_unhold_bss(wdev->u.ibss.current_bss); + cfg80211_put_bss(wdev->wiphy, &wdev->u.ibss.current_bss->pub); }
cfg80211_hold_bss(bss_from_pub(bss)); - wdev->current_bss = bss_from_pub(bss); + wdev->u.ibss.current_bss = bss_from_pub(bss);
if (!(wdev->wiphy->flags & WIPHY_FLAG_HAS_STATIC_WEP)) cfg80211_upload_connect_keys(wdev); @@ -96,7 +96,7 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, lockdep_assert_held(&rdev->wiphy.mtx); ASSERT_WDEV_LOCK(wdev);
- if (wdev->ssid_len) + if (wdev->u.ibss.ssid_len) return -EALREADY;
if (!params->basic_rates) { @@ -131,7 +131,7 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, kfree_sensitive(wdev->connect_keys); wdev->connect_keys = connkeys;
- wdev->chandef = params->chandef; + wdev->u.ibss.chandef = params->chandef; if (connkeys) { params->wep_keys = connkeys->params; params->wep_tx_key = connkeys->def; @@ -146,8 +146,8 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, return err; }
- memcpy(wdev->ssid, params->ssid, params->ssid_len); - wdev->ssid_len = params->ssid_len; + memcpy(wdev->u.ibss.ssid, params->ssid, params->ssid_len); + wdev->u.ibss.ssid_len = params->ssid_len;
return 0; } @@ -173,14 +173,14 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) for (i = 0; i < 6; i++) rdev_del_key(rdev, dev, i, false, NULL);
- if (wdev->current_bss) { - cfg80211_unhold_bss(wdev->current_bss); - cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); + if (wdev->u.ibss.current_bss) { + cfg80211_unhold_bss(wdev->u.ibss.current_bss); + cfg80211_put_bss(wdev->wiphy, &wdev->u.ibss.current_bss->pub); }
- wdev->current_bss = NULL; - wdev->ssid_len = 0; - memset(&wdev->chandef, 0, sizeof(wdev->chandef)); + wdev->u.ibss.current_bss = NULL; + wdev->u.ibss.ssid_len = 0; + memset(&wdev->u.ibss.chandef, 0, sizeof(wdev->u.ibss.chandef)); #ifdef CONFIG_CFG80211_WEXT if (!nowext) wdev->wext.ibss.ssid_len = 0; @@ -205,7 +205,7 @@ int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
ASSERT_WDEV_LOCK(wdev);
- if (!wdev->ssid_len) + if (!wdev->u.ibss.ssid_len) return -ENOLINK;
err = rdev_leave_ibss(rdev, dev); @@ -339,7 +339,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
wdev_lock(wdev); err = 0; - if (wdev->ssid_len) + if (wdev->u.ibss.ssid_len) err = __cfg80211_leave_ibss(rdev, dev, true); wdev_unlock(wdev);
@@ -374,8 +374,8 @@ int cfg80211_ibss_wext_giwfreq(struct net_device *dev, return -EINVAL;
wdev_lock(wdev); - if (wdev->current_bss) - chan = wdev->current_bss->pub.channel; + if (wdev->u.ibss.current_bss) + chan = wdev->u.ibss.current_bss->pub.channel; else if (wdev->wext.ibss.chandef.chan) chan = wdev->wext.ibss.chandef.chan; wdev_unlock(wdev); @@ -408,7 +408,7 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
wdev_lock(wdev); err = 0; - if (wdev->ssid_len) + if (wdev->u.ibss.ssid_len) err = __cfg80211_leave_ibss(rdev, dev, true); wdev_unlock(wdev);
@@ -419,8 +419,8 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev, if (len > 0 && ssid[len - 1] == '\0') len--;
- memcpy(wdev->ssid, ssid, len); - wdev->wext.ibss.ssid = wdev->ssid; + memcpy(wdev->u.ibss.ssid, ssid, len); + wdev->wext.ibss.ssid = wdev->u.ibss.ssid; wdev->wext.ibss.ssid_len = len;
wdev_lock(wdev); @@ -443,10 +443,10 @@ int cfg80211_ibss_wext_giwessid(struct net_device *dev, data->flags = 0;
wdev_lock(wdev); - if (wdev->ssid_len) { + if (wdev->u.ibss.ssid_len) { data->flags = 1; - data->length = wdev->ssid_len; - memcpy(ssid, wdev->ssid, data->length); + data->length = wdev->u.ibss.ssid_len; + memcpy(ssid, wdev->u.ibss.ssid, data->length); } else if (wdev->wext.ibss.ssid && wdev->wext.ibss.ssid_len) { data->flags = 1; data->length = wdev->wext.ibss.ssid_len; @@ -494,7 +494,7 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
wdev_lock(wdev); err = 0; - if (wdev->ssid_len) + if (wdev->u.ibss.ssid_len) err = __cfg80211_leave_ibss(rdev, dev, true); wdev_unlock(wdev);
@@ -527,8 +527,9 @@ int cfg80211_ibss_wext_giwap(struct net_device *dev, ap_addr->sa_family = ARPHRD_ETHER;
wdev_lock(wdev); - if (wdev->current_bss) - memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN); + if (wdev->u.ibss.current_bss) + memcpy(ap_addr->sa_data, wdev->u.ibss.current_bss->pub.bssid, + ETH_ALEN); else if (wdev->wext.ibss.bssid) memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN); else diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index e4e363138279..59a3c5c092b1 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -1,4 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 +/* + * Portions + * Copyright (C) 2022 Intel Corporation + */ #include <linux/ieee80211.h> #include <linux/export.h> #include <net/cfg80211.h> @@ -114,7 +118,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, setup->is_secure) return -EOPNOTSUPP;
- if (wdev->mesh_id_len) + if (wdev->u.mesh.id_len) return -EALREADY;
if (!setup->mesh_id_len) @@ -125,7 +129,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
if (!setup->chandef.chan) { /* if no channel explicitly given, use preset channel */ - setup->chandef = wdev->preset_chandef; + setup->chandef = wdev->u.mesh.preset_chandef; }
if (!setup->chandef.chan) { @@ -209,10 +213,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
err = rdev_join_mesh(rdev, dev, conf, setup); if (!err) { - memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); - wdev->mesh_id_len = setup->mesh_id_len; - wdev->chandef = setup->chandef; - wdev->beacon_interval = setup->beacon_interval; + memcpy(wdev->u.mesh.id, setup->mesh_id, setup->mesh_id_len); + wdev->u.mesh.id_len = setup->mesh_id_len; + wdev->u.mesh.chandef = setup->chandef; + wdev->u.mesh.beacon_interval = setup->beacon_interval; }
return err; @@ -241,15 +245,15 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, chandef->chan); if (!err) - wdev->chandef = *chandef; + wdev->u.mesh.chandef = *chandef;
return err; }
- if (wdev->mesh_id_len) + if (wdev->u.mesh.id_len) return -EBUSY;
- wdev->preset_chandef = *chandef; + wdev->u.mesh.preset_chandef = *chandef; return 0; }
@@ -267,15 +271,16 @@ int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, if (!rdev->ops->leave_mesh) return -EOPNOTSUPP;
- if (!wdev->mesh_id_len) + if (!wdev->u.mesh.id_len) return -ENOTCONN;
err = rdev_leave_mesh(rdev, dev); if (!err) { wdev->conn_owner_nlportid = 0; - wdev->mesh_id_len = 0; - wdev->beacon_interval = 0; - memset(&wdev->chandef, 0, sizeof(wdev->chandef)); + wdev->u.mesh.id_len = 0; + wdev->u.mesh.beacon_interval = 0; + memset(&wdev->u.mesh.chandef, 0, + sizeof(wdev->u.mesh.chandef)); rdev_set_qos_map(rdev, dev, NULL); cfg80211_sched_dfs_chan_update(rdev); } diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index c8155a483ec2..fab2d6206cdd 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -92,8 +92,7 @@ static void cfg80211_process_deauth(struct wireless_dev *wdev,
nl80211_send_deauth(rdev, wdev->netdev, buf, len, reconnect, GFP_KERNEL);
- if (!wdev->current_bss || - !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) + if (!wdev->connected || !ether_addr_equal(wdev->u.client.connected_addr, bssid)) return;
__cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap); @@ -113,8 +112,8 @@ static void cfg80211_process_disassoc(struct wireless_dev *wdev, nl80211_send_disassoc(rdev, wdev->netdev, buf, len, reconnect, GFP_KERNEL);
- if (WARN_ON(!wdev->current_bss || - !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) + if (WARN_ON(!wdev->connected || + !ether_addr_equal(wdev->u.client.connected_addr, bssid))) return;
__cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap); @@ -260,8 +259,8 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, if (!key || !key_len || key_idx < 0 || key_idx > 3) return -EINVAL;
- if (wdev->current_bss && - ether_addr_equal(bssid, wdev->current_bss->pub.bssid)) + if (wdev->connected && + ether_addr_equal(bssid, wdev->u.client.connected_addr)) return -EALREADY;
req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, @@ -322,9 +321,9 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
ASSERT_WDEV_LOCK(wdev);
- if (wdev->current_bss && - (!req->prev_bssid || !ether_addr_equal(wdev->current_bss->pub.bssid, - req->prev_bssid))) + if (wdev->connected && + (!req->prev_bssid || + !ether_addr_equal(wdev->u.client.connected_addr, req->prev_bssid))) return -EALREADY;
cfg80211_oper_and_ht_capa(&req->ht_capa_mask, @@ -364,13 +363,13 @@ int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, ASSERT_WDEV_LOCK(wdev);
if (local_state_change && - (!wdev->current_bss || - !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) + (!wdev->connected || + !ether_addr_equal(wdev->u.client.connected_addr, bssid))) return 0;
if (ether_addr_equal(wdev->disconnect_bssid, bssid) || - (wdev->current_bss && - ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) + (wdev->connected && + ether_addr_equal(wdev->u.client.connected_addr, bssid))) wdev->conn_owner_nlportid = 0;
return rdev_deauth(rdev, dev, &req); @@ -392,11 +391,12 @@ int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
ASSERT_WDEV_LOCK(wdev);
- if (!wdev->current_bss) + if (!wdev->connected) return -ENOTCONN;
- if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) - req.bss = &wdev->current_bss->pub; + if (ether_addr_equal(wdev->links[0].client.current_bss->pub.bssid, + bssid)) + req.bss = &wdev->links[0].client.current_bss->pub; else return -ENOTCONN;
@@ -405,7 +405,7 @@ int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, return err;
/* driver should have reported the disassoc */ - WARN_ON(wdev->current_bss); + WARN_ON(wdev->connected); return 0; }
@@ -420,10 +420,10 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, if (!rdev->ops->deauth) return;
- if (!wdev->current_bss) + if (!wdev->connected) return;
- memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); + memcpy(bssid, wdev->u.client.connected_addr, ETH_ALEN); cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0, WLAN_REASON_DEAUTH_LEAVING, false); } @@ -676,28 +676,34 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
switch (wdev->iftype) { case NL80211_IFTYPE_ADHOC: + /* + * check for IBSS DA must be done by driver as + * cfg80211 doesn't track the stations + */ + if (!wdev->u.ibss.current_bss || + !ether_addr_equal(wdev->u.ibss.current_bss->pub.bssid, + mgmt->bssid)) { + err = -ENOTCONN; + break; + } + break; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: - if (!wdev->current_bss) { + if (!wdev->connected) { err = -ENOTCONN; break; }
- if (!ether_addr_equal(wdev->current_bss->pub.bssid, + /* FIXME: MLD may address this differently */ + + if (!ether_addr_equal(wdev->u.client.connected_addr, mgmt->bssid)) { err = -ENOTCONN; break; }
- /* - * check for IBSS DA must be done by driver as - * cfg80211 doesn't track the stations - */ - if (wdev->iftype == NL80211_IFTYPE_ADHOC) - break; - /* for station, check that DA is the AP */ - if (!ether_addr_equal(wdev->current_bss->pub.bssid, + if (!ether_addr_equal(wdev->u.client.connected_addr, mgmt->da)) { err = -ENOTCONN; break; @@ -743,12 +749,12 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, if (!ieee80211_is_action(mgmt->frame_control) || mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) return -EINVAL; - if (!wdev->current_bss && + if (!wdev->connected && !wiphy_ext_feature_isset( &rdev->wiphy, NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA)) return -EINVAL; - if (wdev->current_bss && + if (wdev->connected && !wiphy_ext_feature_isset( &rdev->wiphy, NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED)) @@ -940,12 +946,16 @@ void cfg80211_cac_event(struct net_device *netdev, struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); unsigned long timeout;
+ /* not yet supported */ + if (wdev->valid_links) + return; + trace_cfg80211_cac_event(netdev, event);
if (WARN_ON(!wdev->cac_started && event != NL80211_RADAR_CAC_STARTED)) return;
- if (WARN_ON(!wdev->chandef.chan)) + if (WARN_ON(!wdev->links[0].ap.chandef.chan)) return;
switch (event) { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 740b29481bc6..af31978fc9cc 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -792,6 +792,10 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { NL80211_EHT_MIN_CAPABILITY_LEN, NL80211_EHT_MAX_CAPABILITY_LEN), [NL80211_ATTR_DISABLE_EHT] = { .type = NLA_FLAG }, + [NL80211_ATTR_MLO_LINKS] = + NLA_POLICY_NESTED_ARRAY(nl80211_policy), + [NL80211_ATTR_MLO_LINK_ID] = + NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS), };
/* policy for the key attributes */ @@ -1225,6 +1229,37 @@ static bool nl80211_put_txq_stats(struct sk_buff *msg,
/* netlink command implementations */
+/** + * nl80211_link_id - return link ID + * @attrs: attributes to look at + * + * Returns: the link ID or 0 if not given + * + * Note this function doesn't do any validation of the link + * ID validity wrt. links that were actually added, so it must + * be called only from ops with %NL80211_FLAG_MLO_VALID_LINK_ID + * or if additional validation is done. + */ +static unsigned int nl80211_link_id(struct nlattr **attrs) +{ + struct nlattr *linkid = attrs[NL80211_ATTR_MLO_LINK_ID]; + + if (!linkid) + return 0; + + return nla_get_u8(linkid); +} + +static int nl80211_link_id_or_invalid(struct nlattr **attrs) +{ + struct nlattr *linkid = attrs[NL80211_ATTR_MLO_LINK_ID]; + + if (!linkid) + return -1; + + return nla_get_u8(linkid); +} + struct key_parse { struct key_params p; int idx; @@ -1496,11 +1531,15 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) case NL80211_IFTYPE_MESH_POINT: break; case NL80211_IFTYPE_ADHOC: + if (wdev->u.ibss.current_bss) + return 0; + return -ENOLINK; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: - if (!wdev->current_bss) - return -ENOLINK; - break; + /* for MLO, require driver validation of the link ID */ + if (wdev->connected) + return 0; + return -ENOLINK; case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_MONITOR: @@ -3232,12 +3271,14 @@ int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, struct net_device *dev, - struct genl_info *info) + struct genl_info *info, + int _link_id) { struct cfg80211_chan_def chandef; int result; enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR; struct wireless_dev *wdev = NULL; + int link_id = _link_id;
if (dev) wdev = dev->ieee80211_ptr; @@ -3246,6 +3287,12 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, if (wdev) iftype = wdev->iftype;
+ if (link_id < 0) { + if (wdev && wdev->valid_links) + return -EINVAL; + link_id = 0; + } + result = nl80211_parse_chandef(rdev, info, &chandef); if (result) return result; @@ -3254,49 +3301,48 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef, - iftype)) { - result = -EINVAL; - break; - } - if (wdev->beacon_interval) { + iftype)) + return -EINVAL; + if (wdev->links[link_id].ap.beacon_interval) { + struct ieee80211_channel *cur_chan; + if (!dev || !rdev->ops->set_ap_chanwidth || !(rdev->wiphy.features & - NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) { - result = -EBUSY; - break; - } + NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) + return -EBUSY;
/* Only allow dynamic channel width changes */ - if (chandef.chan != wdev->preset_chandef.chan) { - result = -EBUSY; - break; - } - result = rdev_set_ap_chanwidth(rdev, dev, &chandef); + cur_chan = wdev->links[link_id].ap.chandef.chan; + if (chandef.chan != cur_chan) + return -EBUSY; + + result = rdev_set_ap_chanwidth(rdev, dev, link_id, + &chandef); if (result) - break; + return result; + wdev->links[link_id].ap.chandef = chandef; + } else { + wdev->u.ap.preset_chandef = chandef; } - wdev->preset_chandef = chandef; - result = 0; - break; + return 0; case NL80211_IFTYPE_MESH_POINT: - result = cfg80211_set_mesh_channel(rdev, wdev, &chandef); - break; + return cfg80211_set_mesh_channel(rdev, wdev, &chandef); case NL80211_IFTYPE_MONITOR: - result = cfg80211_set_monitor_channel(rdev, &chandef); - break; + return cfg80211_set_monitor_channel(rdev, &chandef); default: - result = -EINVAL; + break; }
- return result; + return -EINVAL; }
static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; + int link_id = nl80211_link_id_or_invalid(info->attrs); struct net_device *netdev = info->user_ptr[1];
- return __nl80211_set_channel(rdev, netdev, info); + return __nl80211_set_channel(rdev, netdev, info, link_id); }
static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) @@ -3411,7 +3457,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) result = __nl80211_set_channel( rdev, nl80211_can_set_dev_channel(wdev) ? netdev : NULL, - info); + info, -1); if (result) goto out; } @@ -3696,15 +3742,13 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr)) goto nla_put_failure;
- if (rdev->ops->get_channel) { - int ret; + if (rdev->ops->get_channel && !wdev->valid_links) { struct cfg80211_chan_def chandef = {}; + int ret;
- ret = rdev_get_channel(rdev, wdev, &chandef); - if (ret == 0) { - if (nl80211_send_chandef(msg, &chandef)) - goto nla_put_failure; - } + ret = rdev_get_channel(rdev, wdev, 0, &chandef); + if (ret == 0 && nl80211_send_chandef(msg, &chandef)) + goto nla_put_failure; }
if (rdev->ops->get_tx_power) { @@ -3721,27 +3765,24 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag switch (wdev->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: - if (wdev->ssid_len && - nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) + if (wdev->u.ap.ssid_len && + nla_put(msg, NL80211_ATTR_SSID, wdev->u.ap.ssid_len, + wdev->u.ap.ssid)) goto nla_put_failure_locked; break; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: - case NL80211_IFTYPE_ADHOC: { - const struct element *ssid_elem; - - if (!wdev->current_bss) - break; - rcu_read_lock(); - ssid_elem = ieee80211_bss_get_elem(&wdev->current_bss->pub, - WLAN_EID_SSID); - if (ssid_elem && - nla_put(msg, NL80211_ATTR_SSID, ssid_elem->datalen, - ssid_elem->data)) - goto nla_put_failure_rcu_locked; - rcu_read_unlock(); + if (wdev->u.client.ssid_len && + nla_put(msg, NL80211_ATTR_SSID, wdev->u.client.ssid_len, + wdev->u.client.ssid)) + goto nla_put_failure_locked; + break; + case NL80211_IFTYPE_ADHOC: + if (wdev->u.ibss.ssid_len && + nla_put(msg, NL80211_ATTR_SSID, wdev->u.ibss.ssid_len, + wdev->u.ibss.ssid)) + goto nla_put_failure_locked; break; - } default: /* nothing */ break; @@ -3761,8 +3802,6 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag genlmsg_end(msg, hdr); return 0;
- nla_put_failure_rcu_locked: - rcu_read_unlock(); nla_put_failure_locked: wdev_unlock(wdev); nla_put_failure: @@ -4014,10 +4053,11 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) wdev_lock(wdev); BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); - wdev->mesh_id_up_len = + wdev->u.mesh.id_up_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); - memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), - wdev->mesh_id_up_len); + memcpy(wdev->u.mesh.id, + nla_data(info->attrs[NL80211_ATTR_MESH_ID]), + wdev->u.mesh.id_up_len); wdev_unlock(wdev); }
@@ -4122,10 +4162,11 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) wdev_lock(wdev); BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); - wdev->mesh_id_up_len = + wdev->u.mesh.id_up_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); - memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), - wdev->mesh_id_up_len); + memcpy(wdev->u.mesh.id, + nla_data(info->attrs[NL80211_ATTR_MESH_ID]), + wdev->u.mesh.id_up_len); wdev_unlock(wdev); break; case NL80211_IFTYPE_NAN: @@ -4662,7 +4703,7 @@ static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) return -EOPNOTSUPP;
- if (!dev->ieee80211_ptr->beacon_interval) + if (!dev->ieee80211_ptr->links[0].ap.beacon_interval) return -EINVAL;
acl = parse_acl_data(&rdev->wiphy, info); @@ -4818,14 +4859,24 @@ static void he_build_mcs_mask(u16 he_mcs_map, } }
-static u16 he_get_txmcsmap(struct genl_info *info, +static u16 he_get_txmcsmap(struct genl_info *info, unsigned int link_id, const struct ieee80211_sta_he_cap *he_cap) { struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; - __le16 tx_mcs; + struct cfg80211_chan_def *chandef; + __le16 tx_mcs;
- switch (wdev->chandef.width) { + chandef = wdev_chandef(wdev, link_id); + if (!chandef) { + /* + * This is probably broken, but we never maintained + * a chandef in these cases, so it always was. + */ + return le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); + } + + switch (chandef->width) { case NL80211_CHAN_WIDTH_80P80: tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80p80; break; @@ -4836,6 +4887,7 @@ static u16 he_get_txmcsmap(struct genl_info *info, tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80; break; } + return le16_to_cpu(tx_mcs); }
@@ -4843,7 +4895,8 @@ static bool he_set_mcs_mask(struct genl_info *info, struct wireless_dev *wdev, struct ieee80211_supported_band *sband, struct nl80211_txrate_he *txrate, - u16 mcs[NL80211_HE_NSS_MAX]) + u16 mcs[NL80211_HE_NSS_MAX], + unsigned int link_id) { const struct ieee80211_sta_he_cap *he_cap; u16 tx_mcs_mask[NL80211_HE_NSS_MAX] = {}; @@ -4856,7 +4909,7 @@ static bool he_set_mcs_mask(struct genl_info *info,
memset(mcs, 0, sizeof(u16) * NL80211_HE_NSS_MAX);
- tx_mcs_map = he_get_txmcsmap(info, he_cap); + tx_mcs_map = he_get_txmcsmap(info, link_id, he_cap);
/* Build he_mcs_mask from HE capabilities */ he_build_mcs_mask(tx_mcs_map, tx_mcs_mask); @@ -4876,7 +4929,8 @@ static int nl80211_parse_tx_bitrate_mask(struct genl_info *info, enum nl80211_attrs attr, struct cfg80211_bitrate_mask *mask, struct net_device *dev, - bool default_all_enabled) + bool default_all_enabled, + unsigned int link_id) { struct nlattr *tb[NL80211_TXRATE_MAX + 1]; struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -4913,7 +4967,7 @@ static int nl80211_parse_tx_bitrate_mask(struct genl_info *info, if (!he_cap) continue;
- he_tx_mcs_map = he_get_txmcsmap(info, he_cap); + he_tx_mcs_map = he_get_txmcsmap(info, link_id, he_cap); he_build_mcs_mask(he_tx_mcs_map, mask->control[i].he_mcs);
mask->control[i].he_gi = 0xFF; @@ -4978,7 +5032,8 @@ static int nl80211_parse_tx_bitrate_mask(struct genl_info *info, if (tb[NL80211_TXRATE_HE] && !he_set_mcs_mask(info, wdev, sband, nla_data(tb[NL80211_TXRATE_HE]), - mask->control[band].he_mcs)) + mask->control[band].he_mcs, + link_id)) return -EINVAL;
if (tb[NL80211_TXRATE_HE_GI]) @@ -5215,6 +5270,8 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
memset(bcn, 0, sizeof(*bcn));
+ bcn->link_id = nl80211_link_id(attrs); + if (attrs[NL80211_ATTR_BEACON_HEAD]) { bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]); bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]); @@ -5468,22 +5525,20 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev, struct cfg80211_ap_settings *params) { struct wireless_dev *wdev; - bool ret = false;
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { if (wdev->iftype != NL80211_IFTYPE_AP && wdev->iftype != NL80211_IFTYPE_P2P_GO) continue;
- if (!wdev->preset_chandef.chan) + if (!wdev->u.ap.preset_chandef.chan) continue;
- params->chandef = wdev->preset_chandef; - ret = true; - break; + params->chandef = wdev->u.ap.preset_chandef; + return true; }
- return ret; + return false; }
static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev, @@ -5541,6 +5596,7 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev, static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; + unsigned int link_id = nl80211_link_id(info->attrs); struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_ap_settings *params; @@ -5553,7 +5609,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->start_ap) return -EOPNOTSUPP;
- if (wdev->beacon_interval) + if (wdev->links[link_id].ap.beacon_interval) return -EALREADY;
/* these are required for START_AP */ @@ -5595,6 +5651,18 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) err = -EINVAL; goto out; } + + if (wdev->u.ap.ssid_len && + (wdev->u.ap.ssid_len != params->ssid_len || + memcmp(wdev->u.ap.ssid, params->ssid, params->ssid_len))) { + /* require identical SSID for MLO */ + err = -EINVAL; + goto out; + } + } else if (wdev->valid_links) { + /* require SSID for MLO */ + err = -EINVAL; + goto out; }
if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) @@ -5662,8 +5730,12 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) err = nl80211_parse_chandef(rdev, info, ¶ms->chandef); if (err) goto out; - } else if (wdev->preset_chandef.chan) { - params->chandef = wdev->preset_chandef; + } else if (wdev->valid_links) { + /* with MLD need to specify the channel configuration */ + err = -EINVAL; + goto out; + } else if (wdev->u.ap.preset_chandef.chan) { + params->chandef = wdev->u.ap.preset_chandef; } else if (!nl80211_get_ap_channel(rdev, params)) { err = -EINVAL; goto out; @@ -5679,7 +5751,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) err = nl80211_parse_tx_bitrate_mask(info, info->attrs, NL80211_ATTR_TX_RATES, ¶ms->beacon_rate, - dev, false); + dev, false, link_id); if (err) goto out;
@@ -5779,19 +5851,28 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) params->flags |= NL80211_AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
wdev_lock(wdev); + if (wdev->conn_owner_nlportid && + info->attrs[NL80211_ATTR_SOCKET_OWNER] && + wdev->conn_owner_nlportid != info->snd_portid) { + err = -EINVAL; + goto out_unlock; + } + + /* FIXME: validate MLO/link-id against driver capabilities */ + err = rdev_start_ap(rdev, dev, params); if (!err) { - wdev->preset_chandef = params->chandef; - wdev->beacon_interval = params->beacon_interval; - wdev->chandef = params->chandef; - wdev->ssid_len = params->ssid_len; - memcpy(wdev->ssid, params->ssid, wdev->ssid_len); + wdev->links[link_id].ap.beacon_interval = params->beacon_interval; + wdev->links[link_id].ap.chandef = params->chandef; + wdev->u.ap.ssid_len = params->ssid_len; + memcpy(wdev->u.ap.ssid, params->ssid, + params->ssid_len);
if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) wdev->conn_owner_nlportid = info->snd_portid; } +out_unlock: wdev_unlock(wdev); - out: kfree(params->acl); kfree(params->beacon.mbssid_ies); @@ -5807,6 +5888,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; + unsigned int link_id = nl80211_link_id(info->attrs); struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_beacon_data params; @@ -5819,7 +5901,7 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->change_beacon) return -EOPNOTSUPP;
- if (!wdev->beacon_interval) + if (!wdev->links[link_id].ap.beacon_interval) return -EINVAL;
err = nl80211_parse_beacon(rdev, info->attrs, ¶ms); @@ -5838,9 +5920,10 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; + unsigned int link_id = nl80211_link_id(info->attrs); struct net_device *dev = info->user_ptr[1];
- return cfg80211_stop_ap(rdev, dev, false); + return cfg80211_stop_ap(rdev, dev, link_id, false); }
static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { @@ -7590,7 +7673,7 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
wdev_lock(wdev); /* If not connected, get default parameters */ - if (!wdev->mesh_id_len) + if (!wdev->u.mesh.id_len) memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); else err = rdev_get_mesh_config(rdev, dev, &cur_params); @@ -7971,7 +8054,7 @@ static int nl80211_update_mesh_config(struct sk_buff *skb, return err;
wdev_lock(wdev); - if (!wdev->mesh_id_len) + if (!wdev->u.mesh.id_len) err = -ENOLINK;
if (!err) @@ -8463,14 +8546,44 @@ int nl80211_parse_random_mac(struct nlattr **attrs, return 0; }
-static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev) +static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev, + struct ieee80211_channel *chan) { + unsigned int link_id; + bool all_ok = true; + ASSERT_WDEV_LOCK(wdev);
if (!cfg80211_beaconing_iface_active(wdev)) return true;
- if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR)) + /* + * FIXME: check if we have a free HW resource/link for chan + * + * This, as well as the FIXME below, requires knowing the link + * capabilities of the hardware. + */ + + /* we cannot leave radar channels */ + for_each_valid_link(wdev, link_id) { + struct cfg80211_chan_def *chandef; + + chandef = wdev_chandef(wdev, link_id); + if (!chandef) + continue; + + /* + * FIXME: don't require all_ok, but rather check only the + * correct HW resource/link onto which 'chan' falls, + * as only that link leaves the channel for doing + * the off-channel operation. + */ + + if (chandef->chan->flags & IEEE80211_CHAN_RADAR) + all_ok = false; + } + + if (all_ok) return true;
return regulatory_pre_cac_allowed(wdev->wiphy); @@ -8553,7 +8666,7 @@ nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev, int err;
if (!(wiphy->features & randomness_flag) || - (wdev && wdev->current_bss)) + (wdev && wdev->connected)) return -EOPNOTSUPP;
err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask); @@ -8690,17 +8803,14 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) request->n_channels = i;
wdev_lock(wdev); - if (!cfg80211_off_channel_oper_allowed(wdev)) { - struct ieee80211_channel *chan; + for (i = 0; i < request->n_channels; i++) { + struct ieee80211_channel *chan = request->channels[i];
- if (request->n_channels != 1) { - wdev_unlock(wdev); - err = -EBUSY; - goto out_free; - } + /* if we can go off-channel to the target channel we're good */ + if (cfg80211_off_channel_oper_allowed(wdev, chan)) + continue;
- chan = request->channels[0]; - if (chan->center_freq != wdev->chandef.chan->center_freq) { + if (!cfg80211_wdev_on_sub_chan(wdev, chan, true)) { wdev_unlock(wdev); err = -EBUSY; goto out_free; @@ -9445,7 +9555,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms); if (!err) { - wdev->chandef = chandef; + wdev->links[0].ap.chandef = chandef; wdev->cac_started = true; wdev->cac_start_time = jiffies; wdev->cac_time_ms = cac_time_ms; @@ -9513,6 +9623,7 @@ static int nl80211_notify_radar_detection(struct sk_buff *skb, static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; + unsigned int link_id = nl80211_link_id(info->attrs); struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_csa_settings params; @@ -9539,15 +9650,15 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) need_handle_dfs_flag = false;
/* useless if AP is not running */ - if (!wdev->beacon_interval) + if (!wdev->links[link_id].ap.beacon_interval) return -ENOTCONN; break; case NL80211_IFTYPE_ADHOC: - if (!wdev->ssid_len) + if (!wdev->u.ibss.ssid_len) return -ENOTCONN; break; case NL80211_IFTYPE_MESH_POINT: - if (!wdev->mesh_id_len) + if (!wdev->u.mesh.id_len) return -ENOTCONN; break; default: @@ -9718,6 +9829,7 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, { struct cfg80211_bss *res = &intbss->pub; const struct cfg80211_bss_ies *ies; + unsigned int link_id; void *hdr; struct nlattr *bss;
@@ -9822,13 +9934,15 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, switch (wdev->iftype) { case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: - if (intbss == wdev->current_bss && - nla_put_u32(msg, NL80211_BSS_STATUS, - NL80211_BSS_STATUS_ASSOCIATED)) - goto nla_put_failure; + for_each_valid_link(wdev, link_id) { + if (intbss == wdev->links[link_id].client.current_bss && + nla_put_u32(msg, NL80211_BSS_STATUS, + NL80211_BSS_STATUS_ASSOCIATED)) + goto nla_put_failure; + } break; case NL80211_IFTYPE_ADHOC: - if (intbss == wdev->current_bss && + if (intbss == wdev->u.ibss.current_bss && nla_put_u32(msg, NL80211_BSS_STATUS, NL80211_BSS_STATUS_IBSS_JOINED)) goto nla_put_failure; @@ -11362,7 +11476,7 @@ static int nl80211_update_connect_params(struct sk_buff *skb, }
wdev_lock(dev->ieee80211_ptr); - if (!wdev->current_bss) + if (!wdev->connected) ret = -ENOLINK; else ret = rdev_update_connect_params(rdev, dev, &connect, changed); @@ -11575,9 +11689,9 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; + unsigned int link_id = nl80211_link_id(info->attrs); struct wireless_dev *wdev = info->user_ptr[1]; struct cfg80211_chan_def chandef; - const struct cfg80211_chan_def *compat_chandef; struct sk_buff *msg; void *hdr; u64 cookie; @@ -11607,10 +11721,22 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, return err;
wdev_lock(wdev); - if (!cfg80211_off_channel_oper_allowed(wdev) && - !cfg80211_chandef_identical(&wdev->chandef, &chandef)) { - compat_chandef = cfg80211_chandef_compatible(&wdev->chandef, - &chandef); + if (!cfg80211_off_channel_oper_allowed(wdev, chandef.chan)) { + const struct cfg80211_chan_def *oper_chandef, *compat_chandef; + + oper_chandef = wdev_chandef(wdev, link_id); + + if (WARN_ON(!oper_chandef)) { + /* cannot happen since we must beacon to get here */ + WARN_ON(1); + wdev_unlock(wdev); + return -EBUSY; + } + + /* note: returns first one if identical chandefs */ + compat_chandef = cfg80211_chandef_compatible(&chandef, + oper_chandef); + if (compat_chandef != &chandef) { wdev_unlock(wdev); return -EBUSY; @@ -11672,6 +11798,7 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_bitrate_mask mask; + unsigned int link_id = nl80211_link_id(info->attrs); struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -11683,11 +11810,11 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, wdev_lock(wdev); err = nl80211_parse_tx_bitrate_mask(info, info->attrs, NL80211_ATTR_TX_RATES, &mask, - dev, true); + dev, true, link_id); if (err) goto out;
- err = rdev_set_bitrate_mask(rdev, dev, NULL, &mask); + err = rdev_set_bitrate_mask(rdev, dev, link_id, NULL, &mask); out: wdev_unlock(wdev); return err; @@ -11812,7 +11939,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) return -EINVAL;
wdev_lock(wdev); - if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) { + if (params.offchan && + !cfg80211_off_channel_oper_allowed(wdev, chandef.chan)) { wdev_unlock(wdev); return -EBUSY; } @@ -12030,12 +12158,13 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, * connection is established and enough beacons received to calculate * the average. */ - if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss && + if (!wdev->cqm_config->last_rssi_event_value && + wdev->links[0].client.current_bss && rdev->ops->get_station) { struct station_info sinfo = {}; u8 *mac_addr;
- mac_addr = wdev->current_bss->pub.bssid; + mac_addr = wdev->links[0].client.current_bss->pub.bssid;
err = rdev_get_station(rdev, dev, mac_addr, &sinfo); if (err) @@ -12298,7 +12427,7 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) err = nl80211_parse_tx_bitrate_mask(info, info->attrs, NL80211_ATTR_TX_RATES, &setup.beacon_rate, - dev, false); + dev, false, 0); if (err) return err;
@@ -13268,7 +13397,7 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) rekey_data.akm = nla_get_u32(tb[NL80211_REKEY_DATA_AKM]);
wdev_lock(wdev); - if (!wdev->current_bss) { + if (!wdev->connected) { err = -ENOTCONN; goto out; } @@ -14537,7 +14666,7 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info) switch (wdev->iftype) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: - if (wdev->current_bss) + if (wdev->connected) break; err = -ENOTCONN; goto out; @@ -14710,13 +14839,13 @@ static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info) return -EINVAL;
wdev_lock(wdev); - if (!wdev->current_bss) { + if (!wdev->connected) { ret = -ENOTCONN; goto out; }
pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]); - if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) { + if (memcmp(pmk_conf.aa, wdev->u.client.connected_addr, ETH_ALEN)) { ret = -EINVAL; goto out; } @@ -14844,9 +14973,13 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info) case NL80211_IFTYPE_MESH_POINT: break; case NL80211_IFTYPE_ADHOC: + if (wdev->u.ibss.current_bss) + break; + err = -ENOTCONN; + goto out; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: - if (wdev->current_bss) + if (wdev->connected) break; err = -ENOTCONN; goto out; @@ -14882,12 +15015,14 @@ static int nl80211_get_ftm_responder_stats(struct sk_buff *skb, struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_ftm_responder_stats ftm_stats = {}; + unsigned int link_id = nl80211_link_id(info->attrs); struct sk_buff *msg; void *hdr; struct nlattr *ftm_stats_attr; int err;
- if (wdev->iftype != NL80211_IFTYPE_AP || !wdev->beacon_interval) + if (wdev->iftype != NL80211_IFTYPE_AP || + !wdev->links[link_id].ap.beacon_interval) return -EOPNOTSUPP;
err = rdev_get_ftm_responder_stats(rdev, dev, &ftm_stats); @@ -15017,7 +15152,8 @@ static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info) static int parse_tid_conf(struct cfg80211_registered_device *rdev, struct nlattr *attrs[], struct net_device *dev, struct cfg80211_tid_cfg *tid_conf, - struct genl_info *info, const u8 *peer) + struct genl_info *info, const u8 *peer, + unsigned int link_id) { struct netlink_ext_ack *extack = info->extack; u64 mask; @@ -15092,7 +15228,7 @@ static int parse_tid_conf(struct cfg80211_registered_device *rdev, attr = NL80211_TID_CONFIG_ATTR_TX_RATE; err = nl80211_parse_tx_bitrate_mask(info, attrs, attr, &tid_conf->txrate_mask, dev, - true); + true, link_id); if (err) return err;
@@ -15119,6 +15255,7 @@ static int nl80211_set_tid_config(struct sk_buff *skb, { struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct nlattr *attrs[NL80211_TID_CONFIG_ATTR_MAX + 1]; + unsigned int link_id = nl80211_link_id(info->attrs); struct net_device *dev = info->user_ptr[1]; struct cfg80211_tid_config *tid_config; struct nlattr *tid; @@ -15156,7 +15293,7 @@ static int nl80211_set_tid_config(struct sk_buff *skb,
ret = parse_tid_conf(rdev, attrs, dev, &tid_config->tid_conf[conf_idx], - info, tid_config->peer); + info, tid_config->peer, link_id); if (ret) goto bad_tid_conf;
@@ -15295,6 +15432,62 @@ static int nl80211_set_fils_aad(struct sk_buff *skb, return rdev_set_fils_aad(rdev, dev, &fils_aad); }
+static int nl80211_add_link(struct sk_buff *skb, struct genl_info *info) +{ + unsigned int link_id = nl80211_link_id(info->attrs); + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; + + if (!(wdev->wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO)) + return -EINVAL; + + switch (wdev->iftype) { + case NL80211_IFTYPE_AP: + break; + default: + return -EINVAL; + } + + if (!info->attrs[NL80211_ATTR_MAC] || + !is_valid_ether_addr(nla_data(info->attrs[NL80211_ATTR_MAC]))) + return -EINVAL; + + wdev_lock(wdev); + wdev->valid_links |= BIT(link_id); + ether_addr_copy(wdev->links[link_id].addr, + nla_data(info->attrs[NL80211_ATTR_MAC])); + wdev_unlock(wdev); + + return 0; +} + +static int nl80211_remove_link(struct sk_buff *skb, struct genl_info *info) +{ + unsigned int link_id = nl80211_link_id(info->attrs); + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; + + /* cannot remove if there's no link */ + if (!info->attrs[NL80211_ATTR_MLO_LINK_ID]) + return -EINVAL; + + switch (wdev->iftype) { + case NL80211_IFTYPE_AP: + break; + default: + return -EINVAL; + } + + /* FIXME: stop the link operations first */ + + wdev_lock(wdev); + wdev->valid_links &= ~BIT(link_id); + eth_zero_addr(wdev->links[link_id].addr); + wdev_unlock(wdev); + + return 0; +} + #define NL80211_FLAG_NEED_WIPHY 0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 @@ -15307,6 +15500,8 @@ static int nl80211_set_fils_aad(struct sk_buff *skb, NL80211_FLAG_CHECK_NETDEV_UP) #define NL80211_FLAG_CLEAR_SKB 0x20 #define NL80211_FLAG_NO_WIPHY_MTX 0x40 +#define NL80211_FLAG_MLO_VALID_LINK_ID 0x80 +#define NL80211_FLAG_MLO_UNSUPPORTED 0x100
#define INTERNAL_FLAG_SELECTORS(__sel) \ SELECTOR(__sel, NONE, 0) /* must be first */ \ @@ -15316,6 +15511,12 @@ static int nl80211_set_fils_aad(struct sk_buff *skb, NL80211_FLAG_NEED_WDEV) \ SELECTOR(__sel, NETDEV, \ NL80211_FLAG_NEED_NETDEV) \ + SELECTOR(__sel, NETDEV_LINK, \ + NL80211_FLAG_NEED_NETDEV | \ + NL80211_FLAG_MLO_VALID_LINK_ID) \ + SELECTOR(__sel, NETDEV_NO_MLO, \ + NL80211_FLAG_NEED_NETDEV | \ + NL80211_FLAG_MLO_UNSUPPORTED) \ SELECTOR(__sel, WIPHY_RTNL, \ NL80211_FLAG_NEED_WIPHY | \ NL80211_FLAG_NEED_RTNL) \ @@ -15331,14 +15532,31 @@ static int nl80211_set_fils_aad(struct sk_buff *skb, NL80211_FLAG_NEED_RTNL) \ SELECTOR(__sel, NETDEV_UP, \ NL80211_FLAG_NEED_NETDEV_UP) \ + SELECTOR(__sel, NETDEV_UP_LINK, \ + NL80211_FLAG_NEED_NETDEV_UP | \ + NL80211_FLAG_MLO_VALID_LINK_ID) \ + SELECTOR(__sel, NETDEV_UP_NO_MLO, \ + NL80211_FLAG_NEED_NETDEV_UP | \ + NL80211_FLAG_MLO_UNSUPPORTED) \ + SELECTOR(__sel, NETDEV_UP_NO_MLO_CLEAR, \ + NL80211_FLAG_NEED_NETDEV_UP | \ + NL80211_FLAG_CLEAR_SKB | \ + NL80211_FLAG_MLO_UNSUPPORTED) \ SELECTOR(__sel, NETDEV_UP_NOTMX, \ NL80211_FLAG_NEED_NETDEV_UP | \ NL80211_FLAG_NO_WIPHY_MTX) \ + SELECTOR(__sel, NETDEV_UP_NOTMX_NOMLO, \ + NL80211_FLAG_NEED_NETDEV_UP | \ + NL80211_FLAG_NO_WIPHY_MTX | \ + NL80211_FLAG_MLO_UNSUPPORTED) \ SELECTOR(__sel, NETDEV_UP_CLEAR, \ NL80211_FLAG_NEED_NETDEV_UP | \ NL80211_FLAG_CLEAR_SKB) \ SELECTOR(__sel, WDEV_UP, \ NL80211_FLAG_NEED_WDEV_UP) \ + SELECTOR(__sel, WDEV_UP_LINK, \ + NL80211_FLAG_NEED_WDEV_UP | \ + NL80211_FLAG_MLO_VALID_LINK_ID) \ SELECTOR(__sel, WDEV_UP_RTNL, \ NL80211_FLAG_NEED_WDEV_UP | \ NL80211_FLAG_NEED_RTNL) \ @@ -15362,9 +15580,10 @@ static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = NULL; - struct wireless_dev *wdev; - struct net_device *dev; + struct wireless_dev *wdev = NULL; + struct net_device *dev = NULL; u32 internal_flags; + int err;
if (WARN_ON(ops->internal_flags >= ARRAY_SIZE(nl80211_internal_flags))) return -EINVAL; @@ -15375,8 +15594,8 @@ static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, if (internal_flags & NL80211_FLAG_NEED_WIPHY) { rdev = cfg80211_get_dev_from_info(genl_info_net(info), info); if (IS_ERR(rdev)) { - rtnl_unlock(); - return PTR_ERR(rdev); + err = PTR_ERR(rdev); + goto out_unlock; } info->user_ptr[0] = rdev; } else if (internal_flags & NL80211_FLAG_NEED_NETDEV || @@ -15384,17 +15603,18 @@ static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, wdev = __cfg80211_wdev_from_attrs(NULL, genl_info_net(info), info->attrs); if (IS_ERR(wdev)) { - rtnl_unlock(); - return PTR_ERR(wdev); + err = PTR_ERR(wdev); + goto out_unlock; }
dev = wdev->netdev; + dev_hold(dev); rdev = wiphy_to_rdev(wdev->wiphy);
if (internal_flags & NL80211_FLAG_NEED_NETDEV) { if (!dev) { - rtnl_unlock(); - return -EINVAL; + err = -EINVAL; + goto out_unlock; }
info->user_ptr[1] = dev; @@ -15404,14 +15624,44 @@ static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
if (internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && !wdev_running(wdev)) { - rtnl_unlock(); - return -ENETDOWN; + err = -ENETDOWN; + goto out_unlock; }
- dev_hold(dev); info->user_ptr[0] = rdev; }
+ if (internal_flags & NL80211_FLAG_MLO_VALID_LINK_ID) { + struct nlattr *link_id = info->attrs[NL80211_ATTR_MLO_LINK_ID]; + + if (!wdev) { + err = -EINVAL; + goto out_unlock; + } + + /* MLO -> require valid link ID */ + if (wdev->valid_links && + (!link_id || + !(wdev->valid_links & BIT(nla_get_u16(link_id))))) { + err = -EINVAL; + goto out_unlock; + } + + /* non-MLO -> no link ID attribute accepted */ + if (!wdev->valid_links && link_id) { + err = -EINVAL; + goto out_unlock; + } + } + + if (internal_flags & NL80211_FLAG_MLO_UNSUPPORTED) { + if (info->attrs[NL80211_ATTR_MLO_LINK_ID] || + (wdev && wdev->valid_links)) { + err = -EINVAL; + goto out_unlock; + } + } + if (rdev && !(internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) { wiphy_lock(&rdev->wiphy); /* we keep the mutex locked until post_doit */ @@ -15421,6 +15671,10 @@ static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, rtnl_unlock();
return 0; +out_unlock: + rtnl_unlock(); + dev_put(dev); + return err; }
static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb, @@ -15636,6 +15890,7 @@ static const struct genl_small_ops nl80211_small_ops[] = { .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .doit = nl80211_set_key, .flags = GENL_UNS_ADMIN_PERM, + /* cannot use NL80211_FLAG_MLO_VALID_LINK_ID, depends on key */ .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_CLEAR_SKB), }, @@ -15659,21 +15914,24 @@ static const struct genl_small_ops nl80211_small_ops[] = { .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .flags = GENL_UNS_ADMIN_PERM, .doit = nl80211_set_beacon, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP), + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_MLO_VALID_LINK_ID), }, { .cmd = NL80211_CMD_START_AP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .flags = GENL_UNS_ADMIN_PERM, .doit = nl80211_start_ap, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP), + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_MLO_VALID_LINK_ID), }, { .cmd = NL80211_CMD_STOP_AP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .flags = GENL_UNS_ADMIN_PERM, .doit = nl80211_stop_ap, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP), + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_MLO_VALID_LINK_ID), }, { .cmd = NL80211_CMD_GET_STATION, @@ -15939,7 +16197,9 @@ static const struct genl_small_ops nl80211_small_ops[] = { .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .doit = nl80211_remain_on_channel, .flags = GENL_UNS_ADMIN_PERM, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP), + /* FIXME: requiring a link ID here is probably not good */ + .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP | + NL80211_FLAG_MLO_VALID_LINK_ID), }, { .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, @@ -15953,7 +16213,8 @@ static const struct genl_small_ops nl80211_small_ops[] = { .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .doit = nl80211_set_tx_bitrate_mask, .flags = GENL_UNS_ADMIN_PERM, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV), + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_MLO_VALID_LINK_ID), }, { .cmd = NL80211_CMD_REGISTER_FRAME, @@ -16002,7 +16263,8 @@ static const struct genl_small_ops nl80211_small_ops[] = { .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .doit = nl80211_set_channel, .flags = GENL_UNS_ADMIN_PERM, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV), + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_MLO_VALID_LINK_ID), }, { .cmd = NL80211_CMD_JOIN_MESH, @@ -16163,7 +16425,8 @@ static const struct genl_small_ops nl80211_small_ops[] = { .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .doit = nl80211_set_mac_acl, .flags = GENL_UNS_ADMIN_PERM, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV), + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_MLO_UNSUPPORTED), }, { .cmd = NL80211_CMD_RADAR_DETECT, @@ -16171,7 +16434,8 @@ static const struct genl_small_ops nl80211_small_ops[] = { .doit = nl80211_start_radar_detection, .flags = GENL_UNS_ADMIN_PERM, .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | - NL80211_FLAG_NO_WIPHY_MTX), + NL80211_FLAG_NO_WIPHY_MTX | + NL80211_FLAG_MLO_UNSUPPORTED), }, { .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES, @@ -16217,7 +16481,8 @@ static const struct genl_small_ops nl80211_small_ops[] = { .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .doit = nl80211_channel_switch, .flags = GENL_UNS_ADMIN_PERM, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP), + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_MLO_VALID_LINK_ID), }, { .cmd = NL80211_CMD_VENDOR, @@ -16240,7 +16505,8 @@ static const struct genl_small_ops nl80211_small_ops[] = { .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .doit = nl80211_add_tx_ts, .flags = GENL_UNS_ADMIN_PERM, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP), + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_MLO_UNSUPPORTED), }, { .cmd = NL80211_CMD_DEL_TX_TS, @@ -16301,7 +16567,8 @@ static const struct genl_small_ops nl80211_small_ops[] = { .cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .doit = nl80211_get_ftm_responder_stats, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV), + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_MLO_VALID_LINK_ID), }, { .cmd = NL80211_CMD_PEER_MEASUREMENT_START, @@ -16333,7 +16600,8 @@ static const struct genl_small_ops nl80211_small_ops[] = { .cmd = NL80211_CMD_SET_TID_CONFIG, .doit = nl80211_set_tid_config, .flags = GENL_UNS_ADMIN_PERM, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV), + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_MLO_VALID_LINK_ID), }, { .cmd = NL80211_CMD_SET_SAR_SPECS, @@ -16357,6 +16625,19 @@ static const struct genl_small_ops nl80211_small_ops[] = { .flags = GENL_UNS_ADMIN_PERM, .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP), }, + { + .cmd = NL80211_CMD_ADD_LINK, + .doit = nl80211_add_link, + .flags = GENL_UNS_ADMIN_PERM, + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP), + }, + { + .cmd = NL80211_CMD_REMOVE_LINK, + .doit = nl80211_remove_link, + .flags = GENL_UNS_ADMIN_PERM, + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_MLO_VALID_LINK_ID), + }, };
static struct genl_family nl80211_fam __ro_after_init = { @@ -17984,23 +18265,37 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, }
void cfg80211_ch_switch_notify(struct net_device *dev, - struct cfg80211_chan_def *chandef) + struct cfg80211_chan_def *chandef, + unsigned int link_id) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ASSERT_WDEV_LOCK(wdev); + WARN_INVALID_LINK_ID(wdev, link_id);
- trace_cfg80211_ch_switch_notify(dev, chandef); - - wdev->chandef = *chandef; - wdev->preset_chandef = *chandef; + trace_cfg80211_ch_switch_notify(dev, chandef, link_id);
- if ((wdev->iftype == NL80211_IFTYPE_STATION || - wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && - !WARN_ON(!wdev->current_bss)) - cfg80211_update_assoc_bss_entry(wdev, chandef->chan); + switch (wdev->iftype) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + if (!WARN_ON(!wdev->links[link_id].client.current_bss)) + cfg80211_update_assoc_bss_entry(wdev, link_id, + chandef->chan); + break; + case NL80211_IFTYPE_MESH_POINT: + wdev->u.mesh.chandef = *chandef; + wdev->u.mesh.preset_chandef = *chandef; + break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + wdev->links[link_id].ap.chandef = *chandef; + break; + default: + WARN_ON(1); + break; + }
cfg80211_sched_dfs_chan_update(rdev);
diff --git a/net/wireless/ocb.c b/net/wireless/ocb.c index 2d26a6d980bf..27a1732264f9 100644 --- a/net/wireless/ocb.c +++ b/net/wireless/ocb.c @@ -4,6 +4,7 @@ * * Copyright: (c) 2014 Czech Technical University in Prague * (c) 2014 Volkswagen Group Research + * Copyright (C) 2022 Intel Corporation * Author: Rostislav Lisovy rostislav.lisovy@fel.cvut.cz * Funded by: Volkswagen Group Research */ @@ -34,7 +35,7 @@ int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
err = rdev_join_ocb(rdev, dev, setup); if (!err) - wdev->chandef = setup->chandef; + wdev->u.ocb.chandef = setup->chandef;
return err; } @@ -69,7 +70,7 @@ int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
err = rdev_leave_ocb(rdev, dev); if (!err) - memset(&wdev->chandef, 0, sizeof(wdev->chandef)); + memset(&wdev->u.ocb.chandef, 0, sizeof(wdev->u.ocb.chandef));
return err; } diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 439bcf52369c..d2300eff03ae 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -1,4 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0 */ +/* + * Portions of this file + * Copyright(c) 2016-2017 Intel Deutschland GmbH + * Copyright (C) 2018, 2021-2022 Intel Corporation + */ #ifndef __CFG80211_RDEV_OPS #define __CFG80211_RDEV_OPS
@@ -172,11 +177,11 @@ static inline int rdev_change_beacon(struct cfg80211_registered_device *rdev, }
static inline int rdev_stop_ap(struct cfg80211_registered_device *rdev, - struct net_device *dev) + struct net_device *dev, unsigned int link_id) { int ret; - trace_rdev_stop_ap(&rdev->wiphy, dev); - ret = rdev->ops->stop_ap(&rdev->wiphy, dev); + trace_rdev_stop_ap(&rdev->wiphy, dev, link_id); + ret = rdev->ops->stop_ap(&rdev->wiphy, dev, link_id); trace_rdev_return_int(&rdev->wiphy, ret); return ret; } @@ -651,12 +656,14 @@ static inline int rdev_testmode_dump(struct cfg80211_registered_device *rdev,
static inline int rdev_set_bitrate_mask(struct cfg80211_registered_device *rdev, - struct net_device *dev, const u8 *peer, + struct net_device *dev, unsigned int link_id, + const u8 *peer, const struct cfg80211_bitrate_mask *mask) { int ret; - trace_rdev_set_bitrate_mask(&rdev->wiphy, dev, peer, mask); - ret = rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, peer, mask); + trace_rdev_set_bitrate_mask(&rdev->wiphy, dev, link_id, peer, mask); + ret = rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, link_id, + peer, mask); trace_rdev_return_int(&rdev->wiphy, ret); return ret; } @@ -944,12 +951,13 @@ static inline int rdev_set_noack_map(struct cfg80211_registered_device *rdev, static inline int rdev_get_channel(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, + unsigned int link_id, struct cfg80211_chan_def *chandef) { int ret;
- trace_rdev_get_channel(&rdev->wiphy, wdev); - ret = rdev->ops->get_channel(&rdev->wiphy, wdev, chandef); + trace_rdev_get_channel(&rdev->wiphy, wdev, link_id); + ret = rdev->ops->get_channel(&rdev->wiphy, wdev, link_id, chandef); trace_rdev_return_chandef(&rdev->wiphy, ret, chandef);
return ret; @@ -1107,12 +1115,14 @@ static inline int rdev_set_qos_map(struct cfg80211_registered_device *rdev,
static inline int rdev_set_ap_chanwidth(struct cfg80211_registered_device *rdev, - struct net_device *dev, struct cfg80211_chan_def *chandef) + struct net_device *dev, + unsigned int link_id, + struct cfg80211_chan_def *chandef) { int ret;
- trace_rdev_set_ap_chanwidth(&rdev->wiphy, dev, chandef); - ret = rdev->ops->set_ap_chanwidth(&rdev->wiphy, dev, chandef); + trace_rdev_set_ap_chanwidth(&rdev->wiphy, dev, link_id, chandef); + ret = rdev->ops->set_ap_chanwidth(&rdev->wiphy, dev, link_id, chandef); trace_rdev_return_int(&rdev->wiphy, ret);
return ret; diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 58e83ce642ad..c7383ede794f 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -5,7 +5,7 @@ * Copyright 2008-2011 Luis R. Rodriguez mcgrof@qca.qualcomm.com * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2017 Intel Deutschland GmbH - * Copyright (C) 2018 - 2021 Intel Corporation + * Copyright (C) 2018 - 2022 Intel Corporation * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -2370,6 +2370,7 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); enum nl80211_iftype iftype; bool ret; + int link;
wdev_lock(wdev); iftype = wdev->iftype; @@ -2378,62 +2379,83 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) if (!wdev->netdev || !netif_running(wdev->netdev)) goto wdev_inactive_unlock;
- switch (iftype) { - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_P2P_GO: - case NL80211_IFTYPE_MESH_POINT: - if (!wdev->beacon_interval) - goto wdev_inactive_unlock; - chandef = wdev->chandef; - break; - case NL80211_IFTYPE_ADHOC: - if (!wdev->ssid_len) - goto wdev_inactive_unlock; - chandef = wdev->chandef; - break; - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_P2P_CLIENT: - if (!wdev->current_bss || - !wdev->current_bss->pub.channel) - goto wdev_inactive_unlock; - - if (!rdev->ops->get_channel || - rdev_get_channel(rdev, wdev, &chandef)) - cfg80211_chandef_create(&chandef, - wdev->current_bss->pub.channel, - NL80211_CHAN_NO_HT); - break; - case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_P2P_DEVICE: - /* no enforcement required */ - break; - default: - /* others not implemented for now */ - WARN_ON(1); - break; - } + for (link = 0; link < ARRAY_SIZE(wdev->links); link++) { + struct ieee80211_channel *chan;
- wdev_unlock(wdev); + if (!wdev->valid_links && link > 0) + break; + if (!(wdev->valid_links & BIT(link))) + continue; + switch (iftype) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_MESH_POINT: + if (!wdev->u.mesh.beacon_interval) + continue; + chandef = wdev->u.mesh.chandef; + break; + case NL80211_IFTYPE_ADHOC: + if (!wdev->u.ibss.ssid_len) + continue; + chandef = wdev->u.ibss.chandef; + break; + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + /* Maybe we could consider disabling that link only? */ + if (!wdev->links[link].client.current_bss) + continue;
- switch (iftype) { - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_P2P_GO: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_MESH_POINT: - wiphy_lock(wiphy); - ret = cfg80211_reg_can_beacon_relax(wiphy, &chandef, iftype); - wiphy_unlock(wiphy); + chan = wdev->links[link].client.current_bss->pub.channel; + if (!chan) + continue;
- return ret; - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_P2P_CLIENT: - return cfg80211_chandef_usable(wiphy, &chandef, - IEEE80211_CHAN_DISABLED); - default: - break; + if (!rdev->ops->get_channel || + rdev_get_channel(rdev, wdev, link, &chandef)) + cfg80211_chandef_create(&chandef, chan, + NL80211_CHAN_NO_HT); + break; + case NL80211_IFTYPE_MONITOR: + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_DEVICE: + /* no enforcement required */ + break; + default: + /* others not implemented for now */ + WARN_ON(1); + break; + } + + wdev_unlock(wdev); + + switch (iftype) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + wiphy_lock(wiphy); + ret = cfg80211_reg_can_beacon_relax(wiphy, &chandef, + iftype); + wiphy_unlock(wiphy); + + if (!ret) + return ret; + break; + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + ret = cfg80211_chandef_usable(wiphy, &chandef, + IEEE80211_CHAN_DISABLED); + if (!ret) + return ret; + break; + default: + break; + } + + wdev_lock(wdev); }
+ wdev_unlock(wdev); + return true;
wdev_inactive_unlock: @@ -4215,8 +4237,17 @@ static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev) * In both cases we should end the CAC on the wdev. */ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { - if (wdev->cac_started && - !cfg80211_chandef_dfs_usable(&rdev->wiphy, &wdev->chandef)) + struct cfg80211_chan_def *chandef; + + if (!wdev->cac_started) + continue; + + /* FIXME: radar detection is tied to link 0 for now */ + chandef = wdev_chandef(wdev, 0); + if (!chandef) + continue; + + if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef)) rdev_end_cac(rdev, wdev->netdev); } } diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 6d82bd9eaf8c..0134e5d5c81a 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -5,7 +5,7 @@ * Copyright 2008 Johannes Berg johannes@sipsolutions.net * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2016 Intel Deutschland GmbH - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation */ #include <linux/kernel.h> #include <linux/slab.h> @@ -2617,7 +2617,8 @@ void cfg80211_bss_iter(struct wiphy *wiphy, spin_lock_bh(&rdev->bss_lock);
list_for_each_entry(bss, &rdev->bss_list, list) { - if (!chandef || cfg80211_is_sub_chan(chandef, bss->pub.channel)) + if (!chandef || cfg80211_is_sub_chan(chandef, bss->pub.channel, + false)) iter(wiphy, &bss->pub, iter_data); }
@@ -2626,11 +2627,12 @@ void cfg80211_bss_iter(struct wiphy *wiphy, EXPORT_SYMBOL(cfg80211_bss_iter);
void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev, + unsigned int link_id, struct ieee80211_channel *chan) { struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - struct cfg80211_internal_bss *cbss = wdev->current_bss; + struct cfg80211_internal_bss *cbss = wdev->links[link_id].client.current_bss; struct cfg80211_internal_bss *new = NULL; struct cfg80211_internal_bss *bss; struct cfg80211_bss *nontrans_bss; diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 607a68911047..ca674649d787 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -5,7 +5,7 @@ * (for nl80211's connect() and wext) * * Copyright 2009 Johannes Berg johannes@sipsolutions.net - * Copyright (C) 2009, 2020 Intel Corporation. All rights reserved. + * Copyright (C) 2009, 2020, 2022 Intel Corporation. All rights reserved. * Copyright 2017 Intel Deutschland GmbH */
@@ -454,6 +454,20 @@ void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev) schedule_work(&rdev->conn_work); }
+static void cfg80211_wdev_release_bsses(struct wireless_dev *wdev) +{ + unsigned int link; + + for_each_valid_link(wdev, link) { + if (!wdev->links[link].client.current_bss) + continue; + cfg80211_unhold_bss(wdev->links[link].client.current_bss); + cfg80211_put_bss(wdev->wiphy, + &wdev->links[link].client.current_bss->pub); + wdev->links[link].client.current_bss = NULL; + } +} + static int cfg80211_sme_get_conn_ies(struct wireless_dev *wdev, const u8 *ies, size_t ies_len, const u8 **out_ies, size_t *out_ies_len) @@ -521,12 +535,11 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev, if (!rdev->ops->auth || !rdev->ops->assoc) return -EOPNOTSUPP;
- if (wdev->current_bss) { - cfg80211_unhold_bss(wdev->current_bss); - cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); - wdev->current_bss = NULL; + cfg80211_wdev_release_bsses(wdev);
+ if (wdev->connected) { cfg80211_sme_free(wdev); + wdev->connected = false; }
if (wdev->conn) @@ -563,8 +576,8 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev, wdev->conn->auto_auth = false; }
- wdev->conn->params.ssid = wdev->ssid; - wdev->conn->params.ssid_len = wdev->ssid_len; + wdev->conn->params.ssid = wdev->u.client.ssid; + wdev->conn->params.ssid_len = wdev->u.client.ssid_len;
/* see if we have the bss already */ bss = cfg80211_get_conn_bss(wdev); @@ -648,7 +661,7 @@ static bool cfg80211_is_all_idle(void) list_for_each_entry(rdev, &cfg80211_rdev_list, list) { list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { wdev_lock(wdev); - if (wdev->conn || wdev->current_bss || + if (wdev->conn || wdev->connected || cfg80211_beaconing_iface_active(wdev)) is_all_idle = false; wdev_unlock(wdev); @@ -668,7 +681,6 @@ static void disconnect_work(struct work_struct *work)
DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
- /* * API calls for drivers implementing connect/disconnect and * SME event handling @@ -729,23 +741,19 @@ void __cfg80211_connect_result(struct net_device *dev, if (!cr->bss && (cr->status == WLAN_STATUS_SUCCESS)) { WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect); cr->bss = cfg80211_get_bss(wdev->wiphy, NULL, cr->bssid, - wdev->ssid, wdev->ssid_len, + wdev->u.client.ssid, wdev->u.client.ssid_len, wdev->conn_bss_type, IEEE80211_PRIVACY_ANY); if (cr->bss) cfg80211_hold_bss(bss_from_pub(cr->bss)); }
- if (wdev->current_bss) { - cfg80211_unhold_bss(wdev->current_bss); - cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); - wdev->current_bss = NULL; - } + cfg80211_wdev_release_bsses(wdev);
if (cr->status != WLAN_STATUS_SUCCESS) { kfree_sensitive(wdev->connect_keys); wdev->connect_keys = NULL; - wdev->ssid_len = 0; + wdev->u.client.ssid_len = 0; wdev->conn_owner_nlportid = 0; if (cr->bss) { cfg80211_unhold_bss(bss_from_pub(cr->bss)); @@ -758,7 +766,9 @@ void __cfg80211_connect_result(struct net_device *dev, if (WARN_ON(!cr->bss)) return;
- wdev->current_bss = bss_from_pub(cr->bss); + wdev->links[0].client.current_bss = bss_from_pub(cr->bss); + wdev->connected = true; + ether_addr_copy(wdev->u.client.connected_addr, cr->bss->bssid);
if (!(wdev->wiphy->flags & WIPHY_FLAG_HAS_STATIC_WEP)) cfg80211_upload_connect_keys(wdev); @@ -801,7 +811,7 @@ void cfg80211_connect_done(struct net_device *dev,
found = cfg80211_get_bss(wdev->wiphy, NULL, params->bss->bssid, - wdev->ssid, wdev->ssid_len, + wdev->u.client.ssid, wdev->u.client.ssid_len, wdev->conn_bss_type, IEEE80211_PRIVACY_ANY); if (found) { @@ -906,18 +916,17 @@ void __cfg80211_roamed(struct wireless_dev *wdev, wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) goto out;
- if (WARN_ON(!wdev->current_bss)) + if (WARN_ON(!wdev->connected)) goto out;
- cfg80211_unhold_bss(wdev->current_bss); - cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); - wdev->current_bss = NULL; + cfg80211_wdev_release_bsses(wdev);
if (WARN_ON(!info->bss)) return;
cfg80211_hold_bss(bss_from_pub(info->bss)); - wdev->current_bss = bss_from_pub(info->bss); + wdev->links[0].client.current_bss = bss_from_pub(info->bss); + ether_addr_copy(wdev->u.client.connected_addr, info->bss->bssid);
wdev->unprot_beacon_reported = 0; nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy), @@ -963,8 +972,8 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
if (!info->bss) { info->bss = cfg80211_get_bss(wdev->wiphy, info->channel, - info->bssid, wdev->ssid, - wdev->ssid_len, + info->bssid, wdev->u.client.ssid, + wdev->u.client.ssid_len, wdev->conn_bss_type, IEEE80211_PRIVACY_ANY); } @@ -1035,8 +1044,8 @@ void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid) wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) return;
- if (WARN_ON(!wdev->current_bss) || - WARN_ON(!ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) + if (WARN_ON(!wdev->connected) || + WARN_ON(!ether_addr_equal(wdev->u.client.connected_addr, bssid))) return;
nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev, @@ -1088,13 +1097,9 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) return;
- if (wdev->current_bss) { - cfg80211_unhold_bss(wdev->current_bss); - cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); - } - - wdev->current_bss = NULL; - wdev->ssid_len = 0; + cfg80211_wdev_release_bsses(wdev); + wdev->connected = false; + wdev->u.client.ssid_len = 0; wdev->conn_owner_nlportid = 0; kfree_sensitive(wdev->connect_keys); wdev->connect_keys = NULL; @@ -1183,19 +1188,20 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, * already connected, so reject a new SSID unless it's the * same (which is the case for re-association.) */ - if (wdev->ssid_len && - (wdev->ssid_len != connect->ssid_len || - memcmp(wdev->ssid, connect->ssid, wdev->ssid_len))) + if (wdev->u.client.ssid_len && + (wdev->u.client.ssid_len != connect->ssid_len || + memcmp(wdev->u.client.ssid, connect->ssid, wdev->u.client.ssid_len))) return -EALREADY;
/* * If connected, reject (re-)association unless prev_bssid * matches the current BSSID. */ - if (wdev->current_bss) { + if (wdev->connected) { if (!prev_bssid) return -EALREADY; - if (!ether_addr_equal(prev_bssid, wdev->current_bss->pub.bssid)) + if (!ether_addr_equal(prev_bssid, + wdev->u.client.connected_addr)) return -ENOTCONN; }
@@ -1246,8 +1252,8 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, }
wdev->connect_keys = connkeys; - memcpy(wdev->ssid, connect->ssid, connect->ssid_len); - wdev->ssid_len = connect->ssid_len; + memcpy(wdev->u.client.ssid, connect->ssid, connect->ssid_len); + wdev->u.client.ssid_len = connect->ssid_len;
wdev->conn_bss_type = connect->pbss ? IEEE80211_BSS_TYPE_PBSS : IEEE80211_BSS_TYPE_ESS; @@ -1263,8 +1269,8 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, * This could be reassoc getting refused, don't clear * ssid_len in that case. */ - if (!wdev->current_bss) - wdev->ssid_len = 0; + if (!wdev->connected) + wdev->u.client.ssid_len = 0; return err; }
@@ -1288,7 +1294,7 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev, err = cfg80211_sme_disconnect(wdev, reason); else if (!rdev->ops->disconnect) cfg80211_mlme_down(rdev, dev); - else if (wdev->ssid_len) + else if (wdev->u.client.ssid_len) err = rdev_disconnect(rdev, dev, reason);
/* @@ -1296,8 +1302,8 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev, * in which case cfg80211_disconnected() will take care of * this later. */ - if (!wdev->current_bss) - wdev->ssid_len = 0; + if (!wdev->connected) + wdev->u.client.ssid_len = 0;
return err; } @@ -1321,7 +1327,7 @@ void cfg80211_autodisconnect_wk(struct work_struct *work) break; case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: - __cfg80211_stop_ap(rdev, wdev->netdev, false); + __cfg80211_stop_ap(rdev, wdev->netdev, -1, false); break; case NL80211_IFTYPE_MESH_POINT: __cfg80211_leave_mesh(rdev, wdev->netdev); @@ -1333,7 +1339,7 @@ void cfg80211_autodisconnect_wk(struct work_struct *work) * ops->disconnect not implemented. Otherwise we can * use cfg80211_disconnect. */ - if (rdev->ops->disconnect || wdev->current_bss) + if (rdev->ops->disconnect || wdev->connected) cfg80211_disconnect(rdev, wdev->netdev, WLAN_REASON_DEAUTH_LEAVING, true); diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 228079d7690a..3b2c956b8d78 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -569,6 +569,7 @@ TRACE_EVENT(rdev_start_ap, __field(bool, privacy) __field(enum nl80211_auth_type, auth_type) __field(int, inactivity_timeout) + __field(unsigned int, link_id) ), TP_fast_assign( WIPHY_ASSIGN; @@ -583,16 +584,17 @@ TRACE_EVENT(rdev_start_ap, __entry->inactivity_timeout = settings->inactivity_timeout; memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1); memcpy(__entry->ssid, settings->ssid, settings->ssid_len); + __entry->link_id = settings->beacon.link_id; ), TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", AP settings - ssid: %s, " CHAN_DEF_PR_FMT ", beacon interval: %d, dtim period: %d, " "hidden ssid: %d, wpa versions: %u, privacy: %s, " - "auth type: %d, inactivity timeout: %d", + "auth type: %d, inactivity timeout: %d, link_id: %d", WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ssid, CHAN_DEF_PR_ARG, __entry->beacon_interval, __entry->dtim_period, __entry->hidden_ssid, __entry->wpa_ver, BOOL_TO_STR(__entry->privacy), __entry->auth_type, - __entry->inactivity_timeout) + __entry->inactivity_timeout, __entry->link_id) );
TRACE_EVENT(rdev_change_beacon, @@ -602,6 +604,7 @@ TRACE_EVENT(rdev_change_beacon, TP_STRUCT__entry( WIPHY_ENTRY NETDEV_ENTRY + __field(int, link_id) __dynamic_array(u8, head, info ? info->head_len : 0) __dynamic_array(u8, tail, info ? info->tail_len : 0) __dynamic_array(u8, beacon_ies, info ? info->beacon_ies_len : 0) @@ -615,6 +618,7 @@ TRACE_EVENT(rdev_change_beacon, WIPHY_ASSIGN; NETDEV_ASSIGN; if (info) { + __entry->link_id = info->link_id; if (info->head) memcpy(__get_dynamic_array(head), info->head, info->head_len); @@ -635,9 +639,30 @@ TRACE_EVENT(rdev_change_beacon, if (info->probe_resp) memcpy(__get_dynamic_array(probe_resp), info->probe_resp, info->probe_resp_len); + } else { + __entry->link_id = -1; } ), - TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id:%d", + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id) +); + +TRACE_EVENT(rdev_stop_ap, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + unsigned int link_id), + TP_ARGS(wiphy, netdev, link_id), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + __field(unsigned int, link_id) + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + __entry->link_id = link_id; + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d", + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id) );
DECLARE_EVENT_CLASS(wiphy_netdev_evt, @@ -654,11 +679,6 @@ DECLARE_EVENT_CLASS(wiphy_netdev_evt, TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) );
-DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), - TP_ARGS(wiphy, netdev) -); - DEFINE_EVENT(wiphy_netdev_evt, rdev_set_rekey_data, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), TP_ARGS(wiphy, netdev) @@ -1619,20 +1639,24 @@ TRACE_EVENT(rdev_testmode_dump,
TRACE_EVENT(rdev_set_bitrate_mask, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + unsigned int link_id, const u8 *peer, const struct cfg80211_bitrate_mask *mask), - TP_ARGS(wiphy, netdev, peer, mask), + TP_ARGS(wiphy, netdev, link_id, peer, mask), TP_STRUCT__entry( WIPHY_ENTRY NETDEV_ENTRY + __field(unsigned int, link_id) MAC_ENTRY(peer) ), TP_fast_assign( WIPHY_ASSIGN; NETDEV_ASSIGN; + __entry->link_id = link_id; MAC_ASSIGN(peer, peer); ), - TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer)) + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d, peer: " MAC_PR_FMT, + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id, + MAC_PR_ARG(peer)) );
TRACE_EVENT(rdev_update_mgmt_frame_registrations, @@ -2040,9 +2064,22 @@ TRACE_EVENT(rdev_set_noack_map, WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map) );
-DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), - TP_ARGS(wiphy, wdev) +TRACE_EVENT(rdev_get_channel, + TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, + unsigned int link_id), + TP_ARGS(wiphy, wdev, link_id), + TP_STRUCT__entry( + WIPHY_ENTRY + WDEV_ENTRY + __field(unsigned int, link_id) + ), + TP_fast_assign( + WIPHY_ASSIGN; + WDEV_ASSIGN; + __entry->link_id = link_id; + ), + TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", link_id: %u", + WIPHY_PR_ARG, WDEV_PR_ARG, __entry->link_id) );
TRACE_EVENT(rdev_return_chandef, @@ -2296,20 +2333,24 @@ TRACE_EVENT(rdev_set_qos_map,
TRACE_EVENT(rdev_set_ap_chanwidth, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + unsigned int link_id, struct cfg80211_chan_def *chandef), - TP_ARGS(wiphy, netdev, chandef), + TP_ARGS(wiphy, netdev, link_id, chandef), TP_STRUCT__entry( WIPHY_ENTRY NETDEV_ENTRY CHAN_DEF_ENTRY + __field(unsigned int, link_id) ), TP_fast_assign( WIPHY_ASSIGN; NETDEV_ASSIGN; CHAN_DEF_ASSIGN(chandef); + __entry->link_id = link_id; ), - TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG) + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT ", link:%d", + WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG, + __entry->link_id) );
TRACE_EVENT(rdev_add_tx_ts, @@ -3022,18 +3063,21 @@ TRACE_EVENT(cfg80211_chandef_dfs_required,
TRACE_EVENT(cfg80211_ch_switch_notify, TP_PROTO(struct net_device *netdev, - struct cfg80211_chan_def *chandef), - TP_ARGS(netdev, chandef), + struct cfg80211_chan_def *chandef, + unsigned int link_id), + TP_ARGS(netdev, chandef, link_id), TP_STRUCT__entry( NETDEV_ENTRY CHAN_DEF_ENTRY + __field(unsigned int, link_id) ), TP_fast_assign( NETDEV_ASSIGN; CHAN_DEF_ASSIGN(chandef); + __entry->link_id = link_id; ), - TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT, - NETDEV_PR_ARG, CHAN_DEF_PR_ARG) + TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT ", link:%d", + NETDEV_PR_ARG, CHAN_DEF_PR_ARG, __entry->link_id) );
TRACE_EVENT(cfg80211_ch_switch_started_notify, diff --git a/net/wireless/util.c b/net/wireless/util.c index a60d7d638e72..b7257862e0fe 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -5,7 +5,7 @@ * Copyright 2007-2009 Johannes Berg johannes@sipsolutions.net * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation */ #include <linux/export.h> #include <linux/bitops.h> @@ -1041,7 +1041,6 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, return -EBUSY;
dev->ieee80211_ptr->use_4addr = false; - dev->ieee80211_ptr->mesh_id_up_len = 0; wdev_lock(dev->ieee80211_ptr); rdev_set_qos_map(rdev, dev, NULL); wdev_unlock(dev->ieee80211_ptr); @@ -1049,7 +1048,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, switch (otype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: - cfg80211_stop_ap(rdev, dev, true); + cfg80211_stop_ap(rdev, dev, -1, true); break; case NL80211_IFTYPE_ADHOC: cfg80211_leave_ibss(rdev, dev, false); @@ -1073,6 +1072,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
cfg80211_process_rdev_events(rdev); cfg80211_mlme_purge_registrations(dev->ieee80211_ptr); + + memset(&dev->ieee80211_ptr->u, 0, + sizeof(dev->ieee80211_ptr->u)); + memset(&dev->ieee80211_ptr->links, 0, + sizeof(dev->ieee80211_ptr->links)); }
err = rdev_change_virtual_intf(rdev, dev, ntype, params); @@ -1930,6 +1934,24 @@ bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef, } EXPORT_SYMBOL(ieee80211_chandef_to_operating_class);
+static int cfg80211_wdev_bi(struct wireless_dev *wdev) +{ + switch (wdev->iftype) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + WARN_ON(wdev->valid_links); + return wdev->links[0].ap.beacon_interval; + case NL80211_IFTYPE_MESH_POINT: + return wdev->u.mesh.beacon_interval; + case NL80211_IFTYPE_ADHOC: + return wdev->u.ibss.beacon_interval; + default: + break; + } + + return 0; +} + static void cfg80211_calculate_bi_data(struct wiphy *wiphy, u32 new_beacon_int, u32 *beacon_int_gcd, bool *beacon_int_different) @@ -1940,19 +1962,27 @@ static void cfg80211_calculate_bi_data(struct wiphy *wiphy, u32 new_beacon_int, *beacon_int_different = false;
list_for_each_entry(wdev, &wiphy->wdev_list, list) { - if (!wdev->beacon_interval) + int wdev_bi; + + /* this feature isn't supported with MLO */ + if (wdev->valid_links) + continue; + + wdev_bi = cfg80211_wdev_bi(wdev); + + if (!wdev_bi) continue;
if (!*beacon_int_gcd) { - *beacon_int_gcd = wdev->beacon_interval; + *beacon_int_gcd = wdev_bi; continue; }
- if (wdev->beacon_interval == *beacon_int_gcd) + if (wdev_bi == *beacon_int_gcd) continue;
*beacon_int_different = true; - *beacon_int_gcd = gcd(*beacon_int_gcd, wdev->beacon_interval); + *beacon_int_gcd = gcd(*beacon_int_gcd, wdev_bi); }
if (new_beacon_int && *beacon_int_gcd != new_beacon_int) { diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index a32065d600a1..a9767bfe7330 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -7,7 +7,7 @@ * we directly assign the wireless handlers of wireless interfaces. * * Copyright 2008-2009 Johannes Berg johannes@sipsolutions.net - * Copyright (C) 2019-2021 Intel Corporation + * Copyright (C) 2019-2022 Intel Corporation */
#include <linux/export.h> @@ -415,6 +415,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, int err, i; bool rejoin = false;
+ if (wdev->valid_links) + return -EINVAL; + if (pairwise && !addr) return -EINVAL;
@@ -437,7 +440,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, return -EOPNOTSUPP;
if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { - if (!wdev->current_bss) + if (!wdev->connected) return -ENOLINK;
if (!rdev->ops->set_default_mgmt_key) @@ -450,7 +453,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
if (remove) { err = 0; - if (wdev->current_bss) { + if (wdev->connected || + (wdev->iftype == NL80211_IFTYPE_ADHOC && + wdev->u.ibss.current_bss)) { /* * If removing the current TX key, we will need to * join a new IBSS without the privacy bit clear. @@ -501,7 +506,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, return -EINVAL;
err = 0; - if (wdev->current_bss) + if (wdev->connected || + (wdev->iftype == NL80211_IFTYPE_ADHOC && + wdev->u.ibss.current_bss)) err = rdev_add_key(rdev, dev, idx, pairwise, addr, params); else if (params->cipher != WLAN_CIPHER_SUITE_WEP40 && params->cipher != WLAN_CIPHER_SUITE_WEP104) @@ -526,7 +533,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 || params->cipher == WLAN_CIPHER_SUITE_WEP104) && (tx_key || (!addr && wdev->wext.default_key == -1))) { - if (wdev->current_bss) { + if (wdev->connected || + (wdev->iftype == NL80211_IFTYPE_ADHOC && + wdev->u.ibss.current_bss)) { /* * If we are getting a new TX key from not having * had one before we need to join a new IBSS with @@ -549,7 +558,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC && (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) { - if (wdev->current_bss) + if (wdev->connected || + (wdev->iftype == NL80211_IFTYPE_ADHOC && + wdev->u.ibss.current_bss)) err = rdev_set_default_mgmt_key(rdev, dev, idx); if (!err) wdev->wext.default_mgmt_key = idx; @@ -595,6 +606,11 @@ static int cfg80211_wext_siwencode(struct net_device *dev, return -EOPNOTSUPP;
wiphy_lock(&rdev->wiphy); + if (wdev->valid_links) { + err = -EOPNOTSUPP; + goto out; + } + idx = erq->flags & IW_ENCODE_INDEX; if (idx == 0) { idx = wdev->wext.default_key; @@ -613,7 +629,9 @@ static int cfg80211_wext_siwencode(struct net_device *dev, /* No key data - just set the default TX key index */ err = 0; wdev_lock(wdev); - if (wdev->current_bss) + if (wdev->connected || + (wdev->iftype == NL80211_IFTYPE_ADHOC && + wdev->u.ibss.current_bss)) err = rdev_set_default_key(rdev, dev, idx, true, true); if (!err) @@ -865,7 +883,7 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, break; }
- ret = rdev_get_channel(rdev, wdev, &chandef); + ret = rdev_get_channel(rdev, wdev, 0, &chandef); if (ret) break; freq->m = chandef.chan->center_freq; @@ -1270,7 +1288,10 @@ static int cfg80211_wext_siwrate(struct net_device *dev, return -EINVAL;
wiphy_lock(&rdev->wiphy); - ret = rdev_set_bitrate_mask(rdev, dev, NULL, &mask); + if (dev->ieee80211_ptr->valid_links) + ret = -EOPNOTSUPP; + else + ret = rdev_set_bitrate_mask(rdev, dev, 0, NULL, &mask); wiphy_unlock(&rdev->wiphy);
return ret; @@ -1294,8 +1315,9 @@ static int cfg80211_wext_giwrate(struct net_device *dev,
err = 0; wdev_lock(wdev); - if (wdev->current_bss) - memcpy(addr, wdev->current_bss->pub.bssid, ETH_ALEN); + if (!wdev->valid_links && wdev->links[0].client.current_bss) + memcpy(addr, wdev->links[0].client.current_bss->pub.bssid, + ETH_ALEN); else err = -EOPNOTSUPP; wdev_unlock(wdev); @@ -1339,11 +1361,11 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
/* Grab BSSID of current BSS, if any */ wdev_lock(wdev); - if (!wdev->current_bss) { + if (wdev->valid_links || !wdev->links[0].client.current_bss) { wdev_unlock(wdev); return NULL; } - memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); + memcpy(bssid, wdev->links[0].client.current_bss->pub.bssid, ETH_ALEN); wdev_unlock(wdev);
memset(&sinfo, 0, sizeof(sinfo)); diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index cd09a9042261..68f45afc352d 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -3,7 +3,7 @@ * cfg80211 wext compat for managed mode. * * Copyright 2009 Johannes Berg johannes@sipsolutions.net - * Copyright (C) 2009, 2020-2021 Intel Corporation. + * Copyright (C) 2009, 2020-2022 Intel Corporation */
#include <linux/export.h> @@ -124,9 +124,12 @@ int cfg80211_mgd_wext_giwfreq(struct net_device *dev, if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) return -EINVAL;
+ if (wdev->valid_links) + return -EOPNOTSUPP; + wdev_lock(wdev); - if (wdev->current_bss) - chan = wdev->current_bss->pub.channel; + if (wdev->links[0].client.current_bss) + chan = wdev->links[0].client.current_bss->pub.channel; else if (wdev->wext.connect.channel) chan = wdev->wext.connect.channel; wdev_unlock(wdev); @@ -208,15 +211,19 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) return -EINVAL;
+ if (wdev->valid_links) + return -EINVAL; + data->flags = 0;
wdev_lock(wdev); - if (wdev->current_bss) { + if (wdev->links[0].client.current_bss) { const struct element *ssid_elem;
rcu_read_lock(); - ssid_elem = ieee80211_bss_get_elem(&wdev->current_bss->pub, - WLAN_EID_SSID); + ssid_elem = ieee80211_bss_get_elem( + &wdev->links[0].client.current_bss->pub, + WLAN_EID_SSID); if (ssid_elem) { data->flags = 1; data->length = ssid_elem->datalen; @@ -300,8 +307,14 @@ int cfg80211_mgd_wext_giwap(struct net_device *dev, ap_addr->sa_family = ARPHRD_ETHER;
wdev_lock(wdev); - if (wdev->current_bss) - memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN); + if (wdev->valid_links) { + wdev_unlock(wdev); + return -EOPNOTSUPP; + } + if (wdev->links[0].client.current_bss) + memcpy(ap_addr->sa_data, + wdev->links[0].client.current_bss->pub.bssid, + ETH_ALEN); else eth_zero_addr(ap_addr->sa_data); wdev_unlock(wdev);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit d0a9123ef548def5c8880e83e5df948eb5b55c62 ]
To add MLD, reuse the bss_conf structure later for per-link information, so move some things into it that are per link.
Most transformations were done with the following spatch:
@@ expression sdata; identifier var = { chanctx_conf, mu_mimo_owner, csa_active, color_change_active, color_change_color }; @@ -sdata->vif.var +sdata->vif.bss_conf.var
@@ struct ieee80211_vif *vif; identifier var = { chanctx_conf, mu_mimo_owner, csa_active, color_change_active, color_change_color }; @@ -vif->var +vif->bss_conf.var
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/htt_rx.c | 2 +- drivers/net/wireless/ath/ath10k/mac.c | 8 ++-- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 +- drivers/net/wireless/ath/ath10k/wmi.c | 2 +- drivers/net/wireless/ath/ath11k/mac.c | 12 +++--- drivers/net/wireless/ath/ath11k/wmi.c | 4 +- drivers/net/wireless/ath/ath9k/beacon.c | 2 +- .../net/wireless/ath/ath9k/htc_drv_beacon.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/coex.c | 6 +-- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 +- .../wireless/intel/iwlwifi/mvm/debugfs-vif.c | 4 +- .../intel/iwlwifi/mvm/ftm-responder.c | 4 +- .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 10 ++--- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 10 ++--- .../net/wireless/intel/iwlwifi/mvm/power.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/tdls.c | 4 +- .../wireless/intel/iwlwifi/mvm/time-event.c | 4 +- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 2 +- drivers/net/wireless/mac80211_hwsim.c | 22 ++++++---- drivers/net/wireless/mediatek/mt76/mac80211.c | 4 +- .../net/wireless/mediatek/mt76/mt7615/mcu.c | 2 +- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 10 ++--- drivers/net/wireless/ti/wlcore/main.c | 2 +- include/net/mac80211.h | 40 +++++++++--------- net/mac80211/airtime.c | 4 +- net/mac80211/cfg.c | 40 +++++++++--------- net/mac80211/chan.c | 39 ++++++++--------- net/mac80211/driver-ops.h | 2 +- net/mac80211/ethtool.c | 4 +- net/mac80211/ibss.c | 10 ++--- net/mac80211/ieee80211_i.h | 6 +-- net/mac80211/iface.c | 8 ++-- net/mac80211/main.c | 4 +- net/mac80211/mesh.c | 14 +++---- net/mac80211/mlme.c | 42 +++++++++---------- net/mac80211/ocb.c | 3 +- net/mac80211/offchannel.c | 6 +-- net/mac80211/rate.c | 5 ++- net/mac80211/rx.c | 2 +- net/mac80211/sta_info.c | 2 +- net/mac80211/tdls.c | 6 +-- net/mac80211/tx.c | 28 ++++++------- net/mac80211/util.c | 16 +++---- net/mac80211/vht.c | 6 +-- 45 files changed, 209 insertions(+), 202 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 771252dd6d4e..fe34fcc00af0 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -3840,7 +3840,7 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar, switch (txrate.flags) { case WMI_RATE_PREAMBLE_OFDM: if (arsta->arvif && arsta->arvif->vif) - conf = rcu_dereference(arsta->arvif->vif->chanctx_conf); + conf = rcu_dereference(arsta->arvif->vif->bss_conf.chanctx_conf); if (conf && conf->def.chan->band == NL80211_BAND_5GHZ) arsta->tx_info.status.rates[0].idx = rate_idx - 4; break; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 3570a5895ea8..6407f509e91b 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -659,7 +659,7 @@ int ath10k_mac_vif_chan(struct ieee80211_vif *vif, struct ieee80211_chanctx_conf *conf;
rcu_read_lock(); - conf = rcu_dereference(vif->chanctx_conf); + conf = rcu_dereference(vif->bss_conf.chanctx_conf); if (!conf) { rcu_read_unlock(); return -ENOENT; @@ -2028,7 +2028,7 @@ static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif) if (arvif->vdev_type != WMI_VDEV_TYPE_AP) return;
- if (!vif->csa_active) + if (!vif->bss_conf.csa_active) return;
if (!arvif->is_up) @@ -8798,7 +8798,7 @@ ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac, { struct ath10k_mac_change_chanctx_arg *arg = data;
- if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx) + if (rcu_access_pointer(vif->bss_conf.chanctx_conf) != arg->ctx) return;
arg->n_vifs++; @@ -8811,7 +8811,7 @@ ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac, struct ath10k_mac_change_chanctx_arg *arg = data; struct ieee80211_chanctx_conf *ctx;
- ctx = rcu_access_pointer(vif->chanctx_conf); + ctx = rcu_access_pointer(vif->bss_conf.chanctx_conf); if (ctx != arg->ctx) return;
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 7efbe03fbca8..876410a47d1d 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -205,7 +205,7 @@ static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar, }
arvif = ath10k_get_arvif(ar, vdev_id); - if (arvif && arvif->is_up && arvif->vif->csa_active) + if (arvif && arvif->is_up && arvif->vif->bss_conf.csa_active) ieee80211_queue_work(ar->hw, &arvif->ap_csa_work);
kfree(tb); diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index cd438f76f284..af19cab24c76 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -3882,7 +3882,7 @@ void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) * Once CSA counter is completed stop sending beacons until * actual channel switch is done */ - if (arvif->vif->csa_active && + if (arvif->vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(arvif->vif)) { ieee80211_csa_finish(arvif->vif); continue; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 7d574ad67e59..06b86dcc3826 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -505,7 +505,7 @@ static int ath11k_mac_vif_chan(struct ieee80211_vif *vif, struct ieee80211_chanctx_conf *conf;
rcu_read_lock(); - conf = rcu_dereference(vif->chanctx_conf); + conf = rcu_dereference(vif->bss_conf.chanctx_conf); if (!conf) { rcu_read_unlock(); return -ENOENT; @@ -1398,10 +1398,10 @@ void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif) { struct ieee80211_vif *vif = arvif->vif;
- if (!vif->color_change_active && !arvif->bcca_zero_sent) + if (!vif->bss_conf.color_change_active && !arvif->bcca_zero_sent) return;
- if (vif->color_change_active && ieee80211_beacon_cntdwn_is_complete(vif)) { + if (vif->bss_conf.color_change_active && ieee80211_beacon_cntdwn_is_complete(vif)) { arvif->bcca_zero_sent = true; ieee80211_color_change_finish(vif); return; @@ -1409,7 +1409,7 @@ void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif)
arvif->bcca_zero_sent = false;
- if (vif->color_change_active) + if (vif->bss_conf.color_change_active) ieee80211_beacon_update_cntdwn(vif); ath11k_mac_setup_bcn_tmpl(arvif); } @@ -6848,7 +6848,7 @@ ath11k_mac_change_chanctx_cnt_iter(void *data, u8 *mac, { struct ath11k_mac_change_chanctx_arg *arg = data;
- if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx) + if (rcu_access_pointer(vif->bss_conf.chanctx_conf) != arg->ctx) return;
arg->n_vifs++; @@ -6861,7 +6861,7 @@ ath11k_mac_change_chanctx_fill_iter(void *data, u8 *mac, struct ath11k_mac_change_chanctx_arg *arg = data; struct ieee80211_chanctx_conf *ctx;
- ctx = rcu_access_pointer(vif->chanctx_conf); + ctx = rcu_access_pointer(vif->bss_conf.chanctx_conf); if (ctx != arg->ctx) return;
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 7b1dc19c565e..cc84bd53ddae 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -1700,7 +1700,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id, cmd->vdev_id = vdev_id; cmd->tim_ie_offset = offs->tim_offset;
- if (vif->csa_active) { + if (vif->bss_conf.csa_active) { cmd->csa_switch_count_offset = offs->cntdwn_counter_offs[0]; cmd->ext_csa_switch_count_offset = offs->cntdwn_counter_offs[1]; } @@ -7476,7 +7476,7 @@ ath11k_wmi_process_csa_switch_count_event(struct ath11k_base *ab, continue; }
- if (arvif->is_up && arvif->vif->csa_active) + if (arvif->is_up && arvif->vif->bss_conf.csa_active) ieee80211_csa_finish(arvif->vif); } rcu_read_unlock(); diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 72e2e71aac0e..8b1b966bcef1 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -362,7 +362,7 @@ static void ath9k_set_tsfadjust(struct ath_softc *sc,
bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif) { - if (!vif || !vif->csa_active) + if (!vif || !vif->bss_conf.csa_active) return false;
if (!ieee80211_beacon_cntdwn_is_complete(vif)) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index c745897aa3d6..468bc934d848 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -511,7 +511,7 @@ bool ath9k_htc_csa_is_finished(struct ath9k_htc_priv *priv) struct ieee80211_vif *vif;
vif = priv->csa_vif; - if (!vif || !vif->csa_active) + if (!vif || !vif->bss_conf.csa_active) return false;
if (!ieee80211_beacon_cntdwn_is_complete(vif)) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c index 9b194cb8d65e..8760f2c73369 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2013-2014, 2018-2020 Intel Corporation + * Copyright (C) 2013-2014, 2018-2020, 2022 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH */ #include <linux/ieee80211.h> @@ -106,7 +106,7 @@ iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
rcu_read_lock();
- chanctx_conf = rcu_dereference(vif->chanctx_conf); + chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf);
if (!chanctx_conf || chanctx_conf->def.chan->band != NL80211_BAND_2GHZ) { @@ -283,7 +283,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, return; }
- chanctx_conf = rcu_dereference(vif->chanctx_conf); + chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf);
/* If channel context is invalid or not on 2.4GHz .. */ if ((!chanctx_conf || diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 61f9136a333d..8edc8646a23a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -731,7 +731,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif, return -EINVAL;
rcu_read_lock(); - ctx = rcu_dereference(vif->chanctx_conf); + ctx = rcu_dereference(vif->bss_conf.chanctx_conf); if (WARN_ON(!ctx)) { rcu_read_unlock(); return -EINVAL; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c index 7d9faeffd154..78d8b37eb71a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c @@ -234,7 +234,7 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file, }
rcu_read_lock(); - chanctx_conf = rcu_dereference(vif->chanctx_conf); + chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf); if (chanctx_conf) pos += scnprintf(buf+pos, bufsz-pos, "idle rx chains %d, active rx chains: %d\n", @@ -597,7 +597,7 @@ static ssize_t iwl_dbgfs_rx_phyinfo_write(struct ieee80211_vif *vif, char *buf, mutex_lock(&mvm->mutex); rcu_read_lock();
- chanctx_conf = rcu_dereference(vif->chanctx_conf); + chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf); /* make sure the channel context is assigned */ if (!chanctx_conf) { rcu_read_unlock(); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c index 9729680476fd..e862d1b43f21 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2015-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation */ #include <net/cfg80211.h> #include <linux/etherdevice.h> @@ -398,7 +398,7 @@ int iwl_mvm_ftm_start_responder(struct iwl_mvm *mvm, struct ieee80211_vif *vif) }
rcu_read_lock(); - pctx = rcu_dereference(vif->chanctx_conf); + pctx = rcu_dereference(vif->bss_conf.chanctx_conf); /* Copy the ctx to unlock the rcu and send the phy ctxt. We don't care * about changes in the ctx after releasing the lock because the driver * is still protected by the mutex. */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 56fa20596f16..7756ac0faf3f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -481,7 +481,7 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, eth_broadcast_addr(cmd->bssid_addr);
rcu_read_lock(); - chanctx = rcu_dereference(vif->chanctx_conf); + chanctx = rcu_dereference(vif->bss_conf.chanctx_conf); iwl_mvm_ack_rates(mvm, vif, chanctx ? chanctx->def.chan->band : NL80211_BAND_2GHZ, &cck_ack_rates, &ofdm_ack_rates); @@ -934,7 +934,7 @@ static int iwl_mvm_mac_ctxt_send_beacon_v9(struct iwl_mvm *mvm,
/* Enable FILS on PSC channels only */ rcu_read_lock(); - ctx = rcu_dereference(vif->chanctx_conf); + ctx = rcu_dereference(vif->bss_conf.chanctx_conf); channel = ieee80211_frequency_to_channel(ctx->def.chan->center_freq); WARN_ON(channel == 0); if (cfg80211_channel_is_psc(ctx->def.chan) && @@ -1335,7 +1335,7 @@ void iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
csa_vif = rcu_dereference_protected(mvm->csa_vif, lockdep_is_held(&mvm->mutex)); - if (unlikely(csa_vif && csa_vif->csa_active)) + if (unlikely(csa_vif && csa_vif->bss_conf.csa_active)) iwl_mvm_csa_count_down(mvm, csa_vif, mvm->ap_last_beacon_gp2, (status == TX_STATUS_SUCCESS));
@@ -1558,7 +1558,7 @@ void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm, switch (vif->type) { case NL80211_IFTYPE_AP: csa_vif = rcu_dereference(mvm->csa_vif); - if (WARN_ON(!csa_vif || !csa_vif->csa_active || + if (WARN_ON(!csa_vif || !csa_vif->bss_conf.csa_active || csa_vif != vif)) goto out_unlock;
@@ -1587,7 +1587,7 @@ void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm, */ if (iwl_fw_lookup_notif_ver(mvm->fw, MAC_CONF_GROUP, CHANNEL_SWITCH_ERROR_NOTIF, - 0) && !vif->csa_active) { + 0) && !vif->bss_conf.csa_active) { IWL_DEBUG_INFO(mvm, "Channel Switch was canceled\n"); iwl_mvm_cancel_channel_switch(mvm, vif, mac_id); break; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index bb9bd2165355..c5626ff83805 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1768,7 +1768,7 @@ static int iwl_mvm_update_mu_groups(struct iwl_mvm *mvm, static void iwl_mvm_mu_mimo_iface_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif) { - if (vif->mu_mimo_owner) { + if (vif->bss_conf.mu_mimo_owner) { struct iwl_mu_group_mgmt_notif *notif = _data;
/* @@ -1965,7 +1965,7 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
rcu_read_lock();
- chanctx_conf = rcu_dereference(vif->chanctx_conf); + chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { rcu_read_unlock(); return; @@ -2337,7 +2337,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, * However, on HW restart we should restore this data. */ if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && - (changes & BSS_CHANGED_MU_GROUPS) && vif->mu_mimo_owner) { + (changes & BSS_CHANGED_MU_GROUPS) && vif->bss_conf.mu_mimo_owner) { ret = iwl_mvm_update_mu_groups(mvm, vif); if (ret) IWL_ERR(mvm, @@ -4004,7 +4004,7 @@ static void iwl_mvm_ftm_responder_chanctx_iter(void *_data, u8 *mac, { struct iwl_mvm_ftm_responder_iter_data *data = _data;
- if (rcu_access_pointer(vif->chanctx_conf) == data->ctx && + if (rcu_access_pointer(vif->bss_conf.chanctx_conf) == data->ctx && vif->type == NL80211_IFTYPE_AP && vif->bss_conf.ftmr_params) data->responder = true; } @@ -4631,7 +4631,7 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, csa_vif = rcu_dereference_protected(mvm->csa_vif, lockdep_is_held(&mvm->mutex)); - if (WARN_ONCE(csa_vif && csa_vif->csa_active, + if (WARN_ONCE(csa_vif && csa_vif->bss_conf.csa_active, "Another CSA is already in progress")) { ret = -EBUSY; goto out_unlock; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/power.c b/drivers/net/wireless/intel/iwlwifi/mvm/power.c index b9bd81242b21..afdf3bb523e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c @@ -283,7 +283,7 @@ static bool iwl_mvm_power_is_radar(struct ieee80211_vif *vif) bool radar_detect = false;
rcu_read_lock(); - chanctx_conf = rcu_dereference(vif->chanctx_conf); + chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf); WARN_ON(!chanctx_conf); if (chanctx_conf) { chan = chanctx_conf->def.chan; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 974eeecc9153..303975f9e2b5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -1980,7 +1980,7 @@ static bool rs_tpc_perform(struct iwl_mvm *mvm, #endif
rcu_read_lock(); - chanctx_conf = rcu_dereference(vif->chanctx_conf); + chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) band = NUM_NL80211_BANDS; else diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c b/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c index bf04326e35ff..674dd137fb9f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c @@ -2,7 +2,7 @@ /* * Copyright (C) 2014 Intel Mobile Communications GmbH * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2020 Intel Corporation + * Copyright (C) 2018-2020, 2022 Intel Corporation */ #include <linux/etherdevice.h> #include "mvm.h" @@ -380,7 +380,7 @@ iwl_mvm_tdls_config_channel_switch(struct iwl_mvm *mvm, type == TDLS_MOVE_CH) { /* we need to return to base channel */ struct ieee80211_chanctx_conf *chanctx = - rcu_dereference(vif->chanctx_conf); + rcu_dereference(vif->bss_conf.chanctx_conf);
if (WARN_ON_ONCE(!chanctx)) { rcu_read_unlock(); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index 6edf2b79db43..4f0794a45bf5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2021 Intel Corporation + * Copyright (C) 2012-2014, 2018-2022 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2017 Intel Deutschland GmbH */ @@ -123,7 +123,7 @@ static void iwl_mvm_csa_noa_start(struct iwl_mvm *mvm) rcu_read_lock();
csa_vif = rcu_dereference(mvm->csa_vif); - if (!csa_vif || !csa_vif->csa_active) + if (!csa_vif || !csa_vif->bss_conf.csa_active) goto out_unlock;
IWL_DEBUG_TE(mvm, "CSA NOA started\n"); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 8125bb76f59e..f9e08b339e0c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1959,7 +1959,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,
if (mvmsta->vif) chanctx_conf = - rcu_dereference(mvmsta->vif->chanctx_conf); + rcu_dereference(mvmsta->vif->bss_conf.chanctx_conf);
if (WARN_ON_ONCE(!chanctx_conf)) goto out; diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 6d8f02740b7b..b511e705a46e 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -889,7 +889,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
rcu_read_lock(); mac80211_hwsim_tx_frame(data->hw, skb, - rcu_dereference(vif->chanctx_conf)->def.chan); + rcu_dereference(vif->bss_conf.chanctx_conf)->def.chan); rcu_read_unlock(); }
@@ -922,7 +922,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
rcu_read_lock(); mac80211_hwsim_tx_frame(data->hw, skb, - rcu_dereference(vif->chanctx_conf)->def.chan); + rcu_dereference(vif->bss_conf.chanctx_conf)->def.chan); rcu_read_unlock(); }
@@ -1464,11 +1464,11 @@ static void mac80211_hwsim_tx_iter(void *_data, u8 *addr, { struct tx_iter_data *data = _data;
- if (!vif->chanctx_conf) + if (!vif->bss_conf.chanctx_conf) return;
if (!hwsim_chans_compat(data->channel, - rcu_dereference(vif->chanctx_conf)->def.chan)) + rcu_dereference(vif->bss_conf.chanctx_conf)->def.chan)) return;
data->receive = true; @@ -1686,7 +1686,11 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, } else if (txi->hw_queue == 4) { channel = data->tmp_chan; } else { - chanctx_conf = rcu_dereference(txi->control.vif->chanctx_conf); + struct ieee80211_bss_conf *bss_conf; + + bss_conf = &txi->control.vif->bss_conf; + + chanctx_conf = rcu_dereference(bss_conf->chanctx_conf); if (chanctx_conf) { channel = chanctx_conf->def.chan; confbw = chanctx_conf->def.width; @@ -1935,14 +1939,14 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, }
mac80211_hwsim_tx_frame(hw, skb, - rcu_dereference(vif->chanctx_conf)->def.chan); + rcu_dereference(vif->bss_conf.chanctx_conf)->def.chan);
while ((skb = ieee80211_get_buffered_bc(hw, vif)) != NULL) { mac80211_hwsim_tx_frame(hw, skb, - rcu_dereference(vif->chanctx_conf)->def.chan); + rcu_dereference(vif->bss_conf.chanctx_conf)->def.chan); }
- if (vif->csa_active && ieee80211_beacon_cntdwn_is_complete(vif)) + if (vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(vif)) ieee80211_csa_finish(vif); }
@@ -2204,7 +2208,7 @@ mac80211_hwsim_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *chanctx_conf;
rcu_read_lock(); - chanctx_conf = rcu_dereference(vif->chanctx_conf); + chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf);
if (!WARN_ON(!chanctx_conf)) confbw = chanctx_conf->def.width; diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 18b5de55334c..5f75a8945a6e 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -1459,7 +1459,7 @@ EXPORT_SYMBOL_GPL(mt76_get_sar_power); static void __mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif) { - if (vif->csa_active && ieee80211_beacon_cntdwn_is_complete(vif)) + if (vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(vif)) ieee80211_csa_finish(vif); }
@@ -1481,7 +1481,7 @@ __mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif) { struct mt76_dev *dev = priv;
- if (!vif->csa_active) + if (!vif->bss_conf.csa_active) return;
dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif); diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index 97e2a85cb728..8fb6c9d735dc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -363,7 +363,7 @@ static int mt7615_mcu_fw_pmctrl(struct mt7615_dev *dev) static void mt7615_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif) { - if (vif->csa_active) + if (vif->bss_conf.csa_active) ieee80211_csa_finish(vif); }
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index b7e2b365356c..1b3d6634a72e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -322,7 +322,7 @@ int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3) static void mt7915_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif) { - if (vif->csa_active) + if (vif->bss_conf.csa_active) ieee80211_csa_finish(vif); }
@@ -409,7 +409,7 @@ mt7915_mcu_rx_log_message(struct mt7915_dev *dev, struct sk_buff *skb) static void mt7915_mcu_cca_finish(void *priv, u8 *mac, struct ieee80211_vif *vif) { - if (!vif->color_change_active) + if (!vif->bss_conf.color_change_active) return;
ieee80211_color_change_finish(vif); @@ -1818,7 +1818,7 @@ mt7915_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb, if (!offs->cntdwn_counter_offs[0]) return;
- sub_tag = vif->csa_active ? BSS_INFO_BCN_CSA : BSS_INFO_BCN_BCC; + sub_tag = vif->bss_conf.csa_active ? BSS_INFO_BCN_CSA : BSS_INFO_BCN_BCC; tlv = mt7915_mcu_add_nested_subtlv(rskb, sub_tag, sizeof(*info), &bcn->sub_ntlv, &bcn->len); info = (struct bss_info_bcn_cntdwn *)tlv; @@ -1903,9 +1903,9 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif, if (offs->cntdwn_counter_offs[0]) { u16 offset = offs->cntdwn_counter_offs[0];
- if (vif->csa_active) + if (vif->bss_conf.csa_active) cont->csa_ofs = cpu_to_le16(offset - 4); - if (vif->color_change_active) + if (vif->bss_conf.color_change_active) cont->bcc_ofs = cpu_to_le16(offset - 3); }
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 6959efa4bfa9..21a9e3b0cbac 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -4675,7 +4675,7 @@ static void wlcore_op_change_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
rcu_read_lock(); - if (rcu_access_pointer(vif->chanctx_conf) != ctx) { + if (rcu_access_pointer(vif->bss_conf.chanctx_conf) != ctx) { rcu_read_unlock(); continue; } diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 47642b020706..d95d8cbfc679 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -636,6 +636,19 @@ struct ieee80211_fils_discovery { * @tx_pwr_env_num: number of @tx_pwr_env. * @pwr_reduction: power constraint of BSS. * @eht_support: does this BSS support EHT + * @csa_active: marks whether a channel switch is going on. Internally it is + * write-protected by sdata_lock and local->mtx so holding either is fine + * for read access. + * @mu_mimo_owner: indicates interface owns MU-MIMO capability + * @chanctx_conf: The channel context this interface is assigned to, or %NULL + * when it is not assigned. This pointer is RCU-protected due to the TX + * path needing to access it; even though the netdev carrier will always + * be off when it is %NULL there can still be races and packets could be + * processed after it switches back to %NULL. + * @color_change_active: marks whether a color change is ongoing. Internally it is + * write-protected by sdata_lock and local->mtx so holding either is fine + * for read access. + * @color_change_color: the bss color that will be used after the change. */ struct ieee80211_bss_conf { const u8 *bssid; @@ -711,6 +724,13 @@ struct ieee80211_bss_conf { u8 tx_pwr_env_num; u8 pwr_reduction; bool eht_support; + + bool csa_active; + bool mu_mimo_owner; + struct ieee80211_chanctx_conf __rcu *chanctx_conf; + + bool color_change_active; + u8 color_change_color; };
/** @@ -1713,10 +1733,6 @@ enum ieee80211_offload_flags { * @addr: address of this interface * @p2p: indicates whether this AP or STA interface is a p2p * interface, i.e. a GO or p2p-sta respectively - * @csa_active: marks whether a channel switch is going on. Internally it is - * write-protected by sdata_lock and local->mtx so holding either is fine - * for read access. - * @mu_mimo_owner: indicates interface owns MU-MIMO capability * @driver_flags: flags/capabilities the driver has for this interface, * these need to be set (or cleared) when the interface is added * or, if supported by the driver, the interface type is changed @@ -1728,11 +1744,6 @@ enum ieee80211_offload_flags { * restrictions. * @hw_queue: hardware queue for each AC * @cab_queue: content-after-beacon (DTIM beacon really) queue, AP mode only - * @chanctx_conf: The channel context this interface is assigned to, or %NULL - * when it is not assigned. This pointer is RCU-protected due to the TX - * path needing to access it; even though the netdev carrier will always - * be off when it is %NULL there can still be races and packets could be - * processed after it switches back to %NULL. * @debugfs_dir: debugfs dentry, can be used by drivers to create own per * interface debug files. Note that it will be NULL for the virtual * monitor interface (if that is requested.) @@ -1747,10 +1758,6 @@ enum ieee80211_offload_flags { * protected by fq->lock. * @offload_flags: 802.3 -> 802.11 enapsulation offload flags, see * &enum ieee80211_offload_flags. - * @color_change_active: marks whether a color change is ongoing. Internally it is - * write-protected by sdata_lock and local->mtx so holding either is fine - * for read access. - * @color_change_color: the bss color that will be used after the change. * @mbssid_tx_vif: Pointer to the transmitting interface if MBSSID is enabled. */ struct ieee80211_vif { @@ -1758,16 +1765,12 @@ struct ieee80211_vif { struct ieee80211_bss_conf bss_conf; u8 addr[ETH_ALEN] __aligned(2); bool p2p; - bool csa_active; - bool mu_mimo_owner;
u8 cab_queue; u8 hw_queue[IEEE80211_NUM_ACS];
struct ieee80211_txq *txq;
- struct ieee80211_chanctx_conf __rcu *chanctx_conf; - u32 driver_flags; u32 offload_flags;
@@ -1780,9 +1783,6 @@ struct ieee80211_vif {
bool txqs_stopped[IEEE80211_NUM_ACS];
- bool color_change_active; - u8 color_change_color; - struct ieee80211_vif *mbssid_tx_vif;
/* must be last */ diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c index 4bab1683652d..2e66598fac79 100644 --- a/net/mac80211/airtime.c +++ b/net/mac80211/airtime.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: ISC /* * Copyright (C) 2019 Felix Fietkau nbd@nbd.name - * Copyright (C) 2021 Intel Corporation + * Copyright (C) 2021-2022 Intel Corporation */
#include <net/mac80211.h> @@ -637,7 +637,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
len += 38; /* Ethernet header length */
- conf = rcu_dereference(vif->chanctx_conf); + conf = rcu_dereference(vif->bss_conf.chanctx_conf); if (conf) { band = conf->def.chan->band; shift = ieee80211_chandef_get_shift(&conf->def); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 30ccaa6cb9f3..9ca25ae503b0 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -53,7 +53,7 @@ static void ieee80211_set_mu_mimo_follow(struct ieee80211_sub_if_data *sdata, params->vht_mumimo_follow_addr); }
- sdata->vif.mu_mimo_owner = mu_mimo_groups || mu_mimo_follow; + sdata->vif.bss_conf.mu_mimo_owner = mu_mimo_groups || mu_mimo_follow; }
static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata, @@ -1326,7 +1326,7 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, /* don't allow changing the beacon while a countdown is in place - offset * of channel switch counter may change */ - if (sdata->vif.csa_active || sdata->vif.color_change_active) + if (sdata->vif.bss_conf.csa_active || sdata->vif.bss_conf.color_change_active) return -EBUSY;
old = sdata_dereference(sdata->u.ap.beacon, sdata); @@ -1384,7 +1384,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
/* abort any running channel switch */ mutex_lock(&local->mtx); - sdata->vif.csa_active = false; + sdata->vif.bss_conf.csa_active = false; if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA); @@ -3083,7 +3083,7 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, * to send something, and if we're an AP we have to be able to do * so at a basic rate so that all clients can receive it. */ - if (rcu_access_pointer(sdata->vif.chanctx_conf) && + if (rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) && sdata->vif.bss_conf.chandef.chan) { u32 basic_rates = sdata->vif.bss_conf.basic_rates; enum nl80211_band band = sdata->vif.bss_conf.chandef.chan->band; @@ -3390,7 +3390,7 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) &sdata->csa_chandef)) return -EINVAL;
- sdata->vif.csa_active = false; + sdata->vif.bss_conf.csa_active = false;
err = ieee80211_set_after_csa_beacon(sdata, &changed); if (err) @@ -3434,7 +3434,7 @@ void ieee80211_csa_finalize_work(struct work_struct *work) mutex_lock(&local->chanctx_mtx);
/* AP might have been stopped while waiting for the lock. */ - if (!sdata->vif.csa_active) + if (!sdata->vif.bss_conf.csa_active) goto unlock;
if (!ieee80211_sdata_running(sdata)) @@ -3586,7 +3586,7 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
static void ieee80211_color_change_abort(struct ieee80211_sub_if_data *sdata) { - sdata->vif.color_change_active = false; + sdata->vif.bss_conf.color_change_active = false;
ieee80211_free_next_beacon(sdata);
@@ -3619,11 +3619,11 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, return -EINVAL;
/* don't allow another channel switch if one is already active. */ - if (sdata->vif.csa_active) + if (sdata->vif.bss_conf.csa_active) return -EBUSY;
mutex_lock(&local->chanctx_mtx); - conf = rcu_dereference_protected(sdata->vif.chanctx_conf, + conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, lockdep_is_held(&local->chanctx_mtx)); if (!conf) { err = -EBUSY; @@ -3662,7 +3662,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, }
/* if there is a color change in progress, abort it */ - if (sdata->vif.color_change_active) + if (sdata->vif.bss_conf.color_change_active) ieee80211_color_change_abort(sdata);
err = ieee80211_set_csa_beacon(sdata, params, &changed); @@ -3673,7 +3673,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
sdata->csa_chandef = params->chandef; sdata->csa_block_tx = params->block_tx; - sdata->vif.csa_active = true; + sdata->vif.bss_conf.csa_active = true;
if (sdata->csa_block_tx) ieee80211_stop_vif_queues(local, sdata, @@ -3842,7 +3842,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, mutex_lock(&local->mtx);
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { ret = -EINVAL; goto unlock; @@ -3925,7 +3925,7 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy, int ret = -ENODATA;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (chanctx_conf) { *chandef = sdata->vif.bss_conf.chandef; ret = 0; @@ -4421,7 +4421,7 @@ static int ieee80211_color_change_finalize(struct ieee80211_sub_if_data *sdata) sdata_assert_lock(sdata); lockdep_assert_held(&local->mtx);
- sdata->vif.color_change_active = false; + sdata->vif.bss_conf.color_change_active = false;
err = ieee80211_set_after_color_change_beacon(sdata, &changed); if (err) { @@ -4430,7 +4430,7 @@ static int ieee80211_color_change_finalize(struct ieee80211_sub_if_data *sdata) }
ieee80211_color_change_bss_config_notify(sdata, - sdata->vif.color_change_color, + sdata->vif.bss_conf.color_change_color, 1, changed); cfg80211_color_change_notify(sdata->dev);
@@ -4448,7 +4448,7 @@ void ieee80211_color_change_finalize_work(struct work_struct *work) mutex_lock(&local->mtx);
/* AP might have been stopped while waiting for the lock. */ - if (!sdata->vif.color_change_active) + if (!sdata->vif.bss_conf.color_change_active) goto unlock;
if (!ieee80211_sdata_running(sdata)) @@ -4476,7 +4476,7 @@ ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif, { struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
- if (sdata->vif.color_change_active || sdata->vif.csa_active) + if (sdata->vif.bss_conf.color_change_active || sdata->vif.bss_conf.csa_active) return;
cfg80211_obss_color_collision_notify(sdata->dev, color_bitmap, gfp); @@ -4502,7 +4502,7 @@ ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev, /* don't allow another color change if one is already active or if csa * is active */ - if (sdata->vif.color_change_active || sdata->vif.csa_active) { + if (sdata->vif.bss_conf.color_change_active || sdata->vif.bss_conf.csa_active) { err = -EBUSY; goto out; } @@ -4511,8 +4511,8 @@ ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev, if (err) goto out;
- sdata->vif.color_change_active = true; - sdata->vif.color_change_color = params->color; + sdata->vif.bss_conf.color_change_active = true; + sdata->vif.bss_conf.color_change_color = params->color;
cfg80211_color_change_started_notify(sdata->dev, params->count);
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index d8246e00a10b..eea400902133 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * mac80211 - channel management - * Copyright 2020 - 2021 Intel Corporation + * Copyright 2020 - 2022 Intel Corporation */
#include <linux/nl80211.h> @@ -72,7 +72,7 @@ ieee80211_vif_get_chanctx(struct ieee80211_sub_if_data *sdata) struct ieee80211_local *local __maybe_unused = sdata->local; struct ieee80211_chanctx_conf *conf;
- conf = rcu_dereference_protected(sdata->vif.chanctx_conf, + conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, lockdep_is_held(&local->chanctx_mtx)); if (!conf) return NULL; @@ -260,7 +260,7 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, if (!ieee80211_sdata_running(sdata)) continue;
- if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) + if (rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) != conf) continue;
switch (vif->type) { @@ -298,7 +298,7 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
/* use the configured bandwidth in case of monitor interface */ sdata = rcu_dereference(local->monitor_sdata); - if (sdata && rcu_access_pointer(sdata->vif.chanctx_conf) == conf) + if (sdata && rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) == conf) max_bw = max(max_bw, conf->def.width);
rcu_read_unlock(); @@ -368,7 +368,7 @@ static void ieee80211_chan_bw_change(struct ieee80211_local *local, if (!ieee80211_sdata_running(sta->sdata)) continue;
- if (rcu_access_pointer(sta->sdata->vif.chanctx_conf) != + if (rcu_access_pointer(sta->sdata->vif.bss_conf.chanctx_conf) != &ctx->conf) continue;
@@ -533,7 +533,7 @@ ieee80211_chanctx_radar_required(struct ieee80211_local *local, list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (!ieee80211_sdata_running(sdata)) continue; - if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) + if (rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) != conf) continue; if (!sdata->radar_required) continue; @@ -689,7 +689,7 @@ void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
if (!ieee80211_sdata_running(sdata)) continue; - if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) + if (rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) != conf) continue; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) continue; @@ -759,7 +759,7 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN)) return -ENOTSUPP;
- conf = rcu_dereference_protected(sdata->vif.chanctx_conf, + conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, lockdep_is_held(&local->chanctx_mtx));
if (conf) { @@ -781,7 +781,7 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, }
out: - rcu_assign_pointer(sdata->vif.chanctx_conf, conf); + rcu_assign_pointer(sdata->vif.bss_conf.chanctx_conf, conf);
sdata->vif.bss_conf.idle = !conf;
@@ -825,7 +825,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, if (!ieee80211_sdata_running(sdata)) continue;
- if (rcu_access_pointer(sdata->vif.chanctx_conf) != + if (rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) != &chanctx->conf) continue;
@@ -874,7 +874,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, /* Disable SMPS for the monitor interface */ sdata = rcu_dereference(local->monitor_sdata); if (sdata && - rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf) + rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf) == &chanctx->conf) rx_chains_dynamic = rx_chains_static = local->rx_chains;
rcu_read_unlock(); @@ -917,7 +917,7 @@ __ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, * channel context pointer for a while, possibly pointing * to a channel context that has already been freed. */ - conf = rcu_dereference_protected(sdata->vif.chanctx_conf, + conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, lockdep_is_held(&local->chanctx_mtx)); WARN_ON(!conf);
@@ -925,7 +925,7 @@ __ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, conf = NULL;
list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) - rcu_assign_pointer(vlan->vif.chanctx_conf, conf); + rcu_assign_pointer(vlan->vif.bss_conf.chanctx_conf, conf); }
void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, @@ -1173,7 +1173,7 @@ ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata) }
list_move(&sdata->assigned_chanctx_list, &new_ctx->assigned_vifs); - rcu_assign_pointer(sdata->vif.chanctx_conf, &new_ctx->conf); + rcu_assign_pointer(sdata->vif.bss_conf.chanctx_conf, &new_ctx->conf);
if (sdata->vif.type == NL80211_IFTYPE_AP) __ieee80211_vif_copy_chanctx_to_vlans(sdata, false); @@ -1515,7 +1515,8 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) if (!ieee80211_vif_has_in_place_reservation(sdata)) continue;
- rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf); + rcu_assign_pointer(sdata->vif.bss_conf.chanctx_conf, + &ctx->conf);
if (sdata->vif.type == NL80211_IFTYPE_AP) __ieee80211_vif_copy_chanctx_to_vlans(sdata, @@ -1634,7 +1635,7 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
lockdep_assert_held(&local->chanctx_mtx);
- conf = rcu_dereference_protected(sdata->vif.chanctx_conf, + conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, lockdep_is_held(&local->chanctx_mtx)); if (!conf) return; @@ -1809,7 +1810,7 @@ int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, goto out; }
- conf = rcu_dereference_protected(sdata->vif.chanctx_conf, + conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, lockdep_is_held(&local->chanctx_mtx)); if (!conf) { ret = -EINVAL; @@ -1879,9 +1880,9 @@ void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata)
mutex_lock(&local->chanctx_mtx);
- conf = rcu_dereference_protected(ap->vif.chanctx_conf, + conf = rcu_dereference_protected(ap->vif.bss_conf.chanctx_conf, lockdep_is_held(&local->chanctx_mtx)); - rcu_assign_pointer(sdata->vif.chanctx_conf, conf); + rcu_assign_pointer(sdata->vif.bss_conf.chanctx_conf, conf); mutex_unlock(&local->chanctx_mtx); }
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 4e2fc1a08681..fd2882348211 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -165,7 +165,7 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || sdata->vif.type == NL80211_IFTYPE_NAN || (sdata->vif.type == NL80211_IFTYPE_MONITOR && - !sdata->vif.mu_mimo_owner && + !sdata->vif.bss_conf.mu_mimo_owner && !(changed & BSS_CHANGED_TXPOWER)))) return;
diff --git a/net/mac80211/ethtool.c b/net/mac80211/ethtool.c index 31cd3c1ac07f..6e1fc8788101 100644 --- a/net/mac80211/ethtool.c +++ b/net/mac80211/ethtool.c @@ -5,7 +5,7 @@ * Copied from cfg.c - originally * Copyright 2006-2010 Johannes Berg johannes@sipsolutions.net * Copyright 2014 Intel Corporation (Author: Johannes Berg) - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018, 2022 Intel Corporation */ #include <linux/types.h> #include <net/cfg80211.h> @@ -150,7 +150,7 @@ static void ieee80211_get_stats(struct net_device *dev, survey.filled = 0;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (chanctx_conf) channel = chanctx_conf->def.chan; else diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 14c04fd48b7a..8ff547ff351e 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -9,7 +9,7 @@ * Copyright 2009, Johannes Berg johannes@sipsolutions.net * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright(c) 2016 Intel Deutschland GmbH - * Copyright(c) 2018-2021 Intel Corporation + * Copyright(c) 2018-2022 Intel Corporation */
#include <linux/delay.h> @@ -622,7 +622,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid, }
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON_ONCE(!chanctx_conf)) return NULL; band = chanctx_conf->def.chan->band; @@ -923,7 +923,7 @@ ieee80211_rx_mgmt_spectrum_mgmt(struct ieee80211_sub_if_data *sdata, if (len < required_len) return;
- if (!sdata->vif.csa_active) + if (!sdata->vif.bss_conf.csa_active) ieee80211_ibss_process_chanswitch(sdata, elems, false); }
@@ -1143,7 +1143,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, goto put_bss;
/* process channel switch */ - if (sdata->vif.csa_active || + if (sdata->vif.bss_conf.csa_active || ieee80211_ibss_process_chanswitch(sdata, elems, true)) goto put_bss;
@@ -1220,7 +1220,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, return;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON_ONCE(!chanctx_conf)) { rcu_read_unlock(); return; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 86ef0a46a68c..48fbccbf2a54 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1077,7 +1077,7 @@ ieee80211_vif_get_shift(struct ieee80211_vif *vif) int shift = 0;
rcu_read_lock(); - chanctx_conf = rcu_dereference(vif->chanctx_conf); + chanctx_conf = rcu_dereference(vif->bss_conf.chanctx_conf); if (chanctx_conf) shift = ieee80211_chandef_get_shift(&chanctx_conf->def); rcu_read_unlock(); @@ -1528,7 +1528,7 @@ ieee80211_get_sband(struct ieee80211_sub_if_data *sdata) enum nl80211_band band;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
if (!chanctx_conf) { rcu_read_unlock(); @@ -2225,7 +2225,7 @@ static inline void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, struct ieee80211_chanctx_conf *chanctx_conf;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { rcu_read_unlock(); kfree_skb(skb); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 1a9ada411879..5d29a4ca048a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -51,7 +51,7 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) int power;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (!chanctx_conf) { rcu_read_unlock(); return false; @@ -275,7 +275,7 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, * will not add another interface while any channel * switch is active. */ - if (nsdata->vif.csa_active) + if (nsdata->vif.bss_conf.csa_active) return -EBUSY;
/* @@ -451,7 +451,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do cancel_work_sync(&sdata->recalc_smps); sdata_lock(sdata); mutex_lock(&local->mtx); - sdata->vif.csa_active = false; + sdata->vif.bss_conf.csa_active = false; if (sdata->vif.type == NL80211_IFTYPE_STATION) sdata->u.mgd.csa_waiting_bcn = false; if (sdata->csa_block_tx) { @@ -503,7 +503,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do mutex_lock(&local->mtx); list_del(&sdata->u.vlan.list); mutex_unlock(&local->mtx); - RCU_INIT_POINTER(sdata->vif.chanctx_conf, NULL); + RCU_INIT_POINTER(sdata->vif.bss_conf.chanctx_conf, NULL); /* see comment in the default case below */ ieee80211_free_keys(sdata, true); /* no need to tell driver */ diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 5a385d4146b9..6d638eb05310 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -147,7 +147,7 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (!rcu_access_pointer(sdata->vif.chanctx_conf)) + if (!rcu_access_pointer(sdata->vif.bss_conf.chanctx_conf)) continue; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) continue; @@ -284,7 +284,7 @@ static void ieee80211_restart_work(struct work_struct *work) * Then we can have a race... */ cancel_work_sync(&sdata->u.mgd.csa_connection_drop_work); - if (sdata->vif.csa_active) { + if (sdata->vif.bss_conf.csa_active) { sdata_lock(sdata); ieee80211_sta_connection_lost(sdata, WLAN_REASON_UNSPECIFIED, diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 5275f4f32a78..f60e257cba95 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2008, 2009 open80211s Ltd. - * Copyright (C) 2018 - 2021 Intel Corporation + * Copyright (C) 2018 - 2022 Intel Corporation * Authors: Luis Carlos Cobo luisca@cozybit.com * Javier Cardona javier@cozybit.com */ @@ -399,7 +399,7 @@ static int mesh_add_ds_params_ie(struct ieee80211_sub_if_data *sdata, return -ENOMEM;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { rcu_read_unlock(); return -EINVAL; @@ -455,7 +455,7 @@ int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata, u8 *pos;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { rcu_read_unlock(); return -EINVAL; @@ -527,7 +527,7 @@ int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata, u8 *pos;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { rcu_read_unlock(); return -EINVAL; @@ -820,7 +820,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
sdata = container_of(ifmsh, struct ieee80211_sub_if_data, u.mesh); rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); band = chanctx_conf->def.chan->band; rcu_read_unlock();
@@ -1357,7 +1357,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, rx_status);
if (ifmsh->csa_role != IEEE80211_MESH_CSA_ROLE_INIT && - !sdata->vif.csa_active) + !sdata->vif.bss_conf.csa_active) ieee80211_mesh_process_chnswitch(sdata, elems, true); }
@@ -1488,7 +1488,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
ifmsh->pre_value = pre_value;
- if (!sdata->vif.csa_active && + if (!sdata->vif.bss_conf.csa_active && !ieee80211_mesh_process_chnswitch(sdata, elems, false)) { mcsa_dbg(sdata, "Failed to process CSA action frame"); goto free; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 62fa93f2636e..181aee459d7b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -624,7 +624,7 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, struct ieee80211_sub_if_data *other;
list_for_each_entry_rcu(other, &local->interfaces, list) { - if (other->vif.mu_mimo_owner) { + if (other->vif.bss_conf.mu_mimo_owner) { disable_mu_mimo = true; break; } @@ -632,7 +632,7 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, if (disable_mu_mimo) cap &= ~IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; else - sdata->vif.mu_mimo_owner = true; + sdata->vif.bss_conf.mu_mimo_owner = true; }
mask = IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; @@ -664,7 +664,7 @@ static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata, bool reg_cap = false;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (!WARN_ON_ONCE(!chanctx_conf)) reg_cap = cfg80211_chandef_usable(sdata->wdev.wiphy, &chanctx_conf->def, @@ -705,7 +705,7 @@ static void ieee80211_add_eht_ie(struct ieee80211_sub_if_data *sdata, bool reg_cap = false;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (!WARN_ON_ONCE(!chanctx_conf)) reg_cap = cfg80211_chandef_usable(sdata->wdev.wiphy, &chanctx_conf->def, @@ -766,7 +766,7 @@ static int ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) sdata_assert_lock(sdata);
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { rcu_read_unlock(); return -EINVAL; @@ -1229,7 +1229,7 @@ static void ieee80211_chswitch_work(struct work_struct *work) if (!ifmgd->associated) goto out;
- if (!sdata->vif.csa_active) + if (!sdata->vif.bss_conf.csa_active) goto out;
/* @@ -1289,7 +1289,7 @@ static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata)
sdata_assert_lock(sdata);
- WARN_ON(!sdata->vif.csa_active); + WARN_ON(!sdata->vif.bss_conf.csa_active);
if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, @@ -1297,7 +1297,7 @@ static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata) sdata->csa_block_tx = false; }
- sdata->vif.csa_active = false; + sdata->vif.bss_conf.csa_active = false; ifmgd->csa_waiting_bcn = false; /* * If the CSA IE is still present on the beacon after the switch, @@ -1361,7 +1361,7 @@ ieee80211_sta_abort_chanswitch(struct ieee80211_sub_if_data *sdata) IEEE80211_QUEUE_STOP_REASON_CSA);
sdata->csa_block_tx = false; - sdata->vif.csa_active = false; + sdata->vif.bss_conf.csa_active = false;
mutex_unlock(&local->mtx);
@@ -1412,13 +1412,13 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, if (res < 0) goto lock_and_drop_connection;
- if (beacon && sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) { + if (beacon && sdata->vif.bss_conf.csa_active && !ifmgd->csa_waiting_bcn) { if (res) ieee80211_sta_abort_chanswitch(sdata); else drv_channel_switch_rx_beacon(sdata, &ch_switch); return; - } else if (sdata->vif.csa_active || res) { + } else if (sdata->vif.bss_conf.csa_active || res) { /* disregard subsequent announcements if already processing */ return; } @@ -1471,7 +1471,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
mutex_lock(&local->mtx); mutex_lock(&local->chanctx_mtx); - conf = rcu_dereference_protected(sdata->vif.chanctx_conf, + conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, lockdep_is_held(&local->chanctx_mtx)); if (!conf) { sdata_info(sdata, @@ -1504,7 +1504,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, } mutex_unlock(&local->chanctx_mtx);
- sdata->vif.csa_active = true; + sdata->vif.bss_conf.csa_active = true; sdata->csa_chandef = csa_ie.chandef; sdata->csa_block_tx = csa_ie.mode; ifmgd->csa_ignored_same_chan = false; @@ -1543,7 +1543,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, * send a deauthentication frame. Those two fields will be * reset when the disconnection worker runs. */ - sdata->vif.csa_active = true; + sdata->vif.bss_conf.csa_active = true; sdata->csa_block_tx = csa_ie.mode;
ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work); @@ -2447,7 +2447,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, memset(sdata->vif.bss_conf.mu_group.position, 0, sizeof(sdata->vif.bss_conf.mu_group.position)); changed |= BSS_CHANGED_MU_GROUPS; - sdata->vif.mu_mimo_owner = false; + sdata->vif.bss_conf.mu_mimo_owner = false;
sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
@@ -2482,7 +2482,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, mutex_lock(&local->mtx); ieee80211_vif_release_channel(sdata);
- sdata->vif.csa_active = false; + sdata->vif.bss_conf.csa_active = false; ifmgd->csa_waiting_bcn = false; ifmgd->csa_ignored_same_chan = false; if (sdata->csa_block_tx) { @@ -2810,7 +2810,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, tx, frame_buf); mutex_lock(&local->mtx); - sdata->vif.csa_active = false; + sdata->vif.bss_conf.csa_active = false; ifmgd->csa_waiting_bcn = false; if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, @@ -2950,7 +2950,7 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata, eth_zero_addr(sdata->u.mgd.bssid); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); sdata->u.mgd.flags = 0; - sdata->vif.mu_mimo_owner = false; + sdata->vif.bss_conf.mu_mimo_owner = false;
mutex_lock(&sdata->local->mtx); ieee80211_vif_release_channel(sdata); @@ -4136,7 +4136,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, return;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (!chanctx_conf) { rcu_read_unlock(); return; @@ -4805,7 +4805,7 @@ static void ieee80211_sta_bcn_mon_timer(struct timer_list *t) from_timer(sdata, t, u.mgd.bcn_mon_timer); struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) + if (sdata->vif.bss_conf.csa_active && !ifmgd->csa_waiting_bcn) return;
if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER) @@ -4825,7 +4825,7 @@ static void ieee80211_sta_conn_mon_timer(struct timer_list *t) struct sta_info *sta; unsigned long timeout;
- if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) + if (sdata->vif.bss_conf.csa_active && !ifmgd->csa_waiting_bcn) return;
sta = sta_info_get(sdata, ifmgd->bssid); diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c index f97cb4c453d3..d0f0d96b0948 100644 --- a/net/mac80211/ocb.c +++ b/net/mac80211/ocb.c @@ -4,6 +4,7 @@ * * Copyright: (c) 2014 Czech Technical University in Prague * (c) 2014 Volkswagen Group Research + * Copyright (C) 2022 Intel Corporation * Author: Rostislav Lisovy rostislav.lisovy@fel.cvut.cz * Funded by: Volkswagen Group Research */ @@ -59,7 +60,7 @@ void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata, ocb_dbg(sdata, "Adding new OCB station %pM\n", addr);
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON_ONCE(!chanctx_conf)) { rcu_read_unlock(); return; diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index c5d2ab9df1e7..a1fbd562cac1 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -8,7 +8,7 @@ * Copyright 2006-2007 Jiri Benc jbenc@suse.cz * Copyright 2007, Michael Wu flamingice@sourmilk.net * Copyright 2009 Johannes Berg johannes@sipsolutions.net - * Copyright (C) 2019 Intel Corporation + * Copyright (C) 2019, 2022 Intel Corporation */ #include <linux/export.h> #include <net/mac80211.h> @@ -845,7 +845,7 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, struct ieee80211_chanctx_conf *chanctx_conf;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
if (chanctx_conf) { need_offchan = params->chan && @@ -876,7 +876,7 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, data = skb_put_data(skb, params->buf, params->len);
/* Update CSA counters */ - if (sdata->vif.csa_active && + if (sdata->vif.bss_conf.csa_active && (sdata->vif.type == NL80211_IFTYPE_AP || sdata->vif.type == NL80211_IFTYPE_MESH_POINT || sdata->vif.type == NL80211_IFTYPE_ADHOC) && diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index ae9700e0a1a5..f22381127948 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -4,6 +4,7 @@ * Copyright 2005-2006, Devicescape Software, Inc. * Copyright (c) 2006 Jiri Benc jbenc@suse.cz * Copyright 2017 Intel Deutschland GmbH + * Copyright (C) 2022 Intel Corporation */
#include <linux/kernel.h> @@ -43,7 +44,7 @@ void rate_control_rate_init(struct sta_info *sta)
rcu_read_lock();
- chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sta->sdata->vif.bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { rcu_read_unlock(); return; @@ -100,7 +101,7 @@ void rate_control_rate_update(struct ieee80211_local *local, if (ref && ref->ops->rate_update) { rcu_read_lock();
- chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sta->sdata->vif.bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { rcu_read_unlock(); return; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 1675f8cb87f1..b938806a5184 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3192,7 +3192,7 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx) if (ieee80211_hw_check(&rx->local->hw, DETECTS_COLOR_COLLISION)) return;
- if (rx->sdata->vif.csa_active) + if (rx->sdata->vif.bss_conf.csa_active) return;
baselen = mgmt->u.beacon.variable - rx->skb->data; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 8b192cf7d446..c0b2ce70e101 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1469,7 +1469,7 @@ static void ieee80211_send_null_response(struct sta_info *sta, int tid, skb->dev = sdata->dev;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { rcu_read_unlock(); kfree_skb(skb); diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 4e2d22e47429..fa04021d4c0f 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -6,7 +6,7 @@ * Copyright 2014, Intel Corporation * Copyright 2014 Intel Mobile Communications GmbH * Copyright 2015 - 2016 Intel Deutschland GmbH - * Copyright (C) 2019, 2021 Intel Corporation + * Copyright (C) 2019, 2021-2022 Intel Corporation */
#include <linux/ieee80211.h> @@ -1254,7 +1254,7 @@ static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata, struct ieee80211_supported_band *sband;
mutex_lock(&local->chanctx_mtx); - conf = rcu_dereference_protected(sdata->vif.chanctx_conf, + conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, lockdep_is_held(&local->chanctx_mtx)); if (conf) { width = conf->def.width; @@ -1372,7 +1372,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
switch (oper) { case NL80211_TDLS_ENABLE_LINK: - if (sdata->vif.csa_active) { + if (sdata->vif.bss_conf.csa_active) { tdls_dbg(sdata, "TDLS: disallow link during CSA\n"); ret = -EBUSY; break; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c425f4fb7c2e..3cd24d8170d3 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -57,7 +57,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, return 0;
rcu_read_lock(); - chanctx_conf = rcu_dereference(tx->sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(tx->sdata->vif.bss_conf.chanctx_conf); if (chanctx_conf) { shift = ieee80211_chandef_get_shift(&chanctx_conf->def); rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def); @@ -2347,12 +2347,12 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, } }
- chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (!chanctx_conf) { tmp_sdata = rcu_dereference(local->monitor_sdata); if (tmp_sdata) chanctx_conf = - rcu_dereference(tmp_sdata->vif.chanctx_conf); + rcu_dereference(tmp_sdata->vif.bss_conf.chanctx_conf); }
if (chanctx_conf) @@ -2601,7 +2601,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, } ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); - chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(ap_sdata->vif.bss_conf.chanctx_conf); if (!chanctx_conf) { ret = -ENOTCONN; goto free; @@ -2612,7 +2612,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, fallthrough; case NL80211_IFTYPE_AP: if (sdata->vif.type == NL80211_IFTYPE_AP) - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (!chanctx_conf) { ret = -ENOTCONN; goto free; @@ -2691,7 +2691,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, skb->data + ETH_ALEN);
} - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (!chanctx_conf) { ret = -ENOTCONN; goto free; @@ -2734,7 +2734,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, memcpy(hdr.addr3, skb->data, ETH_ALEN); hdrlen = 24; } - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (!chanctx_conf) { ret = -ENOTCONN; goto free; @@ -2747,7 +2747,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); eth_broadcast_addr(hdr.addr3); hdrlen = 24; - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (!chanctx_conf) { ret = -ENOTCONN; goto free; @@ -2760,7 +2760,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); memcpy(hdr.addr3, sdata->u.ibss.bssid, ETH_ALEN); hdrlen = 24; - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (!chanctx_conf) { ret = -ENOTCONN; goto free; @@ -2974,7 +2974,7 @@ void ieee80211_check_fast_xmit(struct sta_info *sta) goto out;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (!chanctx_conf) { rcu_read_unlock(); goto out; @@ -4605,7 +4605,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, sdata = vif_to_sdata(info->control.vif);
if (info->control.flags & IEEE80211_TX_INTCFL_NEED_TXPROCESSING) { - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (unlikely(!chanctx_conf)) { dev_kfree_skb(skb); return true; @@ -4809,7 +4809,7 @@ static void ieee80211_set_beacon_cntdwn(struct ieee80211_sub_if_data *sdata,
bcn_offsets = beacon->cntdwn_counter_offsets; count = beacon->cntdwn_current_counter; - if (sdata->vif.csa_active) + if (sdata->vif.bss_conf.csa_active) max_count = IEEE80211_MAX_CNTDWN_COUNTERS_NUM;
for (i = 0; i < max_count; ++i) { @@ -5120,7 +5120,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw, rcu_read_lock();
sdata = vif_to_sdata(vif); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
if (!ieee80211_sdata_running(sdata) || !chanctx_conf) goto out; @@ -5537,7 +5537,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, sdata = vif_to_sdata(vif);
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
if (!chanctx_conf) goto out; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index dad42d42aa84..b58df3e63a86 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1569,7 +1569,7 @@ void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata, return;
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (chanctx_conf) center_freq = chanctx_conf->def.chan->center_freq;
@@ -1616,7 +1616,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, memset(&qparam, 0, sizeof(qparam));
rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); use_11b = (chanctx_conf && chanctx_conf->def.chan->band == NL80211_BAND_2GHZ) && !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); @@ -2267,7 +2267,7 @@ static void ieee80211_assign_chanctx(struct ieee80211_local *local, return;
mutex_lock(&local->chanctx_mtx); - conf = rcu_dereference_protected(sdata->vif.chanctx_conf, + conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, lockdep_is_held(&local->chanctx_mtx)); if (conf) { ctx = container_of(conf, struct ieee80211_chanctx, conf); @@ -2526,7 +2526,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) BSS_CHANGED_TXPOWER | BSS_CHANGED_MCAST_RATE;
- if (sdata->vif.mu_mimo_owner) + if (sdata->vif.bss_conf.mu_mimo_owner) changed |= BSS_CHANGED_MU_GROUPS;
switch (sdata->vif.type) { @@ -2809,8 +2809,8 @@ void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata)
mutex_lock(&local->chanctx_mtx);
- chanctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf, - lockdep_is_held(&local->chanctx_mtx)); + chanctx_conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, + lockdep_is_held(&local->chanctx_mtx));
/* * This function can be called from a work, thus it may be possible @@ -2835,8 +2835,8 @@ void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata)
mutex_lock(&local->chanctx_mtx);
- chanctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf, - lockdep_is_held(&local->chanctx_mtx)); + chanctx_conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, + lockdep_is_held(&local->chanctx_mtx));
if (WARN_ON_ONCE(!chanctx_conf)) goto unlock; diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index ff26e0c4787b..ac97584b3a0b 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c @@ -4,7 +4,7 @@ * * Portions of this file * Copyright(c) 2015 - 2016 Intel Deutschland GmbH - * Copyright (C) 2018 - 2021 Intel Corporation + * Copyright (C) 2018 - 2022 Intel Corporation */
#include <linux/ieee80211.h> @@ -649,7 +649,7 @@ void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata, { struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
- if (!sdata->vif.mu_mimo_owner) + if (!sdata->vif.bss_conf.mu_mimo_owner) return;
if (!memcmp(mgmt->u.action.u.vht_group_notif.position, @@ -673,7 +673,7 @@ void ieee80211_update_mu_groups(struct ieee80211_vif *vif, { struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- if (WARN_ON_ONCE(!vif->mu_mimo_owner)) + if (WARN_ON_ONCE(!vif->bss_conf.mu_mimo_owner)) return;
memcpy(bss_conf->mu_group.membership, membership, WLAN_MEMBERSHIP_LEN);
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 79717c4eeeae9dec894794fbe8af72f08f03ebdd ]
Do not update pm stats if mt7615_mcu_fw_pmctrl returns an error.
Fixes: abe912ae3cd42 ("mt76: mt7663: add awake and doze time accounting") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index 8fb6c9d735dc..d2dd1260382c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -350,10 +350,11 @@ static int mt7615_mcu_fw_pmctrl(struct mt7615_dev *dev) }
mt7622_trigger_hif_int(dev, false); - - pm->stats.last_doze_event = jiffies; - pm->stats.awake_time += pm->stats.last_doze_event - - pm->stats.last_wake_event; + if (!err) { + pm->stats.last_doze_event = jiffies; + pm->stats.awake_time += pm->stats.last_doze_event - + pm->stats.last_wake_event; + } out: mutex_unlock(&pm->mutex);
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit f4a92547fb9818ff272e1e2f0c79cd6b0bc99ce8 ]
Do not update pm stats if mt7921e_mcu_fw_pmctrl routine returns an error.
Fixes: 36873246f78a2 ("mt76: mt7921: add awake and doze time accounting") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c index 36669e5aeef3..a1ab5f878f81 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c @@ -102,7 +102,7 @@ int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev) { struct mt76_phy *mphy = &dev->mt76.phy; struct mt76_connac_pm *pm = &dev->pm; - int i, err = 0; + int i;
for (i = 0; i < MT7921_DRV_OWN_RETRY_COUNT; i++) { mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_SET_OWN); @@ -114,12 +114,12 @@ int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev) if (i == MT7921_DRV_OWN_RETRY_COUNT) { dev_err(dev->mt76.dev, "firmware own failed\n"); clear_bit(MT76_STATE_PM, &mphy->state); - err = -EIO; + return -EIO; }
pm->stats.last_doze_event = jiffies; pm->stats.awake_time += pm->stats.last_doze_event - pm->stats.last_wake_event;
- return err; + return 0; }
From: Deren Wu deren.wu@mediatek.com
[ Upstream commit 364718c94ac2ea4e51958ac0aa15c9092c785a3a ]
Move sdio_release_host() to final resource handing
Fixes: b12deb5e86fa ("mt76: mt7921s: fix mt7921s_mcu_[fw|drv]_pmctrl") Reported-by: YN Chen YN.Chen@mediatek.com Co-developed-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Deren Wu deren.wu@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c index 54a5c712a3c3..c572a3107b8b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c @@ -136,8 +136,8 @@ int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev) struct sdio_func *func = dev->mt76.sdio.func; struct mt76_phy *mphy = &dev->mt76.phy; struct mt76_connac_pm *pm = &dev->pm; - int err = 0; u32 status; + int err;
sdio_claim_host(func);
@@ -148,7 +148,7 @@ int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev) 2000, 1000000); if (err < 0) { dev_err(dev->mt76.dev, "mailbox ACK not cleared\n"); - goto err; + goto out; } }
@@ -156,18 +156,18 @@ int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev)
err = readx_poll_timeout(mt76s_read_pcr, &dev->mt76, status, !(status & WHLPCR_IS_DRIVER_OWN), 2000, 1000000); +out: sdio_release_host(func);
-err: if (err < 0) { dev_err(dev->mt76.dev, "firmware own failed\n"); clear_bit(MT76_STATE_PM, &mphy->state); - err = -EIO; + return -EIO; }
pm->stats.last_doze_event = jiffies; pm->stats.awake_time += pm->stats.last_doze_event - pm->stats.last_wake_event;
- return err; + return 0; }
From: Deren Wu deren.wu@mediatek.com
[ Upstream commit d5a50e6bd1972c481f82befa846dce0b9866f025 ]
mt7921/mt7922 support HE max aggregation subframes 256 for both tx/rx. Get better throughput then before.
Fixes: 94bb18b03d43 ("mt76: mt7921: fix max aggregation subframes setting") Tested-by: Ming Yen Hsieh mingyen.hsieh@mediatek.com Reviewed-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Deren Wu deren.wu@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index 4a8675634f80..dd19835313ed 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -53,8 +53,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw) struct wiphy *wiphy = hw->wiphy;
hw->queues = 4; - hw->max_rx_aggregation_subframes = 64; - hw->max_tx_aggregation_subframes = 128; + hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE; + hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE; hw->netdev_features = NETIF_F_RXCSUM;
hw->radiotap_timestamp.units_pos =
From: Deren Wu deren.wu@mediatek.com
[ Upstream commit 31f3248a75932b111bc90c66b1f6c7d89eedca8e ]
Enlarge maximum MPDU length to 11454 that both mt7921/mt7922 can support. After this fixing, we can get better performance.
Fixes: 5c14a5f944b9 ("mt76: mt7921: introduce mt7921e support") Tested-by: Ming Yen Hsieh mingyen.hsieh@mediatek.com Signed-off-by: Deren Wu deren.wu@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index dd19835313ed..8ff1a0f2f076 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -304,7 +304,7 @@ int mt7921_register_device(struct mt7921_dev *dev) IEEE80211_HT_CAP_LDPC_CODING | IEEE80211_HT_CAP_MAX_AMSDU; dev->mphy.sband_5g.sband.vht_cap.cap |= - IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 | + IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit e00b3e407efeed81dc30a72e4041ff57bf7068d5 ]
This is a preliminary patch to share txwi configuration code.
Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/mediatek/mt76/mt7921/mac.c | 23 +++++++++---------- .../net/wireless/mediatek/mt76/mt7921/mcu.c | 2 +- .../wireless/mediatek/mt76/mt7921/mt7921.h | 2 +- .../wireless/mediatek/mt76/mt7921/pci_mac.c | 2 +- 4 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index a630ddbf19e5..2d4c81eec6dc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -809,8 +809,8 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) }
static void -mt7921_mac_write_txwi_8023(struct mt7921_dev *dev, __le32 *txwi, - struct sk_buff *skb, struct mt76_wcid *wcid) +mt7921_mac_write_txwi_8023(__le32 *txwi, struct sk_buff *skb, + struct mt76_wcid *wcid) { u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; u8 fc_type, fc_stype; @@ -848,7 +848,7 @@ mt7921_mac_write_txwi_8023(struct mt7921_dev *dev, __le32 *txwi, }
static void -mt7921_mac_write_txwi_80211(struct mt7921_dev *dev, __le32 *txwi, +mt7921_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, struct sk_buff *skb, struct ieee80211_key_conf *key) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -920,7 +920,7 @@ mt7921_mac_write_txwi_80211(struct mt7921_dev *dev, __le32 *txwi, txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU); }
- if (mt76_is_mmio(&dev->mt76)) { + if (mt76_is_mmio(dev)) { val = FIELD_PREP(MT_TXD7_TYPE, fc_type) | FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype); txwi[7] |= cpu_to_le32(val); @@ -931,17 +931,16 @@ mt7921_mac_write_txwi_80211(struct mt7921_dev *dev, __le32 *txwi, } }
-void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi, +void mt7921_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_key_conf *key, int pid, bool beacon) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_vif *vif = info->control.vif; - struct mt76_phy *mphy = &dev->mphy; + struct mt76_phy *mphy = &dev->phy; u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0; - bool is_mmio = mt76_is_mmio(&dev->mt76); - u32 sz_txd = is_mmio ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE; + u32 sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE; bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; u16 tx_count = 15; u32 val; @@ -957,10 +956,10 @@ void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi, p_fmt = MT_TX_TYPE_FW; q_idx = MT_LMAC_BCN0; } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) { - p_fmt = is_mmio ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; q_idx = MT_LMAC_ALTX0; } else { - p_fmt = is_mmio ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; q_idx = wmm_idx * MT7921_MAX_WMM_SETS + mt76_connac_lmac_mapping(skb_get_queue_mapping(skb)); } @@ -995,7 +994,7 @@ void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi, txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
if (is_8023) - mt7921_mac_write_txwi_8023(dev, txwi, skb, wcid); + mt7921_mac_write_txwi_8023(txwi, skb, wcid); else mt7921_mac_write_txwi_80211(dev, txwi, skb, key);
@@ -1646,7 +1645,7 @@ mt7921_usb_sdio_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid, __le32 *txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE);
memset(txwi, 0, MT_SDIO_TXD_SIZE); - mt7921_mac_write_txwi(dev, txwi, skb, wcid, key, pid, false); + mt7921_mac_write_txwi(&dev->mt76, txwi, skb, wcid, key, pid, false); skb_push(skb, MT_SDIO_TXD_SIZE); }
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 3765b345b741..6ccd469eb3e4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -1272,7 +1272,7 @@ mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, return -EINVAL; }
- mt7921_mac_write_txwi(dev, (__le32 *)(req.beacon_tlv.pkt), skb, + mt7921_mac_write_txwi(&dev->mt76, (__le32 *)(req.beacon_tlv.pkt), skb, wcid, NULL, 0, true); memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len); req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 5ca584bb2fc6..3dfc2d593aa4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -424,7 +424,7 @@ int mt7921_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void *data, int len); int mt7921_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, struct netlink_callback *cb, void *data, int len); -void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi, +void mt7921_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_key_conf *key, int pid, bool beacon); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c index 5ca14dbbdd26..f261cbfae2f3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c @@ -72,7 +72,7 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, }
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); - mt7921_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key, + mt7921_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, key, pid, false);
txp = (struct mt7921_txp_common *)(txwi + MT_TXD_SIZE);
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit d502e30020b85857ead0f9d392d24dba8c0f44cb ]
This is a preliminary patch to share txwi configuration code.
Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/mediatek/mt76/mt7915/mac.c | 23 +++++++++---------- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 4 ++-- .../wireless/mediatek/mt76/mt7915/mt7915.h | 2 +- 3 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index 086244d9be76..b8704018dcc0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -1010,8 +1010,8 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi, }
static void -mt7915_mac_write_txwi_8023(struct mt7915_dev *dev, __le32 *txwi, - struct sk_buff *skb, struct mt76_wcid *wcid) +mt7915_mac_write_txwi_8023(__le32 *txwi, struct sk_buff *skb, + struct mt76_wcid *wcid) {
u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; @@ -1050,9 +1050,8 @@ mt7915_mac_write_txwi_8023(struct mt7915_dev *dev, __le32 *txwi, }
static void -mt7915_mac_write_txwi_80211(struct mt7915_dev *dev, __le32 *txwi, - struct sk_buff *skb, struct ieee80211_key_conf *key, - bool *mcast) +mt7915_mac_write_txwi_80211(__le32 *txwi, struct sk_buff *skb, + struct ieee80211_key_conf *key, bool *mcast) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; @@ -1175,13 +1174,13 @@ mt7915_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif, FIELD_PREP(MT_TX_RATE_MODE, mode); }
-void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, +void mt7915_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, int pid, struct ieee80211_key_conf *key, u32 changed) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_vif *vif = info->control.vif; - struct mt76_phy *mphy = &dev->mphy; + struct mt76_phy *mphy = &dev->phy; bool ext_phy = info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY; u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0, band_idx = 0; bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; @@ -1201,8 +1200,8 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, band_idx = mvif->mt76.band_idx; }
- if (ext_phy && dev->mt76.phy2) - mphy = dev->mt76.phy2; + if (ext_phy && dev->phy2) + mphy = dev->phy2;
if (inband_disc) { p_fmt = MT_TX_TYPE_FW; @@ -1254,9 +1253,9 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
if (is_8023) - mt7915_mac_write_txwi_8023(dev, txwi, skb, wcid); + mt7915_mac_write_txwi_8023(txwi, skb, wcid); else - mt7915_mac_write_txwi_80211(dev, txwi, skb, key, &mcast); + mt7915_mac_write_txwi_80211(txwi, skb, key, &mcast);
if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) { u16 rate = mt7915_mac_tx_rate_val(mphy, vif, beacon, mcast); @@ -1315,7 +1314,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, return id;
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); - mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key, 0); + mt7915_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, pid, key, 0);
txp = (struct mt7915_txp *)(txwi + MT_TXD_SIZE); for (i = 0; i < nbuf; i++) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 1b3d6634a72e..4ac45fd63662 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -1910,7 +1910,7 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif, }
buf = (u8 *)tlv + sizeof(*cont); - mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL, + mt7915_mac_write_txwi(&dev->mt76, (__le32 *)buf, skb, wcid, 0, NULL, BSS_CHANGED_BEACON); memcpy(buf + MT_TXD_SIZE, skb->data, skb->len); } @@ -2049,7 +2049,7 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi
buf = (u8 *)tlv + sizeof(*discov);
- mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL, + mt7915_mac_write_txwi(&dev->mt76, (__le32 *)buf, skb, wcid, 0, NULL, changed); memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 4dcae6991669..8fcaa1d22f01 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -557,7 +557,7 @@ bool mt7915_mac_wtbl_update(struct mt7915_dev *dev, int idx, u32 mask); void mt7915_mac_reset_counters(struct mt7915_phy *phy); void mt7915_mac_cca_stats_reset(struct mt7915_phy *phy); void mt7915_mac_enable_nf(struct mt7915_dev *dev, bool ext_phy); -void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, +void mt7915_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, int pid, struct ieee80211_key_conf *key, u32 changed); void mt7915_mac_set_timing(struct mt7915_phy *phy);
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 90211957a640e6933b236e06728578d252f7374f ]
This is a preliminary patch to share connac2 mac txwi code.
Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- .../wireless/mediatek/mt76/mt76_connac2_mac.h | 167 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7915/mac.h | 142 +-------------- .../wireless/mediatek/mt76/mt7915/mt7915.h | 14 -- .../net/wireless/mediatek/mt76/mt7921/mac.h | 123 +------------ .../wireless/mediatek/mt76/mt7921/mt7921.h | 10 -- 5 files changed, 171 insertions(+), 285 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h new file mode 100644 index 000000000000..c9d9c8475a38 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: ISC */ +/* Copyright (C) 2022 MediaTek Inc. */ + +#ifndef __MT76_CONNAC2_MAC_H +#define __MT76_CONNAC2_MAC_H + +enum tx_header_format { + MT_HDR_FORMAT_802_3, + MT_HDR_FORMAT_CMD, + MT_HDR_FORMAT_802_11, + MT_HDR_FORMAT_802_11_EXT, +}; + +enum tx_pkt_type { + MT_TX_TYPE_CT, + MT_TX_TYPE_SF, + MT_TX_TYPE_CMD, + MT_TX_TYPE_FW, +}; + +enum { + MT_CTX0, + MT_HIF0 = 0x0, + + MT_LMAC_AC00 = 0x0, + MT_LMAC_AC01, + MT_LMAC_AC02, + MT_LMAC_AC03, + MT_LMAC_ALTX0 = 0x10, + MT_LMAC_BMC0, + MT_LMAC_BCN0, + MT_LMAC_PSMP0, +}; + +#define MT_TXD_SIZE (8 * 4) +#define MT_SDIO_TXD_SIZE (MT_TXD_SIZE + 8 * 4) +#define MT_SDIO_TAIL_SIZE 8 +#define MT_SDIO_HDR_SIZE 4 +#define MT_USB_TAIL_SIZE 4 + +#define MT_TXD0_Q_IDX GENMASK(31, 25) +#define MT_TXD0_PKT_FMT GENMASK(24, 23) +#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16) +#define MT_TXD0_TX_BYTES GENMASK(15, 0) + +#define MT_TXD1_LONG_FORMAT BIT(31) +#define MT_TXD1_TGID BIT(30) +#define MT_TXD1_OWN_MAC GENMASK(29, 24) +#define MT_TXD1_AMSDU BIT(23) +#define MT_TXD1_TID GENMASK(22, 20) +#define MT_TXD1_HDR_PAD GENMASK(19, 18) +#define MT_TXD1_HDR_FORMAT GENMASK(17, 16) +#define MT_TXD1_HDR_INFO GENMASK(15, 11) +#define MT_TXD1_ETH_802_3 BIT(15) +#define MT_TXD1_VTA BIT(10) +#define MT_TXD1_WLAN_IDX GENMASK(9, 0) + +#define MT_TXD2_FIX_RATE BIT(31) +#define MT_TXD2_FIXED_RATE BIT(30) +#define MT_TXD2_POWER_OFFSET GENMASK(29, 24) +#define MT_TXD2_MAX_TX_TIME GENMASK(23, 16) +#define MT_TXD2_FRAG GENMASK(15, 14) +#define MT_TXD2_HTC_VLD BIT(13) +#define MT_TXD2_DURATION BIT(12) +#define MT_TXD2_BIP BIT(11) +#define MT_TXD2_MULTICAST BIT(10) +#define MT_TXD2_RTS BIT(9) +#define MT_TXD2_SOUNDING BIT(8) +#define MT_TXD2_NDPA BIT(7) +#define MT_TXD2_NDP BIT(6) +#define MT_TXD2_FRAME_TYPE GENMASK(5, 4) +#define MT_TXD2_SUB_TYPE GENMASK(3, 0) + +#define MT_TXD3_SN_VALID BIT(31) +#define MT_TXD3_PN_VALID BIT(30) +#define MT_TXD3_SW_POWER_MGMT BIT(29) +#define MT_TXD3_BA_DISABLE BIT(28) +#define MT_TXD3_SEQ GENMASK(27, 16) +#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11) +#define MT_TXD3_TX_COUNT GENMASK(10, 6) +#define MT_TXD3_TIMING_MEASURE BIT(5) +#define MT_TXD3_DAS BIT(4) +#define MT_TXD3_EEOSP BIT(3) +#define MT_TXD3_EMRD BIT(2) +#define MT_TXD3_PROTECT_FRAME BIT(1) +#define MT_TXD3_NO_ACK BIT(0) + +#define MT_TXD4_PN_LOW GENMASK(31, 0) + +#define MT_TXD5_PN_HIGH GENMASK(31, 16) +#define MT_TXD5_MD BIT(15) +#define MT_TXD5_ADD_BA BIT(14) +#define MT_TXD5_TX_STATUS_HOST BIT(10) +#define MT_TXD5_TX_STATUS_MCU BIT(9) +#define MT_TXD5_TX_STATUS_FMT BIT(8) +#define MT_TXD5_PID GENMASK(7, 0) + +#define MT_TXD6_TX_IBF BIT(31) +#define MT_TXD6_TX_EBF BIT(30) +#define MT_TXD6_TX_RATE GENMASK(29, 16) +#define MT_TXD6_SGI GENMASK(15, 14) +#define MT_TXD6_HELTF GENMASK(13, 12) +#define MT_TXD6_LDPC BIT(11) +#define MT_TXD6_SPE_ID_IDX BIT(10) +#define MT_TXD6_ANT_ID GENMASK(7, 4) +#define MT_TXD6_DYN_BW BIT(3) +#define MT_TXD6_FIXED_BW BIT(2) +#define MT_TXD6_BW GENMASK(1, 0) + +#define MT_TXD7_TXD_LEN GENMASK(31, 30) +#define MT_TXD7_UDP_TCP_SUM BIT(29) +#define MT_TXD7_IP_SUM BIT(28) +#define MT_TXD7_TYPE GENMASK(21, 20) +#define MT_TXD7_SUB_TYPE GENMASK(19, 16) + +#define MT_TXD7_PSE_FID GENMASK(27, 16) +#define MT_TXD7_SPE_IDX GENMASK(15, 11) +#define MT_TXD7_HW_AMSDU BIT(10) +#define MT_TXD7_TX_TIME GENMASK(9, 0) + +#define MT_TXD8_L_TYPE GENMASK(5, 4) +#define MT_TXD8_L_SUB_TYPE GENMASK(3, 0) + +#define MT_TX_RATE_STBC BIT(13) +#define MT_TX_RATE_NSS GENMASK(12, 10) +#define MT_TX_RATE_MODE GENMASK(9, 6) +#define MT_TX_RATE_SU_EXT_TONE BIT(5) +#define MT_TX_RATE_DCM BIT(4) +/* VHT/HE only use bits 0-3 */ +#define MT_TX_RATE_IDX GENMASK(5, 0) + +#define MT_TXS0_FIXED_RATE BIT(31) +#define MT_TXS0_BW GENMASK(30, 29) +#define MT_TXS0_TID GENMASK(28, 26) +#define MT_TXS0_AMPDU BIT(25) +#define MT_TXS0_TXS_FORMAT GENMASK(24, 23) +#define MT_TXS0_BA_ERROR BIT(22) +#define MT_TXS0_PS_FLAG BIT(21) +#define MT_TXS0_TXOP_TIMEOUT BIT(20) +#define MT_TXS0_BIP_ERROR BIT(19) + +#define MT_TXS0_QUEUE_TIMEOUT BIT(18) +#define MT_TXS0_RTS_TIMEOUT BIT(17) +#define MT_TXS0_ACK_TIMEOUT BIT(16) +#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16) + +#define MT_TXS0_TX_STATUS_HOST BIT(15) +#define MT_TXS0_TX_STATUS_MCU BIT(14) +#define MT_TXS0_TX_RATE GENMASK(13, 0) + +#define MT_TXS1_SEQNO GENMASK(31, 20) +#define MT_TXS1_RESP_RATE GENMASK(19, 16) +#define MT_TXS1_RXV_SEQNO GENMASK(15, 8) +#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0) + +#define MT_TXS2_BF_STATUS GENMASK(31, 30) +#define MT_TXS2_LAST_TX_RATE GENMASK(29, 27) +#define MT_TXS2_SHARED_ANTENNA BIT(26) +#define MT_TXS2_WCID GENMASK(25, 16) +#define MT_TXS2_TX_DELAY GENMASK(15, 0) + +#define MT_TXS3_PID GENMASK(31, 24) +#define MT_TXS3_ANT_ID GENMASK(23, 0) + +#define MT_TXS4_TIMESTAMP GENMASK(31, 0) + +#endif /* __MT76_CONNAC2_MAC_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h index c5fd1a618ae7..f581ae27375b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h @@ -4,6 +4,8 @@ #ifndef __MT7915_MAC_H #define __MT7915_MAC_H
+#include "../mt76_connac2_mac.h" + #define MT_CT_PARSE_LEN 72 #define MT_CT_DMA_BUF_NUM 2
@@ -166,20 +168,6 @@ enum rx_pkt_type { #define MT_CRXV_FOE_HI GENMASK(6, 0) #define MT_CRXV_FOE_SHIFT 13
-enum tx_header_format { - MT_HDR_FORMAT_802_3, - MT_HDR_FORMAT_CMD, - MT_HDR_FORMAT_802_11, - MT_HDR_FORMAT_802_11_EXT, -}; - -enum tx_pkt_type { - MT_TX_TYPE_CT, - MT_TX_TYPE_SF, - MT_TX_TYPE_CMD, - MT_TX_TYPE_FW, -}; - enum tx_port_idx { MT_TX_PORT_IDX_LMAC, MT_TX_PORT_IDX_MCU @@ -200,97 +188,6 @@ enum tx_mcu_port_q_idx { #define MT_CT_INFO_HSR2_TX BIT(4) #define MT_CT_INFO_FROM_HOST BIT(7)
-#define MT_TXD_SIZE (8 * 4) - -#define MT_TXD0_Q_IDX GENMASK(31, 25) -#define MT_TXD0_PKT_FMT GENMASK(24, 23) -#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16) -#define MT_TXD0_TX_BYTES GENMASK(15, 0) - -#define MT_TXD1_LONG_FORMAT BIT(31) -#define MT_TXD1_TGID BIT(30) -#define MT_TXD1_OWN_MAC GENMASK(29, 24) -#define MT_TXD1_AMSDU BIT(23) -#define MT_TXD1_TID GENMASK(22, 20) -#define MT_TXD1_HDR_PAD GENMASK(19, 18) -#define MT_TXD1_HDR_FORMAT GENMASK(17, 16) -#define MT_TXD1_HDR_INFO GENMASK(15, 11) -#define MT_TXD1_ETH_802_3 BIT(15) -#define MT_TXD1_VTA BIT(10) -#define MT_TXD1_WLAN_IDX GENMASK(9, 0) - -#define MT_TXD2_FIX_RATE BIT(31) -#define MT_TXD2_FIXED_RATE BIT(30) -#define MT_TXD2_POWER_OFFSET GENMASK(29, 24) -#define MT_TXD2_MAX_TX_TIME GENMASK(23, 16) -#define MT_TXD2_FRAG GENMASK(15, 14) -#define MT_TXD2_HTC_VLD BIT(13) -#define MT_TXD2_DURATION BIT(12) -#define MT_TXD2_BIP BIT(11) -#define MT_TXD2_MULTICAST BIT(10) -#define MT_TXD2_RTS BIT(9) -#define MT_TXD2_SOUNDING BIT(8) -#define MT_TXD2_NDPA BIT(7) -#define MT_TXD2_NDP BIT(6) -#define MT_TXD2_FRAME_TYPE GENMASK(5, 4) -#define MT_TXD2_SUB_TYPE GENMASK(3, 0) - -#define MT_TXD3_SN_VALID BIT(31) -#define MT_TXD3_PN_VALID BIT(30) -#define MT_TXD3_SW_POWER_MGMT BIT(29) -#define MT_TXD3_BA_DISABLE BIT(28) -#define MT_TXD3_SEQ GENMASK(27, 16) -#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11) -#define MT_TXD3_TX_COUNT GENMASK(10, 6) -#define MT_TXD3_TIMING_MEASURE BIT(5) -#define MT_TXD3_DAS BIT(4) -#define MT_TXD3_EEOSP BIT(3) -#define MT_TXD3_EMRD BIT(2) -#define MT_TXD3_PROTECT_FRAME BIT(1) -#define MT_TXD3_NO_ACK BIT(0) - -#define MT_TXD4_PN_LOW GENMASK(31, 0) - -#define MT_TXD5_PN_HIGH GENMASK(31, 16) -#define MT_TXD5_MD BIT(15) -#define MT_TXD5_ADD_BA BIT(14) -#define MT_TXD5_TX_STATUS_HOST BIT(10) -#define MT_TXD5_TX_STATUS_MCU BIT(9) -#define MT_TXD5_TX_STATUS_FMT BIT(8) -#define MT_TXD5_PID GENMASK(7, 0) - -#define MT_TXD6_TX_IBF BIT(31) -#define MT_TXD6_TX_EBF BIT(30) -#define MT_TXD6_TX_RATE GENMASK(29, 16) -#define MT_TXD6_SGI GENMASK(15, 14) -#define MT_TXD6_HELTF GENMASK(13, 12) -#define MT_TXD6_LDPC BIT(11) -#define MT_TXD6_SPE_ID_IDX BIT(10) -#define MT_TXD6_ANT_ID GENMASK(7, 4) -#define MT_TXD6_DYN_BW BIT(3) -#define MT_TXD6_FIXED_BW BIT(2) -#define MT_TXD6_BW GENMASK(1, 0) - -#define MT_TXD7_TXD_LEN GENMASK(31, 30) -#define MT_TXD7_UDP_TCP_SUM BIT(29) -#define MT_TXD7_IP_SUM BIT(28) - -#define MT_TXD7_TYPE GENMASK(21, 20) -#define MT_TXD7_SUB_TYPE GENMASK(19, 16) - -#define MT_TXD7_PSE_FID GENMASK(27, 16) -#define MT_TXD7_SPE_IDX GENMASK(15, 11) -#define MT_TXD7_HW_AMSDU BIT(10) -#define MT_TXD7_TX_TIME GENMASK(9, 0) - -#define MT_TX_RATE_STBC BIT(13) -#define MT_TX_RATE_NSS GENMASK(12, 10) -#define MT_TX_RATE_MODE GENMASK(9, 6) -#define MT_TX_RATE_SU_EXT_TONE BIT(5) -#define MT_TX_RATE_DCM BIT(4) -/* VHT/HE only use bits 0-3 */ -#define MT_TX_RATE_IDX GENMASK(5, 0) - #define MT_TXP_MAX_BUF_NUM 6
struct mt7915_txp { @@ -324,41 +221,6 @@ struct mt7915_tx_free { /* will support this field in further revision */ #define MT_TX_FREE_RATE GENMASK(13, 0)
-#define MT_TXS0_FIXED_RATE BIT(31) -#define MT_TXS0_BW GENMASK(30, 29) -#define MT_TXS0_TID GENMASK(28, 26) -#define MT_TXS0_AMPDU BIT(25) -#define MT_TXS0_TXS_FORMAT GENMASK(24, 23) -#define MT_TXS0_BA_ERROR BIT(22) -#define MT_TXS0_PS_FLAG BIT(21) -#define MT_TXS0_TXOP_TIMEOUT BIT(20) -#define MT_TXS0_BIP_ERROR BIT(19) - -#define MT_TXS0_QUEUE_TIMEOUT BIT(18) -#define MT_TXS0_RTS_TIMEOUT BIT(17) -#define MT_TXS0_ACK_TIMEOUT BIT(16) -#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16) - -#define MT_TXS0_TX_STATUS_HOST BIT(15) -#define MT_TXS0_TX_STATUS_MCU BIT(14) -#define MT_TXS0_TX_RATE GENMASK(13, 0) - -#define MT_TXS1_SEQNO GENMASK(31, 20) -#define MT_TXS1_RESP_RATE GENMASK(19, 16) -#define MT_TXS1_RXV_SEQNO GENMASK(15, 8) -#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0) - -#define MT_TXS2_BF_STATUS GENMASK(31, 30) -#define MT_TXS2_LAST_TX_RATE GENMASK(29, 27) -#define MT_TXS2_SHARED_ANTENNA BIT(26) -#define MT_TXS2_WCID GENMASK(25, 16) -#define MT_TXS2_TX_DELAY GENMASK(15, 0) - -#define MT_TXS3_PID GENMASK(31, 24) -#define MT_TXS3_ANT_ID GENMASK(23, 0) - -#define MT_TXS4_TIMESTAMP GENMASK(31, 0) - #define MT_TXS5_F0_FINAL_MPDU BIT(31) #define MT_TXS5_F0_QOS BIT(30) #define MT_TXS5_F0_TX_COUNT GENMASK(29, 25) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 8fcaa1d22f01..440a76021ad0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -341,20 +341,6 @@ enum { __MT_WFDMA_MAX, };
-enum { - MT_CTX0, - MT_HIF0 = 0x0, - - MT_LMAC_AC00 = 0x0, - MT_LMAC_AC01, - MT_LMAC_AC02, - MT_LMAC_AC03, - MT_LMAC_ALTX0 = 0x10, - MT_LMAC_BMC0, - MT_LMAC_BCN0, - MT_LMAC_PSMP0, -}; - enum { MT_RX_SEL0, MT_RX_SEL1, diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h index 79447e2d0143..556e687bd235 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h @@ -4,6 +4,8 @@ #ifndef __MT7921_MAC_H #define __MT7921_MAC_H
+#include "../mt76_connac2_mac.h" + #define MT_CT_PARSE_LEN 72 #define MT_CT_DMA_BUF_NUM 2
@@ -163,20 +165,6 @@ enum rx_pkt_type { #define MT_CRXV_FOE_HI GENMASK(6, 0) #define MT_CRXV_FOE_SHIFT 13
-enum tx_header_format { - MT_HDR_FORMAT_802_3, - MT_HDR_FORMAT_CMD, - MT_HDR_FORMAT_802_11, - MT_HDR_FORMAT_802_11_EXT, -}; - -enum tx_pkt_type { - MT_TX_TYPE_CT, - MT_TX_TYPE_SF, - MT_TX_TYPE_CMD, - MT_TX_TYPE_FW, -}; - enum tx_port_idx { MT_TX_PORT_IDX_LMAC, MT_TX_PORT_IDX_MCU @@ -197,104 +185,6 @@ enum tx_mcu_port_q_idx { #define MT_CT_INFO_HSR2_TX BIT(4) #define MT_CT_INFO_FROM_HOST BIT(7)
-#define MT_TXD_SIZE (8 * 4) - -#define MT_SDIO_TXD_SIZE (MT_TXD_SIZE + 8 * 4) -#define MT_SDIO_TAIL_SIZE 8 -#define MT_SDIO_HDR_SIZE 4 -#define MT_USB_TAIL_SIZE 4 - -#define MT_TXD0_Q_IDX GENMASK(31, 25) -#define MT_TXD0_PKT_FMT GENMASK(24, 23) -#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16) -#define MT_TXD0_TX_BYTES GENMASK(15, 0) - -#define MT_TXD1_LONG_FORMAT BIT(31) -#define MT_TXD1_TGID BIT(30) -#define MT_TXD1_OWN_MAC GENMASK(29, 24) -#define MT_TXD1_AMSDU BIT(23) -#define MT_TXD1_TID GENMASK(22, 20) -#define MT_TXD1_HDR_PAD GENMASK(19, 18) -#define MT_TXD1_HDR_FORMAT GENMASK(17, 16) -#define MT_TXD1_HDR_INFO GENMASK(15, 11) -#define MT_TXD1_ETH_802_3 BIT(15) -#define MT_TXD1_VTA BIT(10) -#define MT_TXD1_WLAN_IDX GENMASK(9, 0) - -#define MT_TXD2_FIX_RATE BIT(31) -#define MT_TXD2_FIXED_RATE BIT(30) -#define MT_TXD2_POWER_OFFSET GENMASK(29, 24) -#define MT_TXD2_MAX_TX_TIME GENMASK(23, 16) -#define MT_TXD2_FRAG GENMASK(15, 14) -#define MT_TXD2_HTC_VLD BIT(13) -#define MT_TXD2_DURATION BIT(12) -#define MT_TXD2_BIP BIT(11) -#define MT_TXD2_MULTICAST BIT(10) -#define MT_TXD2_RTS BIT(9) -#define MT_TXD2_SOUNDING BIT(8) -#define MT_TXD2_NDPA BIT(7) -#define MT_TXD2_NDP BIT(6) -#define MT_TXD2_FRAME_TYPE GENMASK(5, 4) -#define MT_TXD2_SUB_TYPE GENMASK(3, 0) - -#define MT_TXD3_SN_VALID BIT(31) -#define MT_TXD3_PN_VALID BIT(30) -#define MT_TXD3_SW_POWER_MGMT BIT(29) -#define MT_TXD3_BA_DISABLE BIT(28) -#define MT_TXD3_SEQ GENMASK(27, 16) -#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11) -#define MT_TXD3_TX_COUNT GENMASK(10, 6) -#define MT_TXD3_TIMING_MEASURE BIT(5) -#define MT_TXD3_DAS BIT(4) -#define MT_TXD3_EEOSP BIT(3) -#define MT_TXD3_EMRD BIT(2) -#define MT_TXD3_PROTECT_FRAME BIT(1) -#define MT_TXD3_NO_ACK BIT(0) - -#define MT_TXD4_PN_LOW GENMASK(31, 0) - -#define MT_TXD5_PN_HIGH GENMASK(31, 16) -#define MT_TXD5_MD BIT(15) -#define MT_TXD5_ADD_BA BIT(14) -#define MT_TXD5_TX_STATUS_HOST BIT(10) -#define MT_TXD5_TX_STATUS_MCU BIT(9) -#define MT_TXD5_TX_STATUS_FMT BIT(8) -#define MT_TXD5_PID GENMASK(7, 0) - -#define MT_TXD6_TX_IBF BIT(31) -#define MT_TXD6_TX_EBF BIT(30) -#define MT_TXD6_TX_RATE GENMASK(29, 16) -#define MT_TXD6_SGI GENMASK(15, 14) -#define MT_TXD6_HELTF GENMASK(13, 12) -#define MT_TXD6_LDPC BIT(11) -#define MT_TXD6_SPE_ID_IDX BIT(10) -#define MT_TXD6_ANT_ID GENMASK(7, 4) -#define MT_TXD6_DYN_BW BIT(3) -#define MT_TXD6_FIXED_BW BIT(2) -#define MT_TXD6_BW GENMASK(1, 0) - -#define MT_TXD7_TXD_LEN GENMASK(31, 30) -#define MT_TXD7_UDP_TCP_SUM BIT(29) -#define MT_TXD7_IP_SUM BIT(28) - -#define MT_TXD7_TYPE GENMASK(21, 20) -#define MT_TXD7_SUB_TYPE GENMASK(19, 16) - -#define MT_TXD7_PSE_FID GENMASK(27, 16) -#define MT_TXD7_SPE_IDX GENMASK(15, 11) -#define MT_TXD7_HW_AMSDU BIT(10) -#define MT_TXD7_TX_TIME GENMASK(9, 0) - -#define MT_TXD8_L_TYPE GENMASK(5, 4) -#define MT_TXD8_L_SUB_TYPE GENMASK(3, 0) - -#define MT_TX_RATE_STBC BIT(13) -#define MT_TX_RATE_NSS GENMASK(12, 10) -#define MT_TX_RATE_MODE GENMASK(9, 6) -#define MT_TX_RATE_SU_EXT_TONE BIT(5) -#define MT_TX_RATE_DCM BIT(4) -#define MT_TX_RATE_IDX GENMASK(3, 0) - #define MT_TXP_MAX_BUF_NUM 6
struct mt7921_txp { @@ -325,15 +215,6 @@ struct mt7921_tx_free { /* will support this field in further revision */ #define MT_TX_FREE_RATE GENMASK(13, 0)
-#define MT_TXS0_BW GENMASK(30, 29) -#define MT_TXS0_TXS_FORMAT GENMASK(24, 23) -#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16) -#define MT_TXS0_TX_RATE GENMASK(13, 0) - -#define MT_TXS2_WCID GENMASK(25, 16) - -#define MT_TXS3_PID GENMASK(31, 24) - static inline struct mt7921_txp_common * mt7921_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 3dfc2d593aa4..38a3ce1b8f9b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -247,16 +247,6 @@ struct mt7921_txpwr { } data[TXPWR_MAX_NUM]; };
-enum { - MT_LMAC_AC00, - MT_LMAC_AC01, - MT_LMAC_AC02, - MT_LMAC_AC03, - MT_LMAC_ALTX0 = 0x10, - MT_LMAC_BMC0, - MT_LMAC_BCN0, -}; - static inline struct mt7921_phy * mt7921_hw_phy(struct ieee80211_hw *hw) {
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 182071cdd594bc79f42899c85afa995c370ef82d ]
mac_write_txwi code is shared between connac2 devices (mt7915 and mt7921). Move it in connac module.
Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/mediatek/mt76/mt76_connac.h | 6 + .../wireless/mediatek/mt76/mt76_connac_mac.c | 284 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7915/mac.c | 251 +--------------- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +- .../wireless/mediatek/mt76/mt7915/mt7915.h | 1 - .../net/wireless/mediatek/mt76/mt7921/mac.c | 212 +------------ .../net/wireless/mediatek/mt76/mt7921/main.c | 2 +- .../net/wireless/mediatek/mt76/mt7921/mcu.c | 4 +- .../wireless/mediatek/mt76/mt7921/mt7921.h | 5 - .../wireless/mediatek/mt76/mt7921/pci_mac.c | 4 +- 10 files changed, 299 insertions(+), 472 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h index 400ba514460e..a9d7a269fcf3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h @@ -12,6 +12,8 @@ #define MT76_CONNAC_MAX_SCHED_SCAN_SSID 10 #define MT76_CONNAC_MAX_SCAN_MATCH 16
+#define MT76_CONNAC_MAX_WMM_SETS 4 + #define MT76_CONNAC_COREDUMP_TIMEOUT (HZ / 20) #define MT76_CONNAC_COREDUMP_SZ (1300 * 1024)
@@ -244,5 +246,9 @@ void mt76_connac_pm_queue_skb(struct ieee80211_hw *hw, struct sk_buff *skb); void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy, struct mt76_connac_pm *pm); +void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, + struct sk_buff *skb, struct mt76_wcid *wcid, + struct ieee80211_key_conf *key, int pid, + u32 changed);
#endif /* __MT76_CONNAC_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c index 306e9eaea917..0ea795565c88 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c @@ -2,6 +2,7 @@ /* Copyright (C) 2020 MediaTek Inc. */
#include "mt76_connac.h" +#include "mt76_connac2_mac.h"
int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm) { @@ -115,3 +116,286 @@ void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy, mt76_worker_schedule(&phy->dev->tx_worker); } EXPORT_SYMBOL_GPL(mt76_connac_pm_dequeue_skbs); + +static u16 +mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif, + bool beacon, bool mcast) +{ + u8 mode = 0, band = mphy->chandef.chan->band; + int rateidx = 0, mcast_rate; + + if (!vif) + goto legacy; + + if (is_mt7921(mphy->dev)) { + rateidx = ffs(vif->bss_conf.basic_rates) - 1; + goto legacy; + } + + if (beacon) { + struct cfg80211_bitrate_mask *mask; + + mask = &vif->bss_conf.beacon_tx_rate; + if (hweight16(mask->control[band].he_mcs[0]) == 1) { + rateidx = ffs(mask->control[band].he_mcs[0]) - 1; + mode = MT_PHY_TYPE_HE_SU; + goto out; + } else if (hweight16(mask->control[band].vht_mcs[0]) == 1) { + rateidx = ffs(mask->control[band].vht_mcs[0]) - 1; + mode = MT_PHY_TYPE_VHT; + goto out; + } else if (hweight8(mask->control[band].ht_mcs[0]) == 1) { + rateidx = ffs(mask->control[band].ht_mcs[0]) - 1; + mode = MT_PHY_TYPE_HT; + goto out; + } else if (hweight32(mask->control[band].legacy) == 1) { + rateidx = ffs(mask->control[band].legacy) - 1; + goto legacy; + } + } + + mcast_rate = vif->bss_conf.mcast_rate[band]; + if (mcast && mcast_rate > 0) + rateidx = mcast_rate - 1; + else + rateidx = ffs(vif->bss_conf.basic_rates) - 1; + +legacy: + rateidx = mt76_calculate_default_rate(mphy, rateidx); + mode = rateidx >> 8; + rateidx &= GENMASK(7, 0); + +out: + return FIELD_PREP(MT_TX_RATE_IDX, rateidx) | + FIELD_PREP(MT_TX_RATE_MODE, mode); +} + +static void +mt76_connac2_mac_write_txwi_8023(__le32 *txwi, struct sk_buff *skb, + struct mt76_wcid *wcid) +{ + u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; + u8 fc_type, fc_stype; + u16 ethertype; + bool wmm = false; + u32 val; + + if (wcid->sta) { + struct ieee80211_sta *sta; + + sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv); + wmm = sta->wme; + } + + val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) | + FIELD_PREP(MT_TXD1_TID, tid); + + ethertype = get_unaligned_be16(&skb->data[12]); + if (ethertype >= ETH_P_802_3_MIN) + val |= MT_TXD1_ETH_802_3; + + txwi[1] |= cpu_to_le32(val); + + fc_type = IEEE80211_FTYPE_DATA >> 2; + fc_stype = wmm ? IEEE80211_STYPE_QOS_DATA >> 4 : 0; + + val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) | + FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype); + + txwi[2] |= cpu_to_le32(val); + + val = FIELD_PREP(MT_TXD7_TYPE, fc_type) | + FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype); + + txwi[7] |= cpu_to_le32(val); +} + +static void +mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, + struct sk_buff *skb, + struct ieee80211_key_conf *key) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + bool multicast = is_multicast_ether_addr(hdr->addr1); + u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; + __le16 fc = hdr->frame_control; + u8 fc_type, fc_stype; + u32 val; + + if (ieee80211_is_action(fc) && + mgmt->u.action.category == WLAN_CATEGORY_BACK && + mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) { + u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); + + txwi[5] |= cpu_to_le32(MT_TXD5_ADD_BA); + tid = (capab >> 2) & IEEE80211_QOS_CTL_TID_MASK; + } else if (ieee80211_is_back_req(hdr->frame_control)) { + struct ieee80211_bar *bar = (struct ieee80211_bar *)hdr; + u16 control = le16_to_cpu(bar->control); + + tid = FIELD_GET(IEEE80211_BAR_CTRL_TID_INFO_MASK, control); + } + + val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_11) | + FIELD_PREP(MT_TXD1_HDR_INFO, + ieee80211_get_hdrlen_from_skb(skb) / 2) | + FIELD_PREP(MT_TXD1_TID, tid); + + txwi[1] |= cpu_to_le32(val); + + fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2; + fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4; + + val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) | + FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype) | + FIELD_PREP(MT_TXD2_MULTICAST, multicast); + + if (key && multicast && ieee80211_is_robust_mgmt_frame(skb) && + key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { + val |= MT_TXD2_BIP; + txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME); + } + + if (!ieee80211_is_data(fc) || multicast || + info->flags & IEEE80211_TX_CTL_USE_MINRATE) + val |= MT_TXD2_FIX_RATE; + + txwi[2] |= cpu_to_le32(val); + + if (ieee80211_is_beacon(fc)) { + txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT); + txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT); + if (!is_mt7921(dev)) + txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, + 0x18)); + } + + if (info->flags & IEEE80211_TX_CTL_INJECTED) { + u16 seqno = le16_to_cpu(hdr->seq_ctrl); + + if (ieee80211_is_back_req(hdr->frame_control)) { + struct ieee80211_bar *bar; + + bar = (struct ieee80211_bar *)skb->data; + seqno = le16_to_cpu(bar->start_seq_num); + } + + val = MT_TXD3_SN_VALID | + FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno)); + txwi[3] |= cpu_to_le32(val); + txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU); + } + + if (mt76_is_mmio(dev)) { + val = FIELD_PREP(MT_TXD7_TYPE, fc_type) | + FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype); + txwi[7] |= cpu_to_le32(val); + } else { + val = FIELD_PREP(MT_TXD8_L_TYPE, fc_type) | + FIELD_PREP(MT_TXD8_L_SUB_TYPE, fc_stype); + txwi[8] |= cpu_to_le32(val); + } +} + +void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, + struct sk_buff *skb, struct mt76_wcid *wcid, + struct ieee80211_key_conf *key, int pid, + u32 changed) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + bool ext_phy = info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY; + struct ieee80211_vif *vif = info->control.vif; + struct mt76_phy *mphy = &dev->phy; + u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0, band_idx = 0; + u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE; + bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; + bool beacon = !!(changed & (BSS_CHANGED_BEACON | + BSS_CHANGED_BEACON_ENABLED)); + bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | + BSS_CHANGED_FILS_DISCOVERY)); + + if (vif) { + struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + + omac_idx = mvif->omac_idx; + wmm_idx = mvif->wmm_idx; + band_idx = mvif->band_idx; + } + + if (ext_phy && dev->phy2) + mphy = dev->phy2; + + if (inband_disc) { + p_fmt = MT_TX_TYPE_FW; + q_idx = MT_LMAC_ALTX0; + } else if (beacon) { + p_fmt = MT_TX_TYPE_FW; + q_idx = MT_LMAC_BCN0; + } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; + q_idx = MT_LMAC_ALTX0; + } else { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; + q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS + + mt76_connac_lmac_mapping(skb_get_queue_mapping(skb)); + } + + val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) | + FIELD_PREP(MT_TXD0_PKT_FMT, p_fmt) | + FIELD_PREP(MT_TXD0_Q_IDX, q_idx); + txwi[0] = cpu_to_le32(val); + + val = MT_TXD1_LONG_FORMAT | + FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) | + FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx); + if (!is_mt7921(dev)) + val |= MT_TXD1_VTA; + if (ext_phy || band_idx) + val |= MT_TXD1_TGID; + + txwi[1] = cpu_to_le32(val); + txwi[2] = 0; + + val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, 15); + if (!is_mt7921(dev)) + val |= MT_TXD3_SW_POWER_MGMT; + if (key) + val |= MT_TXD3_PROTECT_FRAME; + if (info->flags & IEEE80211_TX_CTL_NO_ACK) + val |= MT_TXD3_NO_ACK; + + txwi[3] = cpu_to_le32(val); + txwi[4] = 0; + + val = FIELD_PREP(MT_TXD5_PID, pid); + if (pid >= MT_PACKET_ID_FIRST) + val |= MT_TXD5_TX_STATUS_HOST; + + txwi[5] = cpu_to_le32(val); + txwi[6] = 0; + txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0; + + if (is_8023) + mt76_connac2_mac_write_txwi_8023(txwi, skb, wcid); + else + mt76_connac2_mac_write_txwi_80211(dev, txwi, skb, key); + + if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) { + /* Fixed rata is available just for 802.11 txd */ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + bool multicast = is_multicast_ether_addr(hdr->addr1); + u16 rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon, + multicast); + u32 val = MT_TXD6_FIXED_BW; + + /* hardware won't add HTC for mgmt/ctrl frame */ + txwi[2] |= cpu_to_le32(MT_TXD2_HTC_VLD); + + val |= FIELD_PREP(MT_TXD6_TX_RATE, rate); + txwi[6] |= cpu_to_le32(val); + txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); + } +} +EXPORT_SYMBOL_GPL(mt76_connac2_mac_write_txwi); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index b8704018dcc0..89f10bf885ba 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -1009,265 +1009,18 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi, #endif }
-static void -mt7915_mac_write_txwi_8023(__le32 *txwi, struct sk_buff *skb, - struct mt76_wcid *wcid) -{ - - u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; - u8 fc_type, fc_stype; - u16 ethertype; - bool wmm = false; - u32 val; - - if (wcid->sta) { - struct ieee80211_sta *sta; - - sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv); - wmm = sta->wme; - } - - val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) | - FIELD_PREP(MT_TXD1_TID, tid); - - ethertype = get_unaligned_be16(&skb->data[12]); - if (ethertype >= ETH_P_802_3_MIN) - val |= MT_TXD1_ETH_802_3; - - txwi[1] |= cpu_to_le32(val); - - fc_type = IEEE80211_FTYPE_DATA >> 2; - fc_stype = wmm ? IEEE80211_STYPE_QOS_DATA >> 4 : 0; - - val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) | - FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype); - - txwi[2] |= cpu_to_le32(val); - - val = FIELD_PREP(MT_TXD7_TYPE, fc_type) | - FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype); - txwi[7] |= cpu_to_le32(val); -} - -static void -mt7915_mac_write_txwi_80211(__le32 *txwi, struct sk_buff *skb, - struct ieee80211_key_conf *key, bool *mcast) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; - __le16 fc = hdr->frame_control; - u8 fc_type, fc_stype; - u32 val; - - *mcast = is_multicast_ether_addr(hdr->addr1); - - if (ieee80211_is_action(fc) && - mgmt->u.action.category == WLAN_CATEGORY_BACK && - mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) { - u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); - - txwi[5] |= cpu_to_le32(MT_TXD5_ADD_BA); - tid = (capab >> 2) & IEEE80211_QOS_CTL_TID_MASK; - } else if (ieee80211_is_back_req(hdr->frame_control)) { - struct ieee80211_bar *bar = (struct ieee80211_bar *)hdr; - u16 control = le16_to_cpu(bar->control); - - tid = FIELD_GET(IEEE80211_BAR_CTRL_TID_INFO_MASK, control); - } - - val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_11) | - FIELD_PREP(MT_TXD1_HDR_INFO, - ieee80211_get_hdrlen_from_skb(skb) / 2) | - FIELD_PREP(MT_TXD1_TID, tid); - txwi[1] |= cpu_to_le32(val); - - fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2; - fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4; - - val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) | - FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype) | - FIELD_PREP(MT_TXD2_MULTICAST, *mcast); - - if (key && *mcast && ieee80211_is_robust_mgmt_frame(skb) && - key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { - val |= MT_TXD2_BIP; - txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME); - } - - if (!ieee80211_is_data(fc) || *mcast || - info->flags & IEEE80211_TX_CTL_USE_MINRATE) - val |= MT_TXD2_FIX_RATE; - - txwi[2] |= cpu_to_le32(val); - - if (ieee80211_is_beacon(fc)) { - txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT); - txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT); - txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, 0x18)); - } - - if (info->flags & IEEE80211_TX_CTL_INJECTED) { - u16 seqno = le16_to_cpu(hdr->seq_ctrl); - - if (ieee80211_is_back_req(hdr->frame_control)) { - struct ieee80211_bar *bar; - - bar = (struct ieee80211_bar *)skb->data; - seqno = le16_to_cpu(bar->start_seq_num); - } - - val = MT_TXD3_SN_VALID | - FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno)); - txwi[3] |= cpu_to_le32(val); - txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU); - } - - val = FIELD_PREP(MT_TXD7_TYPE, fc_type) | - FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype); - txwi[7] |= cpu_to_le32(val); -} - -static u16 -mt7915_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif, - bool beacon, bool mcast) -{ - u8 mode = 0, band = mphy->chandef.chan->band; - int rateidx = 0, mcast_rate; - - if (beacon) { - struct cfg80211_bitrate_mask *mask; - - mask = &vif->bss_conf.beacon_tx_rate; - if (hweight16(mask->control[band].he_mcs[0]) == 1) { - rateidx = ffs(mask->control[band].he_mcs[0]) - 1; - mode = MT_PHY_TYPE_HE_SU; - goto out; - } else if (hweight16(mask->control[band].vht_mcs[0]) == 1) { - rateidx = ffs(mask->control[band].vht_mcs[0]) - 1; - mode = MT_PHY_TYPE_VHT; - goto out; - } else if (hweight8(mask->control[band].ht_mcs[0]) == 1) { - rateidx = ffs(mask->control[band].ht_mcs[0]) - 1; - mode = MT_PHY_TYPE_HT; - goto out; - } else if (hweight32(mask->control[band].legacy) == 1) { - rateidx = ffs(mask->control[band].legacy) - 1; - goto legacy; - } - } - - mcast_rate = vif->bss_conf.mcast_rate[band]; - if (mcast && mcast_rate > 0) - rateidx = mcast_rate - 1; - else - rateidx = ffs(vif->bss_conf.basic_rates) - 1; - -legacy: - rateidx = mt76_calculate_default_rate(mphy, rateidx); - mode = rateidx >> 8; - rateidx &= GENMASK(7, 0); - -out: - return FIELD_PREP(MT_TX_RATE_IDX, rateidx) | - FIELD_PREP(MT_TX_RATE_MODE, mode); -} - void mt7915_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, int pid, struct ieee80211_key_conf *key, u32 changed) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_vif *vif = info->control.vif; struct mt76_phy *mphy = &dev->phy; - bool ext_phy = info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY; - u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0, band_idx = 0; - bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; - bool mcast = false; - u16 tx_count = 15; - u32 val; - bool beacon = !!(changed & (BSS_CHANGED_BEACON | - BSS_CHANGED_BEACON_ENABLED)); - bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | - BSS_CHANGED_FILS_DISCOVERY)); - - if (vif) { - struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
- omac_idx = mvif->mt76.omac_idx; - wmm_idx = mvif->mt76.wmm_idx; - band_idx = mvif->mt76.band_idx; - } - - if (ext_phy && dev->phy2) + if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && dev->phy2) mphy = dev->phy2;
- if (inband_disc) { - p_fmt = MT_TX_TYPE_FW; - q_idx = MT_LMAC_ALTX0; - } else if (beacon) { - p_fmt = MT_TX_TYPE_FW; - q_idx = MT_LMAC_BCN0; - } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) { - p_fmt = MT_TX_TYPE_CT; - q_idx = MT_LMAC_ALTX0; - } else { - p_fmt = MT_TX_TYPE_CT; - q_idx = wmm_idx * MT7915_MAX_WMM_SETS + - mt76_connac_lmac_mapping(skb_get_queue_mapping(skb)); - } - - val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + MT_TXD_SIZE) | - FIELD_PREP(MT_TXD0_PKT_FMT, p_fmt) | - FIELD_PREP(MT_TXD0_Q_IDX, q_idx); - txwi[0] = cpu_to_le32(val); - - val = MT_TXD1_LONG_FORMAT | MT_TXD1_VTA | - FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) | - FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx); - - if (ext_phy || band_idx) - val |= MT_TXD1_TGID; - - txwi[1] = cpu_to_le32(val); - - txwi[2] = 0; + mt76_connac2_mac_write_txwi(dev, txwi, skb, wcid, key, pid, changed);
- val = MT_TXD3_SW_POWER_MGMT | - FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count); - if (key) - val |= MT_TXD3_PROTECT_FRAME; - if (info->flags & IEEE80211_TX_CTL_NO_ACK) - val |= MT_TXD3_NO_ACK; - - txwi[3] = cpu_to_le32(val); - txwi[4] = 0; - - val = FIELD_PREP(MT_TXD5_PID, pid); - if (pid >= MT_PACKET_ID_FIRST) - val |= MT_TXD5_TX_STATUS_HOST; - txwi[5] = cpu_to_le32(val); - - txwi[6] = 0; - txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0; - - if (is_8023) - mt7915_mac_write_txwi_8023(txwi, skb, wcid); - else - mt7915_mac_write_txwi_80211(txwi, skb, key, &mcast); - - if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) { - u16 rate = mt7915_mac_tx_rate_val(mphy, vif, beacon, mcast); - - /* hardware won't add HTC for mgmt/ctrl frame */ - txwi[2] |= cpu_to_le32(MT_TXD2_HTC_VLD); - - val = MT_TXD6_FIXED_BW | - FIELD_PREP(MT_TXD6_TX_RATE, rate); - txwi[6] |= cpu_to_le32(val); - txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); - }
if (mt76_testmode_enabled(mphy)) mt7915_mac_write_txwi_tm(mphy->priv, txwi, skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 4ac45fd63662..17fa2acc0d07 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -2685,7 +2685,7 @@ int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif) struct edca *e = &req.edca[ac];
e->set = WMM_PARAM_SET; - e->queue = ac + mvif->mt76.wmm_idx * MT7915_MAX_WMM_SETS; + e->queue = ac + mvif->mt76.wmm_idx * MT76_CONNAC_MAX_WMM_SETS; e->aifs = q->aifs; e->txop = cpu_to_le16(q->txop);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 440a76021ad0..2c1248ca0ed0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -10,7 +10,6 @@ #include "regs.h"
#define MT7915_MAX_INTERFACES 19 -#define MT7915_MAX_WMM_SETS 4 #define MT7915_WTBL_SIZE 288 #define MT7916_WTBL_SIZE 544 #define MT7915_WTBL_RESERVED (mt7915_wtbl_size(dev) - 1) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index 2d4c81eec6dc..2a2ea7b9977a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -808,216 +808,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) return 0; }
-static void -mt7921_mac_write_txwi_8023(__le32 *txwi, struct sk_buff *skb, - struct mt76_wcid *wcid) -{ - u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; - u8 fc_type, fc_stype; - u16 ethertype; - bool wmm = false; - u32 val; - - if (wcid->sta) { - struct ieee80211_sta *sta; - - sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv); - wmm = sta->wme; - } - - val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) | - FIELD_PREP(MT_TXD1_TID, tid); - - ethertype = get_unaligned_be16(&skb->data[12]); - if (ethertype >= ETH_P_802_3_MIN) - val |= MT_TXD1_ETH_802_3; - - txwi[1] |= cpu_to_le32(val); - - fc_type = IEEE80211_FTYPE_DATA >> 2; - fc_stype = wmm ? IEEE80211_STYPE_QOS_DATA >> 4 : 0; - - val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) | - FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype); - - txwi[2] |= cpu_to_le32(val); - - val = FIELD_PREP(MT_TXD7_TYPE, fc_type) | - FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype); - txwi[7] |= cpu_to_le32(val); -} - -static void -mt7921_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, - struct sk_buff *skb, struct ieee80211_key_conf *key) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - bool multicast = is_multicast_ether_addr(hdr->addr1); - u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; - __le16 fc = hdr->frame_control; - u8 fc_type, fc_stype; - u32 val; - - if (ieee80211_is_action(fc) && - mgmt->u.action.category == WLAN_CATEGORY_BACK && - mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) { - u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); - - txwi[5] |= cpu_to_le32(MT_TXD5_ADD_BA); - tid = (capab >> 2) & IEEE80211_QOS_CTL_TID_MASK; - } else if (ieee80211_is_back_req(hdr->frame_control)) { - struct ieee80211_bar *bar = (struct ieee80211_bar *)hdr; - u16 control = le16_to_cpu(bar->control); - - tid = FIELD_GET(IEEE80211_BAR_CTRL_TID_INFO_MASK, control); - } - - val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_11) | - FIELD_PREP(MT_TXD1_HDR_INFO, - ieee80211_get_hdrlen_from_skb(skb) / 2) | - FIELD_PREP(MT_TXD1_TID, tid); - txwi[1] |= cpu_to_le32(val); - - fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2; - fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4; - - val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) | - FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype) | - FIELD_PREP(MT_TXD2_MULTICAST, multicast); - - if (key && multicast && ieee80211_is_robust_mgmt_frame(skb) && - key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { - val |= MT_TXD2_BIP; - txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME); - } - - if (!ieee80211_is_data(fc) || multicast || - info->flags & IEEE80211_TX_CTL_USE_MINRATE) - val |= MT_TXD2_FIX_RATE; - - txwi[2] |= cpu_to_le32(val); - - if (ieee80211_is_beacon(fc)) { - txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT); - txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT); - } - - if (info->flags & IEEE80211_TX_CTL_INJECTED) { - u16 seqno = le16_to_cpu(hdr->seq_ctrl); - - if (ieee80211_is_back_req(hdr->frame_control)) { - struct ieee80211_bar *bar; - - bar = (struct ieee80211_bar *)skb->data; - seqno = le16_to_cpu(bar->start_seq_num); - } - - val = MT_TXD3_SN_VALID | - FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno)); - txwi[3] |= cpu_to_le32(val); - txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU); - } - - if (mt76_is_mmio(dev)) { - val = FIELD_PREP(MT_TXD7_TYPE, fc_type) | - FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype); - txwi[7] |= cpu_to_le32(val); - } else { - val = FIELD_PREP(MT_TXD8_L_TYPE, fc_type) | - FIELD_PREP(MT_TXD8_L_SUB_TYPE, fc_stype); - txwi[8] |= cpu_to_le32(val); - } -} - -void mt7921_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, - struct sk_buff *skb, struct mt76_wcid *wcid, - struct ieee80211_key_conf *key, int pid, - bool beacon) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_vif *vif = info->control.vif; - struct mt76_phy *mphy = &dev->phy; - u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0; - u32 sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE; - bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; - u16 tx_count = 15; - u32 val; - - if (vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; - - omac_idx = mvif->omac_idx; - wmm_idx = mvif->wmm_idx; - } - - if (beacon) { - p_fmt = MT_TX_TYPE_FW; - q_idx = MT_LMAC_BCN0; - } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) { - p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; - q_idx = MT_LMAC_ALTX0; - } else { - p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; - q_idx = wmm_idx * MT7921_MAX_WMM_SETS + - mt76_connac_lmac_mapping(skb_get_queue_mapping(skb)); - } - - val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) | - FIELD_PREP(MT_TXD0_PKT_FMT, p_fmt) | - FIELD_PREP(MT_TXD0_Q_IDX, q_idx); - txwi[0] = cpu_to_le32(val); - - val = MT_TXD1_LONG_FORMAT | - FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) | - FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx); - - txwi[1] = cpu_to_le32(val); - txwi[2] = 0; - - val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count); - if (key) - val |= MT_TXD3_PROTECT_FRAME; - if (info->flags & IEEE80211_TX_CTL_NO_ACK) - val |= MT_TXD3_NO_ACK; - - txwi[3] = cpu_to_le32(val); - txwi[4] = 0; - - val = FIELD_PREP(MT_TXD5_PID, pid); - if (pid >= MT_PACKET_ID_FIRST) - val |= MT_TXD5_TX_STATUS_HOST; - txwi[5] = cpu_to_le32(val); - - txwi[6] = 0; - txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0; - - if (is_8023) - mt7921_mac_write_txwi_8023(txwi, skb, wcid); - else - mt7921_mac_write_txwi_80211(dev, txwi, skb, key); - - if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) { - int rateidx = vif ? ffs(vif->bss_conf.basic_rates) - 1 : 0; - u16 rate, mode; - - /* hardware won't add HTC for mgmt/ctrl frame */ - txwi[2] |= cpu_to_le32(MT_TXD2_HTC_VLD); - - rate = mt76_calculate_default_rate(mphy, rateidx); - mode = rate >> 8; - rate &= GENMASK(7, 0); - rate |= FIELD_PREP(MT_TX_RATE_MODE, mode); - - val = MT_TXD6_FIXED_BW | - FIELD_PREP(MT_TXD6_TX_RATE, rate); - txwi[6] |= cpu_to_le32(val); - txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); - } -} -EXPORT_SYMBOL_GPL(mt7921_mac_write_txwi); - void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) { struct mt7921_sta *msta; @@ -1645,7 +1435,7 @@ mt7921_usb_sdio_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid, __le32 *txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE);
memset(txwi, 0, MT_SDIO_TXD_SIZE); - mt7921_mac_write_txwi(&dev->mt76, txwi, skb, wcid, key, pid, false); + mt76_connac2_mac_write_txwi(&dev->mt76, txwi, skb, wcid, key, pid, 0); skb_push(skb, MT_SDIO_TXD_SIZE); }
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index 80279f342109..e86fe9ee4623 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -322,7 +322,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw, mvif->mt76.omac_idx = mvif->mt76.idx; mvif->phy = phy; mvif->mt76.band_idx = 0; - mvif->mt76.wmm_idx = mvif->mt76.idx % MT7921_MAX_WMM_SETS; + mvif->mt76.wmm_idx = mvif->mt76.idx % MT76_CONNAC_MAX_WMM_SETS;
ret = mt76_connac_mcu_uni_add_dev(&dev->mphy, vif, &mvif->sta.wcid, true); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 6ccd469eb3e4..613a94be8ea4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -1272,8 +1272,8 @@ mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, return -EINVAL; }
- mt7921_mac_write_txwi(&dev->mt76, (__le32 *)(req.beacon_tlv.pkt), skb, - wcid, NULL, 0, true); + mt76_connac2_mac_write_txwi(&dev->mt76, (__le32 *)(req.beacon_tlv.pkt), + skb, wcid, NULL, 0, BSS_CHANGED_BEACON); memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len); req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len); req.beacon_tlv.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 38a3ce1b8f9b..66054123bcc4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -10,7 +10,6 @@ #include "regs.h"
#define MT7921_MAX_INTERFACES 4 -#define MT7921_MAX_WMM_SETS 4 #define MT7921_WTBL_SIZE 20 #define MT7921_WTBL_RESERVED (MT7921_WTBL_SIZE - 1) #define MT7921_WTBL_STA (MT7921_WTBL_RESERVED - \ @@ -414,10 +413,6 @@ int mt7921_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void *data, int len); int mt7921_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, struct netlink_callback *cb, void *data, int len); -void mt7921_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, - struct sk_buff *skb, struct mt76_wcid *wcid, - struct ieee80211_key_conf *key, int pid, - bool beacon); void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi); void mt7921_mac_sta_poll(struct mt7921_dev *dev); int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb, diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c index f261cbfae2f3..b0f58bcf70cb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c @@ -72,8 +72,8 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, }
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); - mt7921_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, key, - pid, false); + mt76_connac2_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, key, + pid, 0);
txp = (struct mt7921_txp_common *)(txwi + MT_TXD_SIZE); memset(txp, 0, sizeof(struct mt7921_txp_common));
From: Shayne Chen shayne.chen@mediatek.com
[ Upstream commit 6e744cfeee02c2d8676eb55d5b3720808812f41f ]
Fix the issue that the measured inter packet gap didn't fit its setting value.
Fixes: c2d3b1926f30 ("mt76: mt7915: add support for ipg in testmode") Signed-off-by: Shayne Chen shayne.chen@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/testmode.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c index 20f63644e929..0f5c1e5bffe1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c @@ -168,13 +168,14 @@ mt7915_tm_set_tam_arb(struct mt7915_phy *phy, bool enable, bool mu) }
static int -mt7915_tm_set_wmm_qid(struct mt7915_dev *dev, u8 qid, u8 aifs, u8 cw_min, +mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min, u16 cw_max, u16 txop) { + struct mt7915_vif *mvif = (struct mt7915_vif *)phy->monitor_vif->drv_priv; struct mt7915_mcu_tx req = { .total = 1 }; struct edca *e = &req.edca[0];
- e->queue = qid; + e->queue = qid + mvif->mt76.wmm_idx * MT76_CONNAC_MAX_WMM_SETS; e->set = WMM_PARAM_SET;
e->aifs = aifs; @@ -182,7 +183,7 @@ mt7915_tm_set_wmm_qid(struct mt7915_dev *dev, u8 qid, u8 aifs, u8 cw_min, e->cw_max = cpu_to_le16(cw_max); e->txop = cpu_to_le16(txop);
- return mt7915_mcu_update_edca(dev, &req); + return mt7915_mcu_update_edca(phy->dev, &req); }
static int @@ -244,7 +245,7 @@ mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode)
mt7915_tm_set_slot_time(phy, slot_time, sifs);
- return mt7915_tm_set_wmm_qid(dev, + return mt7915_tm_set_wmm_qid(phy, mt76_connac_lmac_mapping(IEEE80211_AC_BE), aifsn, cw, cw, 0); }
From: Felix Fietkau nbd@nbd.name
[ Upstream commit aac86cebb4a09e3fa2c07589f79f7d0e07e8c9a4 ]
For some reason, mt7615 reacts badly to repeatedly enabling/disabling the radar detector without also switching the channel. This results in very bad throughput on DFS channels, because hw->conf.radar_enabled can get toggled a few times after CAC ends. Fix this by always leaving the DFS detector enabled on DFS channels and instead suppress unwanted detection events.
Fixes: 2c86f6752046 ("mt76: mt7615: fix/rewrite the dfs state handling logic") Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/mediatek/mt76/mt7615/mac.c | 7 ++++--- .../net/wireless/mediatek/mt76/mt7615/main.c | 21 ------------------- .../net/wireless/mediatek/mt76/mt7615/mcu.c | 3 +++ .../wireless/mediatek/mt76/mt7615/mt7615.h | 1 - 4 files changed, 7 insertions(+), 25 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index bd687f7de628..9e832b27170f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -2282,6 +2282,7 @@ mt7615_dfs_init_radar_specs(struct mt7615_phy *phy)
int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy) { + struct cfg80211_chan_def *chandef = &phy->mt76->chandef; struct mt7615_dev *dev = phy->dev; bool ext_phy = phy != &dev->phy; enum mt76_dfs_state dfs_state, prev_state; @@ -2292,13 +2293,13 @@ int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy)
prev_state = phy->mt76->dfs_state; dfs_state = mt76_phy_dfs_state(phy->mt76); + if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) && + dfs_state < MT_DFS_STATE_CAC) + dfs_state = MT_DFS_STATE_ACTIVE;
if (prev_state == dfs_state) return 0;
- if (prev_state == MT_DFS_STATE_UNKNOWN) - mt7615_dfs_stop_radar_detector(phy); - if (dfs_state == MT_DFS_STATE_DISABLED) goto stop;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index a9c9b97d173e..d722c3c177be 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -282,26 +282,6 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw, mt76_packet_id_flush(&dev->mt76, &mvif->sta.wcid); }
-static void mt7615_init_dfs_state(struct mt7615_phy *phy) -{ - struct mt76_phy *mphy = phy->mt76; - struct ieee80211_hw *hw = mphy->hw; - struct cfg80211_chan_def *chandef = &hw->conf.chandef; - - if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) - return; - - if (!(chandef->chan->flags & IEEE80211_CHAN_RADAR) && - !(mphy->chandef.chan->flags & IEEE80211_CHAN_RADAR)) - return; - - if (mphy->chandef.chan->center_freq == chandef->chan->center_freq && - mphy->chandef.width == chandef->width) - return; - - phy->dfs_state = -1; -} - int mt7615_set_channel(struct mt7615_phy *phy) { struct mt7615_dev *dev = phy->dev; @@ -314,7 +294,6 @@ int mt7615_set_channel(struct mt7615_phy *phy)
set_bit(MT76_RESET, &phy->mt76->state);
- mt7615_init_dfs_state(phy); mt76_set_channel(phy->mt76);
if (is_mt7615(&dev->mt76) && dev->flash_eeprom) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index d2dd1260382c..8a7bc78da954 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -403,6 +403,9 @@ mt7615_mcu_rx_radar_detected(struct mt7615_dev *dev, struct sk_buff *skb) if (r->band_idx && dev->mt76.phy2) mphy = dev->mt76.phy2;
+ if (mt76_phy_dfs_state(mphy) < MT_DFS_STATE_CAC) + return; + ieee80211_radar_detected(mphy->hw); dev->hw_pattern++; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h index 2e91f6a27d0f..082c73b571ae 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h @@ -177,7 +177,6 @@ struct mt7615_phy {
u8 chfreq; u8 rdd_state; - int dfs_state;
u32 rx_ampdu_ts; u32 ampdu_ref;
From: Liang He windhl@126.com
[ Upstream commit 0a14c1d0113f121151edf34333cdf212dd209190 ]
We should use of_node_put() for the reference 'np' returned by of_get_child_by_name() which will increase the refcount.
Fixes: 17f1de56df05 ("mt76: add common code shared between multiple chipsets") Signed-off-by: Liang He windhl@126.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mac80211.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 5f75a8945a6e..a520f9ac2799 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -210,6 +210,7 @@ static int mt76_led_init(struct mt76_dev *dev) if (!of_property_read_u32(np, "led-sources", &led_pin)) dev->led_pin = led_pin; dev->led_al = of_property_read_bool(np, "led-active-low"); + of_node_put(np); }
return led_classdev_register(dev->dev, &dev->led_cdev);
From: Liang He windhl@126.com
[ Upstream commit 3bd53ea02d77917c2314ec7be9e2d05be22f87d3 ]
We should use of_node_put() for the reference 'np' returned by of_get_child_by_name() which will increase the refcount.
Fixes: 22b980badc0f ("mt76: add functions for parsing rate power limits from DT") Signed-off-by: Liang He windhl@126.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/eeprom.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c index a499861918fa..9bc8758573fc 100644 --- a/drivers/net/wireless/mediatek/mt76/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c @@ -162,10 +162,13 @@ mt76_find_power_limits_node(struct mt76_dev *dev) }
if (mt76_string_prop_find(country, dev->alpha2) || - mt76_string_prop_find(regd, region_name)) + mt76_string_prop_find(regd, region_name)) { + of_node_put(np); return cur; + } }
+ of_node_put(np); return fallback; }
From: Liu Jian liujian56@huawei.com
[ Upstream commit 9974d37ea75f01b47d16072b5dad305bd8d23fcc ]
In sk_psock_skb_ingress_enqueue function, if the linear area + nr_frags + frag_list of the SKB has NR_MSG_FRAG_IDS blocks in total, skb_to_sgvec will return NR_MSG_FRAG_IDS, then msg->sg.end will be set to NR_MSG_FRAG_IDS, and in addition, (NR_MSG_FRAG_IDS - 1) is set to the last SG of msg. Recv the msg in sk_msg_recvmsg, when i is (NR_MSG_FRAG_IDS - 1), the sk_msg_iter_var_next(i) will change i to 0 (not NR_MSG_FRAG_IDS), the judgment condition "msg_rx->sg.start==msg_rx->sg.end" and "i != msg_rx->sg.end" can not work.
As a result, the processed msg cannot be deleted from ingress_msg list. But the length of all the sge of the msg has changed to 0. Then the next recvmsg syscall will process the msg repeatedly, because the length of sge is 0, the -EFAULT error is always returned.
Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface") Signed-off-by: Liu Jian liujian56@huawei.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: John Fastabend john.fastabend@gmail.com Link: https://lore.kernel.org/bpf/20220628123616.186950-1-liujian56@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/skmsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/core/skmsg.c b/net/core/skmsg.c index b0fcd0200e84..a8dbea559c7f 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -462,7 +462,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
if (copied == len) break; - } while (i != msg_rx->sg.end); + } while (!sg_is_last(sge));
if (unlikely(peek)) { msg_rx = sk_psock_next_msg(psock, msg_rx); @@ -472,7 +472,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, }
msg_rx->sg.start = i; - if (!sge->length && msg_rx->sg.start == msg_rx->sg.end) { + if (!sge->length && sg_is_last(sge)) { msg_rx = sk_psock_dequeue_msg(psock); kfree_sk_msg(msg_rx); }
From: Jian Zhang zhangjian210@huawei.com
[ Upstream commit 48b927770f8ad3f8cf4a024a552abf272af9f592 ]
In exynos7_decon_resume, When it fails, we must use clk_disable_unprepare() to free resource that have been used.
Fixes: 6f83d20838c09 ("drm/exynos: use DRM_DEV_ERROR to print out error message") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Jian Zhang zhangjian210@huawei.com Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/exynos/exynos7_drm_decon.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index c04264f70ad1..3c31405600f0 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -800,31 +800,40 @@ static int exynos7_decon_resume(struct device *dev) if (ret < 0) { DRM_DEV_ERROR(dev, "Failed to prepare_enable the pclk [%d]\n", ret); - return ret; + goto err_pclk_enable; }
ret = clk_prepare_enable(ctx->aclk); if (ret < 0) { DRM_DEV_ERROR(dev, "Failed to prepare_enable the aclk [%d]\n", ret); - return ret; + goto err_aclk_enable; }
ret = clk_prepare_enable(ctx->eclk); if (ret < 0) { DRM_DEV_ERROR(dev, "Failed to prepare_enable the eclk [%d]\n", ret); - return ret; + goto err_eclk_enable; }
ret = clk_prepare_enable(ctx->vclk); if (ret < 0) { DRM_DEV_ERROR(dev, "Failed to prepare_enable the vclk [%d]\n", ret); - return ret; + goto err_vclk_enable; }
return 0; + +err_vclk_enable: + clk_disable_unprepare(ctx->eclk); +err_eclk_enable: + clk_disable_unprepare(ctx->aclk); +err_aclk_enable: + clk_disable_unprepare(ctx->pclk); +err_pclk_enable: + return ret; } #endif
From: Tony Ambardar tony.ambardar@gmail.com
[ Upstream commit 95acd8817e66d031d2e6ee7def3f1e1874819317 ]
The BPF core/verifier is hard-coded to permit mixing bpf2bpf and tail calls for only x86-64. Change the logic to instead rely on a new weak function 'bool bpf_jit_supports_subprog_tailcalls(void)', which a capable JIT backend can override.
Update the x86-64 eBPF JIT to reflect this.
Signed-off-by: Tony Ambardar Tony.Ambardar@gmail.com [jakub: drop MIPS bits and tweak patch subject] Signed-off-by: Jakub Sitnicki jakub@cloudflare.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20220617105735.733938-2-jakub@cloudflare.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/net/bpf_jit_comp.c | 6 ++++++ include/linux/filter.h | 1 + kernel/bpf/core.c | 6 ++++++ kernel/bpf/verifier.c | 3 ++- 4 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index b808c9a80d1b..eba704b9ce1e 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -2506,3 +2506,9 @@ void *bpf_arch_text_copy(void *dst, void *src, size_t len) return ERR_PTR(-EINVAL); return dst; } + +/* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */ +bool bpf_jit_supports_subprog_tailcalls(void) +{ + return true; +} diff --git a/include/linux/filter.h b/include/linux/filter.h index ed0c0ff42ad5..d9a0db845b50 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -948,6 +948,7 @@ u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog); void bpf_jit_compile(struct bpf_prog *prog); bool bpf_jit_needs_zext(void); +bool bpf_jit_supports_subprog_tailcalls(void); bool bpf_jit_supports_kfunc_call(void); bool bpf_helper_changes_pkt_data(void *func);
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index e7961508a47d..6e3fe4b7230b 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -2716,6 +2716,12 @@ bool __weak bpf_jit_needs_zext(void) return false; }
+/* Return TRUE if the JIT backend supports mixing bpf2bpf and tailcalls. */ +bool __weak bpf_jit_supports_subprog_tailcalls(void) +{ + return false; +} + bool __weak bpf_jit_supports_kfunc_call(void) { return false; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 0efbac0fd126..602366bc230f 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -6143,7 +6143,8 @@ static bool may_update_sockmap(struct bpf_verifier_env *env, int func_id)
static bool allow_tail_call_in_subprogs(struct bpf_verifier_env *env) { - return env->prog->jit_requested && IS_ENABLED(CONFIG_X86_64); + return env->prog->jit_requested && + bpf_jit_supports_subprog_tailcalls(); }
static int check_map_func_compatibility(struct bpf_verifier_env *env,
From: Song Liu song@kernel.org
[ Upstream commit 1d5f82d9dd477d5c66e0214a68c3e4f308eadd6d ]
syzbot reported a few issues with bpf_prog_pack [1], [2]. This only happens with multiple subprogs. In jit_subprogs(), we first call bpf_int_jit_compile() on each sub program. And then, we call it on each sub program again. jit_data is not freed in the first call of bpf_int_jit_compile(). Similarly we don't call bpf_jit_binary_pack_finalize() in the first call of bpf_int_jit_compile().
If bpf_int_jit_compile() failed for one sub program, we will call bpf_jit_binary_pack_finalize() for this sub program. However, we don't have a chance to call it for other sub programs. Then we will hit "goto out_free" in jit_subprogs(), and call bpf_jit_free on some subprograms that haven't got bpf_jit_binary_pack_finalize() yet.
At this point, bpf_jit_binary_pack_free() is called and the whole 2MB page is freed erroneously.
Fix this with a custom bpf_jit_free() for x86_64, which calls bpf_jit_binary_pack_finalize() if necessary. Also, with custom bpf_jit_free(), bpf_prog_aux->use_bpf_prog_pack is not needed any more, remove it.
Fixes: 1022a5498f6f ("bpf, x86_64: Use bpf_jit_binary_pack_alloc") [1] https://syzkaller.appspot.com/bug?extid=2f649ec6d2eea1495a8f [2] https://syzkaller.appspot.com/bug?extid=87f65c75f4a72db05445 Reported-by: syzbot+2f649ec6d2eea1495a8f@syzkaller.appspotmail.com Reported-by: syzbot+87f65c75f4a72db05445@syzkaller.appspotmail.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20220706002612.4013790-1-song@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/net/bpf_jit_comp.c | 25 +++++++++++++++++++++++++ include/linux/bpf.h | 1 - include/linux/filter.h | 8 ++++++++ kernel/bpf/core.c | 29 ++++++++++++----------------- 4 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index eba704b9ce1e..41d170653e8d 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -2512,3 +2512,28 @@ bool bpf_jit_supports_subprog_tailcalls(void) { return true; } + +void bpf_jit_free(struct bpf_prog *prog) +{ + if (prog->jited) { + struct x64_jit_data *jit_data = prog->aux->jit_data; + struct bpf_binary_header *hdr; + + /* + * If we fail the final pass of JIT (from jit_subprogs), + * the program may not be finalized yet. Call finalize here + * before freeing it. + */ + if (jit_data) { + bpf_jit_binary_pack_finalize(prog, jit_data->header, + jit_data->rw_header); + kvfree(jit_data->addrs); + kfree(jit_data); + } + hdr = bpf_jit_binary_pack_hdr(prog); + bpf_jit_binary_pack_free(hdr, NULL); + WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(prog)); + } + + bpf_prog_unlock_free(prog); +} diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 2b914a56a2c5..7424cf234ae0 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1025,7 +1025,6 @@ struct bpf_prog_aux { bool sleepable; bool tail_call_reachable; bool xdp_has_frags; - bool use_bpf_prog_pack; /* BTF_KIND_FUNC_PROTO for valid attach_btf_id */ const struct btf_type *attach_func_proto; /* function name for valid attach_btf_id */ diff --git a/include/linux/filter.h b/include/linux/filter.h index d9a0db845b50..8fd2e2f58eeb 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -1061,6 +1061,14 @@ u64 bpf_jit_alloc_exec_limit(void); void *bpf_jit_alloc_exec(unsigned long size); void bpf_jit_free_exec(void *addr); void bpf_jit_free(struct bpf_prog *fp); +struct bpf_binary_header * +bpf_jit_binary_pack_hdr(const struct bpf_prog *fp); + +static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp) +{ + return list_empty(&fp->aux->ksym.lnode) || + fp->aux->ksym.lnode.prev == LIST_POISON2; +}
struct bpf_binary_header * bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **ro_image, diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 6e3fe4b7230b..fb6bd57228a8 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -649,12 +649,6 @@ static bool bpf_prog_kallsyms_candidate(const struct bpf_prog *fp) return fp->jited && !bpf_prog_was_classic(fp); }
-static bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp) -{ - return list_empty(&fp->aux->ksym.lnode) || - fp->aux->ksym.lnode.prev == LIST_POISON2; -} - void bpf_prog_kallsyms_add(struct bpf_prog *fp) { if (!bpf_prog_kallsyms_candidate(fp) || @@ -1152,7 +1146,6 @@ int bpf_jit_binary_pack_finalize(struct bpf_prog *prog, bpf_prog_pack_free(ro_header); return PTR_ERR(ptr); } - prog->aux->use_bpf_prog_pack = true; return 0; }
@@ -1176,17 +1169,23 @@ void bpf_jit_binary_pack_free(struct bpf_binary_header *ro_header, bpf_jit_uncharge_modmem(size); }
+struct bpf_binary_header * +bpf_jit_binary_pack_hdr(const struct bpf_prog *fp) +{ + unsigned long real_start = (unsigned long)fp->bpf_func; + unsigned long addr; + + addr = real_start & BPF_PROG_CHUNK_MASK; + return (void *)addr; +} + static inline struct bpf_binary_header * bpf_jit_binary_hdr(const struct bpf_prog *fp) { unsigned long real_start = (unsigned long)fp->bpf_func; unsigned long addr;
- if (fp->aux->use_bpf_prog_pack) - addr = real_start & BPF_PROG_CHUNK_MASK; - else - addr = real_start & PAGE_MASK; - + addr = real_start & PAGE_MASK; return (void *)addr; }
@@ -1199,11 +1198,7 @@ void __weak bpf_jit_free(struct bpf_prog *fp) if (fp->jited) { struct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);
- if (fp->aux->use_bpf_prog_pack) - bpf_jit_binary_pack_free(hdr, NULL /* rw_buffer */); - else - bpf_jit_binary_free(hdr); - + bpf_jit_binary_free(hdr); WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp)); }
From: Yonglong Li liyonglong@chinatelecom.cn
[ Upstream commit 536a6c8e05f95e3d1118c40ae8b3022ee2d05d52 ]
current code of __tcp_retransmit_skb only check TCP_SKB_CB(skb)->seq in send window, and TCP_SKB_CB(skb)->seq_end maybe out of send window. If receiver has shrunk his window, and skb is out of new window, it should retransmit a smaller portion of the payload.
test packetdrill script: 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) +0 > S 0:0(0) win 65535 <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8> +.05 < S. 0:0(0) ack 1 win 6000 <mss 1000,nop,nop,sackOK> +0 > . 1:1(0) ack 1
+0 write(3, ..., 10000) = 10000
+0 > . 1:2001(2000) ack 1 win 65535 +0 > . 2001:4001(2000) ack 1 win 65535 +0 > . 4001:6001(2000) ack 1 win 65535
+.05 < . 1:1(0) ack 4001 win 1001
and tcpdump show: 192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 1:2001, ack 1, win 65535, length 2000 192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 2001:4001, ack 1, win 65535, length 2000 192.168.226.67.55 > 192.0.2.1.8080: Flags [P.], seq 4001:5001, ack 1, win 65535, length 1000 192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 5001:6001, ack 1, win 65535, length 1000 192.0.2.1.8080 > 192.168.226.67.55: Flags [.], ack 4001, win 1001, length 0 192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 5001:6001, ack 1, win 65535, length 1000 192.168.226.67.55 > 192.0.2.1.8080: Flags [P.], seq 4001:5001, ack 1, win 65535, length 1000
when cient retract window to 1001, send window is [4001,5002], but TLP send 5001-6001 packet which is out of send window.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Yonglong Li liyonglong@chinatelecom.cn Signed-off-by: Eric Dumazet edumazet@google.com Link: https://lore.kernel.org/r/1657532838-20200-1-git-send-email-liyonglong@china... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp_output.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 4c376b6d8764..ec9a4f621703 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3142,7 +3142,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) struct tcp_sock *tp = tcp_sk(sk); unsigned int cur_mss; int diff, len, err; - + int avail_wnd;
/* Inconclusive MTU probe */ if (icsk->icsk_mtup.probe_size) @@ -3164,17 +3164,25 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) return -EHOSTUNREACH; /* Routing failure or similar. */
cur_mss = tcp_current_mss(sk); + avail_wnd = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
/* If receiver has shrunk his window, and skb is out of * new window, do not retransmit it. The exception is the * case, when window is shrunk to zero. In this case - * our retransmit serves as a zero window probe. + * our retransmit of one segment serves as a zero window probe. */ - if (!before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp)) && - TCP_SKB_CB(skb)->seq != tp->snd_una) - return -EAGAIN; + if (avail_wnd <= 0) { + if (TCP_SKB_CB(skb)->seq != tp->snd_una) + return -EAGAIN; + avail_wnd = cur_mss; + }
len = cur_mss * segs; + if (len > avail_wnd) { + len = rounddown(avail_wnd, cur_mss); + if (!len) + len = avail_wnd; + } if (skb->len > len) { if (tcp_fragment(sk, TCP_FRAG_IN_RTX_QUEUE, skb, len, cur_mss, GFP_ATOMIC)) @@ -3188,8 +3196,9 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) diff -= tcp_skb_pcount(skb); if (diff) tcp_adjust_pcount(sk, skb, diff); - if (skb->len < cur_mss) - tcp_retrans_try_collapse(sk, skb, cur_mss); + avail_wnd = min_t(int, avail_wnd, cur_mss); + if (skb->len < avail_wnd) + tcp_retrans_try_collapse(sk, skb, avail_wnd); }
/* RFC3168, section 6.1.1.1. ECN fallback */
From: Anquan Wu leiqi96@hotmail.com
[ Upstream commit bf3f00378524adae16628cbadbd11ba7211863bb ]
BPF map name is limited to BPF_OBJ_NAME_LEN. A map name is defined as being longer than BPF_OBJ_NAME_LEN, it will be truncated to BPF_OBJ_NAME_LEN when a userspace program calls libbpf to create the map. A pinned map also generates a path in the /sys. If the previous program wanted to reuse the map, it can not get bpf_map by name, because the name of the map is only partially the same as the name which get from pinned path.
The syscall information below show that map name "process_pinned_map" is truncated to "process_pinned_".
bpf(BPF_OBJ_GET, {pathname="/sys/fs/bpf/process_pinned_map", bpf_fd=0, file_flags=0}, 144) = -1 ENOENT (No such file or directory)
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_HASH, key_size=4, value_size=4,max_entries=1024, map_flags=0, inner_map_fd=0, map_name="process_pinned_",map_ifindex=0, btf_fd=3, btf_key_type_id=6, btf_value_type_id=10,btf_vmlinux_value_type_id=0}, 72) = 4
This patch check that if the name of pinned map are the same as the actual name for the first (BPF_OBJ_NAME_LEN - 1), bpf map still uses the name which is included in bpf object.
Fixes: 26736eb9a483 ("tools: libbpf: allow map reuse") Signed-off-by: Anquan Wu leiqi96@hotmail.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/OSZP286MB1725CEA1C95C5CB8E7CCC53FB8869@OSZP286MB... Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index b9245bf688fa..5b9b42ab7aa0 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -4327,7 +4327,7 @@ int bpf_map__set_autocreate(struct bpf_map *map, bool autocreate) int bpf_map__reuse_fd(struct bpf_map *map, int fd) { struct bpf_map_info info = {}; - __u32 len = sizeof(info); + __u32 len = sizeof(info), name_len; int new_fd, err; char *new_name;
@@ -4337,7 +4337,12 @@ int bpf_map__reuse_fd(struct bpf_map *map, int fd) if (err) return libbpf_err(err);
- new_name = strdup(info.name); + name_len = strlen(info.name); + if (name_len == BPF_OBJ_NAME_LEN - 1 && strncmp(map->name, info.name, name_len) == 0) + new_name = strdup(map->name); + else + new_name = strdup(info.name); + if (!new_name) return libbpf_err(-errno);
From: David Gow davidgow@google.com
[ Upstream commit 94681e289bf5d10c9db9db143d1a22d8717205c5 ]
It's possible that memory allocation for 'filtered' will fail, but for the copy of the suite to succeed. In this case, the copy could be leaked.
Properly free 'copy' in the error case for the allocation of 'filtered' failing.
Note that there may also have been a similar issue in kunit_filter_subsuites, before it was removed in "kunit: flatten kunit_suite*** to kunit_suite** in .kunit_test_suites".
This was reported by clang-analyzer via the kernel test robot, here: https://lore.kernel.org/all/c8073b8e-7b9e-0830-4177-87c12f16349c@intel.com/
And by smatch via Dan Carpenter and the kernel test robot: https://lore.kernel.org/all/202207101328.ASjx88yj-lkp@intel.com/
Fixes: a02353f49162 ("kunit: bail out of test filtering logic quicker if OOM") Reported-by: kernel test robot yujie.liu@intel.com Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Daniel Latypov dlatypov@google.com Reviewed-by: Brendan Higgins brendanhiggins@google.com Signed-off-by: David Gow davidgow@google.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/kunit/executor.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c index 96f96e42ce06..16fb88c0aca3 100644 --- a/lib/kunit/executor.c +++ b/lib/kunit/executor.c @@ -76,8 +76,10 @@ kunit_filter_tests(struct kunit_suite *const suite, const char *test_glob) memcpy(copy, suite, sizeof(*copy));
filtered = kcalloc(n + 1, sizeof(*filtered), GFP_KERNEL); - if (!filtered) + if (!filtered) { + kfree(copy); return ERR_PTR(-ENOMEM); + }
n = 0; kunit_suite_for_each_test_case(suite, test_case) {
From: Wolfram Sang wsa+renesas@sang-engineering.com
[ Upstream commit 9a162977d20436be5678a8e21a8e58eb4616d86a ]
Toolchains with an include file 'sys/timex.h' based on 3.18 will have a 'clock_adjtime' definition added, so it can't be static in the code:
valid-adjtimex.c:43:12: error: static declaration of ‘clock_adjtime’ follows non-static declaration
Fixes: e03a58c320e1 ("kselftests: timers: Add adjtimex SETOFFSET validity tests") Signed-off-by: Wolfram Sang wsa+renesas@sang-engineering.com Acked-by: John Stultz jstultz@google.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/timers/valid-adjtimex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/timers/valid-adjtimex.c b/tools/testing/selftests/timers/valid-adjtimex.c index 5397de708d3c..48b9a803235a 100644 --- a/tools/testing/selftests/timers/valid-adjtimex.c +++ b/tools/testing/selftests/timers/valid-adjtimex.c @@ -40,7 +40,7 @@ #define ADJ_SETOFFSET 0x0100
#include <sys/syscall.h> -static int clock_adjtime(clockid_t id, struct timex *tx) +int clock_adjtime(clockid_t id, struct timex *tx) { return syscall(__NR_clock_adjtime, id, tx); }
From: Wolfram Sang wsa+renesas@sang-engineering.com
[ Upstream commit 4d8f52ac5fa9eede7b7aa2f2d67c841d9eeb655f ]
The return value from system() is a waitpid-style integer. Do not return it directly because with the implicit masking in exit() it will always return 0. Access it with appropriate macros to really pass on errors.
Fixes: 7290ce1423c3 ("selftests/timers: Add clocksource-switch test from timetest suite") Signed-off-by: Wolfram Sang wsa+renesas@sang-engineering.com Acked-by: John Stultz jstultz@google.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/timers/clocksource-switch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/timers/clocksource-switch.c b/tools/testing/selftests/timers/clocksource-switch.c index ef8eb3604595..b57f0a9be490 100644 --- a/tools/testing/selftests/timers/clocksource-switch.c +++ b/tools/testing/selftests/timers/clocksource-switch.c @@ -110,10 +110,10 @@ int run_tests(int secs)
sprintf(buf, "./inconsistency-check -t %i", secs); ret = system(buf); - if (ret) - return ret; + if (WIFEXITED(ret) && WEXITSTATUS(ret)) + return WEXITSTATUS(ret); ret = system("./nanosleep"); - return ret; + return WIFEXITED(ret) ? WEXITSTATUS(ret) : 0; }
From: Alexei Starovoitov ast@kernel.org
[ Upstream commit 9c7c48d6a1e2eb5192ad5294c1c4dbd42a88e88b ]
The commit 7337224fc150 ("bpf: Improve the info.func_info and info.func_info_rec_size behavior") accidently made bpf_prog_ksym_set_name() conservative for bpf subprograms. Fixed it so instead of "bpf_prog_tag_F" the stack traces print "bpf_prog_tag_full_subprog_name".
Fixes: 7337224fc150 ("bpf: Improve the info.func_info and info.func_info_rec_size behavior") Reported-by: Tejun Heo tj@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Martin KaFai Lau kafai@fb.com Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20220714211637.17150-1-alexei.starovoitov@gmail.... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/verifier.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 602366bc230f..e91d2faef160 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -13526,6 +13526,7 @@ static int jit_subprogs(struct bpf_verifier_env *env) /* Below members will be freed only at prog->aux */ func[i]->aux->btf = prog->aux->btf; func[i]->aux->func_info = prog->aux->func_info; + func[i]->aux->func_info_cnt = prog->aux->func_info_cnt; func[i]->aux->poke_tab = prog->aux->poke_tab; func[i]->aux->size_poke_tab = prog->aux->size_poke_tab;
@@ -13538,9 +13539,6 @@ static int jit_subprogs(struct bpf_verifier_env *env) poke->aux = func[i]->aux; }
- /* Use bpf_prog_F_tag to indicate functions in stack traces. - * Long term would need debug info to populate names - */ func[i]->aux->name[0] = 'F'; func[i]->aux->stack_depth = env->subprog_info[i].stack_depth; func[i]->jit_requested = 1;
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 284b38b6902a7154e3675482418a7b6df47808fe ]
At least the quantenna driver calls wdev_chandef() here which now requires the lock, so acquire it.
Fixes: 7b0a0e3c3a88 ("wifi: cfg80211: do some rework towards MLO link APIs") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/nl80211.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index af31978fc9cc..c4014ee3f667 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -10126,7 +10126,9 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb) }
while (1) { + wdev_lock(wdev); res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey); + wdev_unlock(wdev); if (res == -ENOENT) break; if (res)
From: Sakari Ailus sakari.ailus@linux.intel.com
[ Upstream commit 46347e3ec61660562d4a4a933713e2c2b74598e2 ]
For camera sensor devices the firmware information of which comes from non-DT (or some ACPI variants), the kernel makes the information visible to the drivers in a form similar to DT. This takes place through device's secondary fwnodes, in which case also the secondary fwnode needs to be heterogenously (endpoint vs. device) matched.
Fixes: 1f391df44607 ("media: v4l2-async: Use endpoints in __v4l2_async_nf_add_fwnode_remote()") Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Reviewed-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/v4l2-core/v4l2-async.c | 35 +++++++++++++++++----------- 1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index c6995718237a..b16f3ce8e5ef 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -66,8 +66,10 @@ static bool match_i2c(struct v4l2_async_notifier *notifier, #endif }
-static bool match_fwnode(struct v4l2_async_notifier *notifier, - struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) +static bool +match_fwnode_one(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd, struct fwnode_handle *sd_fwnode, + struct v4l2_async_subdev *asd) { struct fwnode_handle *other_fwnode; struct fwnode_handle *dev_fwnode; @@ -80,15 +82,7 @@ static bool match_fwnode(struct v4l2_async_notifier *notifier, * fwnode or a device fwnode. Start with the simple case of direct * fwnode matching. */ - if (sd->fwnode == asd->match.fwnode) - return true; - - /* - * Check the same situation for any possible secondary assigned to the - * subdev's fwnode - */ - if (!IS_ERR_OR_NULL(sd->fwnode->secondary) && - sd->fwnode->secondary == asd->match.fwnode) + if (sd_fwnode == asd->match.fwnode) return true;
/* @@ -99,7 +93,7 @@ static bool match_fwnode(struct v4l2_async_notifier *notifier, * ACPI. This won't make a difference, as drivers should not try to * match unconnected endpoints. */ - sd_fwnode_is_ep = fwnode_graph_is_endpoint(sd->fwnode); + sd_fwnode_is_ep = fwnode_graph_is_endpoint(sd_fwnode); asd_fwnode_is_ep = fwnode_graph_is_endpoint(asd->match.fwnode);
if (sd_fwnode_is_ep == asd_fwnode_is_ep) @@ -110,11 +104,11 @@ static bool match_fwnode(struct v4l2_async_notifier *notifier, * parent of the endpoint fwnode, and compare it with the other fwnode. */ if (sd_fwnode_is_ep) { - dev_fwnode = fwnode_graph_get_port_parent(sd->fwnode); + dev_fwnode = fwnode_graph_get_port_parent(sd_fwnode); other_fwnode = asd->match.fwnode; } else { dev_fwnode = fwnode_graph_get_port_parent(asd->match.fwnode); - other_fwnode = sd->fwnode; + other_fwnode = sd_fwnode; }
fwnode_handle_put(dev_fwnode); @@ -143,6 +137,19 @@ static bool match_fwnode(struct v4l2_async_notifier *notifier, return true; }
+static bool match_fwnode(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) +{ + if (match_fwnode_one(notifier, sd, sd->fwnode, asd)) + return true; + + /* Also check the secondary fwnode. */ + if (IS_ERR_OR_NULL(sd->fwnode->secondary)) + return false; + + return match_fwnode_one(notifier, sd, sd->fwnode->secondary, asd); +} + static LIST_HEAD(subdev_list); static LIST_HEAD(notifier_list); static DEFINE_MUTEX(list_lock);
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 7a9795b31049b7e233d050a82b00094155a695c7 ]
Add the missing gpiod_set_value_cansleep() and clk_disable_unprepare() before return from ov7251_set_power_on() in the error handling case.
Fixes: 9e1d3012cc10 ("media: i2c: Remove .s_power() from ov7251") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/ov7251.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c index 0e7be15bc20a..ad9689820ecc 100644 --- a/drivers/media/i2c/ov7251.c +++ b/drivers/media/i2c/ov7251.c @@ -934,6 +934,8 @@ static int ov7251_set_power_on(struct device *dev) ARRAY_SIZE(ov7251_global_init_setting)); if (ret < 0) { dev_err(ov7251->dev, "error during global init\n"); + gpiod_set_value_cansleep(ov7251->enable_gpio, 0); + clk_disable_unprepare(ov7251->xclk); ov7251_regulators_disable(ov7251); return ret; }
From: Jason A. Donenfeld Jason@zx2c4.com
[ Upstream commit 97ef77c52b789ec1411d360ed99dca1efe4b2c81 ]
The original direct splicing mechanism from Jens required the input to be a regular file because it was avoiding the special socket case. It also recognized blkdevs as being close enough to a regular file. But it forgot about chardevs, which behave the same way and work fine here.
This is an okayish heuristic, but it doesn't totally work. For example, a few chardevs should be spliceable here. And a few regular files shouldn't. This patch fixes this by instead checking whether FMODE_LSEEK is set, which represents decently enough what we need rewinding for when splicing to internal pipes.
Fixes: b92ce5589374 ("[PATCH] splice: add direct fd <-> fd splicing support") Cc: Jens Axboe axboe@kernel.dk Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/splice.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/fs/splice.c b/fs/splice.c index 047b79db8eb5..93a2c9bf6249 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -814,17 +814,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, { struct pipe_inode_info *pipe; long ret, bytes; - umode_t i_mode; size_t len; int i, flags, more;
/* - * We require the input being a regular file, as we don't want to - * randomly drop data for eg socket -> socket splicing. Use the - * piped splicing for that! + * We require the input to be seekable, as we don't want to randomly + * drop data for eg socket -> socket splicing. Use the piped splicing + * for that! */ - i_mode = file_inode(in)->i_mode; - if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode))) + if (unlikely(!(in->f_mode & FMODE_LSEEK))) return -EINVAL;
/*
From: Jernej Skrabec jernej.skrabec@gmail.com
[ Upstream commit 104a70e1d0bcef28db13c4192b8729086089651c ]
Bit 21 in register 0x24 (slice header info 1) actually represents negated version of low delay flag. This can be seen in vendor Cedar library source code. While this flag is not part of the standard, it can be found in reference HEVC implementation.
Fix macro name and change it to flag.
Fixes: 86caab29da78 ("media: cedrus: Add HEVC/H.265 decoding support") Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 4 +++- drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c index 44f385be9f6c..2febdf7a97fe 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c @@ -559,7 +559,6 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
reg = VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(slice_params->slice_tc_offset_div2) | VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(slice_params->slice_beta_offset_div2) | - VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(decode_params->num_poc_st_curr_after == 0) | VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(slice_params->slice_cr_qp_offset) | VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(slice_params->slice_cb_qp_offset) | VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA(slice_params->slice_qp_delta); @@ -572,6 +571,9 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED, slice_params->flags);
+ if (decode_params->num_poc_st_curr_after == 0) + reg |= VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_NOT_LOW_DELAY; + cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO1, reg);
chroma_log2_weight_denom = pred_weight_table->luma_log2_weight_denom + diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h index bdb062ad8682..d81f7513ade0 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h @@ -377,13 +377,12 @@
#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED BIT(23) #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED BIT(22) +#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_NOT_LOW_DELAY BIT(21)
#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(v) \ SHIFT_AND_MASK_BITS(v, 31, 28) #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(v) \ SHIFT_AND_MASK_BITS(v, 27, 24) -#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(v) \ - ((v) ? BIT(21) : 0) #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(v) \ SHIFT_AND_MASK_BITS(v, 20, 16) #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(v) \
From: Benjamin Gaignard benjamin.gaignard@collabora.com
[ Upstream commit c4a179c7167ee16aad1267f9c99bc1ecff475585 ]
The HEVC specification describes the following: "PicOrderCntVal is derived as follows: PicOrderCntVal = PicOrderCntMsb + slice_pic_order_cnt_lsb The value of PicOrderCntVal shall be in the range of −2^31 to 2^31 − 1, inclusive."
To match with these definitions change __u16 pic_order_cnt[2] into __s32 pic_order_cnt_val. Change v4l2_ctrl_hevc_slice_params->slice_pic_order_cnt to __s32 too.
Signed-off-by: Benjamin Gaignard benjamin.gaignard@collabora.com Reviewed-by: Ezequiel Garcia ezequiel@vanguardiasur.com.ar Acked-by: Nicolas Dufresne nicolas.dufresne@collabora.com Tested-by: Jernej Skrabec jernej.skrabec@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 2 +- drivers/staging/media/hantro/hantro_g2_hevc_dec.c | 7 +++---- drivers/staging/media/hantro/hantro_hevc.c | 2 +- drivers/staging/media/hantro/hantro_hw.h | 4 ++-- drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 4 ++-- include/media/hevc-ctrls.h | 4 ++-- 6 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 6183f43f4d73..004b0ec62c44 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -2997,7 +2997,7 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - * - __u8 - ``colour_plane_id`` - - * - __u16 + * - __s32 - ``slice_pic_order_cnt`` - * - __u8 diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c index 5df6f08e26f5..d28653d04d20 100644 --- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c +++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c @@ -390,11 +390,10 @@ static int set_ref(struct hantro_ctx *ctx) !!(pps->flags & V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED));
/* - * Write POC count diff from current pic. For frame decoding only compute - * pic_order_cnt[0] and ignore pic_order_cnt[1] used in field-coding. + * Write POC count diff from current pic. */ for (i = 0; i < decode_params->num_active_dpb_entries && i < ARRAY_SIZE(cur_poc); i++) { - char poc_diff = decode_params->pic_order_cnt_val - dpb[i].pic_order_cnt[0]; + char poc_diff = decode_params->pic_order_cnt_val - dpb[i].pic_order_cnt_val;
hantro_reg_write(vpu, &cur_poc[i], poc_diff); } @@ -421,7 +420,7 @@ static int set_ref(struct hantro_ctx *ctx) dpb_longterm_e = 0; for (i = 0; i < decode_params->num_active_dpb_entries && i < (V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1); i++) { - luma_addr = hantro_hevc_get_ref_buf(ctx, dpb[i].pic_order_cnt[0]); + luma_addr = hantro_hevc_get_ref_buf(ctx, dpb[i].pic_order_cnt_val); if (!luma_addr) return -ENOMEM;
diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c index bd924896e409..4f7e2acb46ec 100644 --- a/drivers/staging/media/hantro/hantro_hevc.c +++ b/drivers/staging/media/hantro/hantro_hevc.c @@ -33,7 +33,7 @@ void hantro_hevc_ref_init(struct hantro_ctx *ctx) }
dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, - int poc) + s32 poc) { struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec; int i; diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index a2e0f0836281..33d156ccbfeb 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -145,7 +145,7 @@ struct hantro_hevc_dec_hw_ctx { struct hantro_aux_buf tile_bsd; struct hantro_aux_buf ref_bufs[NUM_REF_PICTURES]; struct hantro_aux_buf scaling_lists; - int ref_bufs_poc[NUM_REF_PICTURES]; + s32 ref_bufs_poc[NUM_REF_PICTURES]; u32 ref_bufs_used; struct hantro_hevc_dec_ctrls ctrls; unsigned int num_tile_cols_allocated; @@ -357,7 +357,7 @@ void hantro_hevc_dec_exit(struct hantro_ctx *ctx); int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx); int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx); void hantro_hevc_ref_init(struct hantro_ctx *ctx); -dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc); +dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, s32 poc); int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr); int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c index 2febdf7a97fe..c26e515d64c9 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c @@ -143,8 +143,8 @@ static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx, for (i = 0; i < num_active_dpb_entries; i++) { int buffer_index = vb2_find_timestamp(vq, dpb[i].timestamp, 0); u32 pic_order_cnt[2] = { - dpb[i].pic_order_cnt[0], - dpb[i].pic_order_cnt[1] + dpb[i].pic_order_cnt_val, + dpb[i].pic_order_cnt_val };
cedrus_h265_frame_info_write_single(ctx, i, dpb[i].field_pic, diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h index 01ccda48d8c5..88e804578cb1 100644 --- a/include/media/hevc-ctrls.h +++ b/include/media/hevc-ctrls.h @@ -135,7 +135,7 @@ struct v4l2_hevc_dpb_entry { __u64 timestamp; __u8 flags; __u8 field_pic; - __u16 pic_order_cnt[2]; + __s32 pic_order_cnt_val; __u8 padding[2]; };
@@ -178,7 +178,7 @@ struct v4l2_ctrl_hevc_slice_params { /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ __u8 slice_type; __u8 colour_plane_id; - __u16 slice_pic_order_cnt; + __s32 slice_pic_order_cnt; __u8 num_ref_idx_l0_active_minus1; __u8 num_ref_idx_l1_active_minus1; __u8 collocated_ref_idx;
From: Jernej Skrabec jernej.skrabec@gmail.com
[ Upstream commit f1a413902aa71044b6ec41265e5e28ebaf29a9ce ]
Now that we know real purpose of "not low delay" flag, logic for applying this flag should be fixed too. According to vendor and reference implementation, low delay is signaled when POC of current frame is lower than POC of at least one reference of a slice.
Implement mentioned logic and invert it to conform to flag meaning. Also don't apply flag for I frames. They don't have any reference.
This fixes decoding of 3 reference bitstreams.
Fixes: 86caab29da78 ("media: cedrus: Add HEVC/H.265 decoding support") Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../staging/media/sunxi/cedrus/cedrus_h265.c | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c index c26e515d64c9..2f6404fccd5a 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c @@ -301,6 +301,31 @@ static void cedrus_h265_write_scaling_list(struct cedrus_ctx *ctx, } }
+static int cedrus_h265_is_low_delay(struct cedrus_run *run) +{ + const struct v4l2_ctrl_hevc_slice_params *slice_params; + const struct v4l2_hevc_dpb_entry *dpb; + s32 poc; + int i; + + slice_params = run->h265.slice_params; + poc = run->h265.decode_params->pic_order_cnt_val; + dpb = run->h265.decode_params->dpb; + + for (i = 0; i < slice_params->num_ref_idx_l0_active_minus1 + 1; i++) + if (dpb[slice_params->ref_idx_l0[i]].pic_order_cnt_val > poc) + return 1; + + if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_B) + return 0; + + for (i = 0; i < slice_params->num_ref_idx_l1_active_minus1 + 1; i++) + if (dpb[slice_params->ref_idx_l1[i]].pic_order_cnt_val > poc) + return 1; + + return 0; +} + static void cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) { @@ -571,7 +596,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED, slice_params->flags);
- if (decode_params->num_poc_st_curr_after == 0) + if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_I && !cedrus_h265_is_low_delay(run)) reg |= VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_NOT_LOW_DELAY;
cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO1, reg);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 7a4836560a6198d245d5732e26f94898b12eb760 ]
The simple_write_to_buffer() function will succeed if even a single byte is initialized. However, we need to initialize the whole buffer to prevent information leaks. Just use memdup_user().
Fixes: ff974e408334 ("wil6210: debugfs interface to send raw WMI command") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/Ysg14NdKAZF/hcNG@kili Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wil6210/debugfs.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 64d6c98174c8..fe84362718de 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -1012,18 +1012,12 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf, u16 cmdid; int rc, rc1;
- if (cmdlen < 0) + if (cmdlen < 0 || *ppos != 0) return -EINVAL;
- wmi = kmalloc(len, GFP_KERNEL); - if (!wmi) - return -ENOMEM; - - rc = simple_write_to_buffer(wmi, len, ppos, buf, len); - if (rc < 0) { - kfree(wmi); - return rc; - } + wmi = memdup_user(buf, len); + if (IS_ERR(wmi)) + return PTR_ERR(wmi);
cmd = (cmdlen > 0) ? &wmi[1] : NULL; cmdid = le16_to_cpu(wmi->command_id);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 83781f0162d080fec7dcb911afd1bc2f5ad04471 ]
If an error occurs after a successful call to p54spi_request_firmware(), it must be undone by a corresponding release_firmware() as already done in the error handling path of p54spi_request_firmware() and in the .remove() function.
Add the missing call in the error handling path and remove it from p54spi_request_firmware() now that it is the responsibility of the caller to release the firmware
Fixes: cd8d3d321285 ("p54spi: p54spi driver") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Acked-by: Christian Lamparter chunkeey@gmail.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/297d2547ff2ee627731662abceeab9dbdaf23231.165506832... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intersil/p54/p54spi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intersil/p54/p54spi.c b/drivers/net/wireless/intersil/p54/p54spi.c index f99b7ba69fc3..19152fd449ba 100644 --- a/drivers/net/wireless/intersil/p54/p54spi.c +++ b/drivers/net/wireless/intersil/p54/p54spi.c @@ -164,7 +164,7 @@ static int p54spi_request_firmware(struct ieee80211_hw *dev)
ret = p54_parse_firmware(dev, priv->firmware); if (ret) { - release_firmware(priv->firmware); + /* the firmware is released by the caller */ return ret; }
@@ -659,6 +659,7 @@ static int p54spi_probe(struct spi_device *spi) return 0;
err_free_common: + release_firmware(priv->firmware); free_irq(gpio_to_irq(p54spi_gpio_irq), spi); err_free_gpio_irq: gpio_free(p54spi_gpio_irq);
From: Rustam Subkhankulov subkhankulov@ispras.ru
[ Upstream commit bcfd9d7f6840b06d5988c7141127795cf405805e ]
The assignment of the value to the variable total in the loop condition must be enclosed in additional parentheses, since otherwise, in accordance with the precedence of the operators, the conjunction will be performed first, and only then the assignment.
Due to this error, a warning later in the function after the loop may not occur in the situation when it should.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Rustam Subkhankulov subkhankulov@ispras.ru Fixes: 0d4171e2153b ("p54: implement flush callback") Acked-by: Christian Lamparter chunkeey@gmail.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220714134831.106004-1-subkhankulov@ispras.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intersil/p54/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intersil/p54/main.c b/drivers/net/wireless/intersil/p54/main.c index a3ca6620dc0c..8fa3ec71603e 100644 --- a/drivers/net/wireless/intersil/p54/main.c +++ b/drivers/net/wireless/intersil/p54/main.c @@ -682,7 +682,7 @@ static void p54_flush(struct ieee80211_hw *dev, struct ieee80211_vif *vif, * queues have already been stopped and no new frames can sneak * up from behind. */ - while ((total = p54_flush_count(priv) && i--)) { + while ((total = p54_flush_count(priv)) && i--) { /* waste time */ msleep(20); }
From: Alex Deucher alexander.deucher@amd.com
[ Upstream commit 912db6a58738e8be502838eb6a88f207ba356cd7 ]
Align aldebaran with all other asics. One HDP bit per SDMA instance, aligned with firmware. This is effectively a revert of commit a0f9f8546668 ("drm/amdgpu/nbio7.4: don't use GPU_HDP_FLUSH bit 12"). On further discussions with the relevant hardware teams, re-align the bits for SDMA.
Fixes: a0f9f8546668 ("drm/amdgpu/nbio7.4: don't use GPU_HDP_FLUSH bit 12") Reviewed-by: Kent Russell kent.russell@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 5 +---- drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 21 ------------------- drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h | 1 - 3 files changed, 1 insertion(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index 47f0344205ed..ba03238c9749 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -2194,12 +2194,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev) break; case IP_VERSION(7, 4, 0): case IP_VERSION(7, 4, 1): - adev->nbio.funcs = &nbio_v7_4_funcs; - adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg; - break; case IP_VERSION(7, 4, 4): adev->nbio.funcs = &nbio_v7_4_funcs; - adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg_ald; + adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg; break; case IP_VERSION(7, 2, 0): case IP_VERSION(7, 2, 1): diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c index 4531761dcf77..11848d1e238b 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c @@ -339,27 +339,6 @@ const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg = { .ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK, };
-const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald = { - .ref_and_mask_cp0 = GPU_HDP_FLUSH_DONE__CP0_MASK, - .ref_and_mask_cp1 = GPU_HDP_FLUSH_DONE__CP1_MASK, - .ref_and_mask_cp2 = GPU_HDP_FLUSH_DONE__CP2_MASK, - .ref_and_mask_cp3 = GPU_HDP_FLUSH_DONE__CP3_MASK, - .ref_and_mask_cp4 = GPU_HDP_FLUSH_DONE__CP4_MASK, - .ref_and_mask_cp5 = GPU_HDP_FLUSH_DONE__CP5_MASK, - .ref_and_mask_cp6 = GPU_HDP_FLUSH_DONE__CP6_MASK, - .ref_and_mask_cp7 = GPU_HDP_FLUSH_DONE__CP7_MASK, - .ref_and_mask_cp8 = GPU_HDP_FLUSH_DONE__CP8_MASK, - .ref_and_mask_cp9 = GPU_HDP_FLUSH_DONE__CP9_MASK, - .ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK, - .ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK, - .ref_and_mask_sdma2 = GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK, - .ref_and_mask_sdma3 = GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK, - .ref_and_mask_sdma4 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK, - .ref_and_mask_sdma5 = GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK, - .ref_and_mask_sdma6 = GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK, - .ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK, -}; - static void nbio_v7_4_init_registers(struct amdgpu_device *adev) { uint32_t baco_cntl; diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h index 7490022d79d4..f27c41728822 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h @@ -27,7 +27,6 @@ #include "soc15_common.h"
extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg; -extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald; extern const struct amdgpu_nbio_funcs nbio_v7_4_funcs; extern struct amdgpu_nbio_ras nbio_v7_4_ras;
From: Alex Deucher alexander.deucher@amd.com
[ Upstream commit 98a90f1f0fdd112b85b16ef6ceee69f319ab9311 ]
Align RDNA2.x with other asics. One HDP bit per SDMA instance, aligned with firmware. This is effectively a revert of commit 369b7d04baf3 ("drm/amdgpu/nbio2.3: don't use GPU_HDP_FLUSH bit 12"). On further discussions with the relevant hardware teams, re-align the bits for SDMA.
Fixes: 369b7d04baf3 ("drm/amdgpu/nbio2.3: don't use GPU_HDP_FLUSH bit 12") Reviewed-by: Kent Russell kent.russell@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 5 +---- drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c | 21 ------------------- drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h | 1 - 3 files changed, 1 insertion(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index ba03238c9749..c1636d311fe5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -2210,15 +2210,12 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev) case IP_VERSION(2, 3, 0): case IP_VERSION(2, 3, 1): case IP_VERSION(2, 3, 2): - adev->nbio.funcs = &nbio_v2_3_funcs; - adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; - break; case IP_VERSION(3, 3, 0): case IP_VERSION(3, 3, 1): case IP_VERSION(3, 3, 2): case IP_VERSION(3, 3, 3): adev->nbio.funcs = &nbio_v2_3_funcs; - adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg_sc; + adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; break; case IP_VERSION(4, 3, 0): case IP_VERSION(4, 3, 1): diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c index 6cd1fb2eb913..f49db13b3fbe 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c @@ -328,27 +328,6 @@ const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg = { .ref_and_mask_sdma1 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__SDMA1_MASK, };
-const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg_sc = { - .ref_and_mask_cp0 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP0_MASK, - .ref_and_mask_cp1 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP1_MASK, - .ref_and_mask_cp2 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP2_MASK, - .ref_and_mask_cp3 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP3_MASK, - .ref_and_mask_cp4 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP4_MASK, - .ref_and_mask_cp5 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP5_MASK, - .ref_and_mask_cp6 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP6_MASK, - .ref_and_mask_cp7 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP7_MASK, - .ref_and_mask_cp8 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP8_MASK, - .ref_and_mask_cp9 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP9_MASK, - .ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK, - .ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK, - .ref_and_mask_sdma2 = GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK, - .ref_and_mask_sdma3 = GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK, - .ref_and_mask_sdma4 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK, - .ref_and_mask_sdma5 = GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK, - .ref_and_mask_sdma6 = GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK, - .ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK, -}; - static void nbio_v2_3_init_registers(struct amdgpu_device *adev) { uint32_t def, data; diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h index 6074dd3a1ed8..a43b60acf7f6 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h @@ -27,7 +27,6 @@ #include "soc15_common.h"
extern const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg; -extern const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg_sc; extern const struct amdgpu_nbio_funcs nbio_v2_3_funcs;
#endif
From: Alex Deucher alexander.deucher@amd.com
[ Upstream commit 958afce98c2c86732483458c03540d3c6ef45254 ]
Save the original stable pstate on ctx init and restore it on ctx fini so that we restore a manually selected stable pstate on ctx exit.
v2: fix init order (Alex) v3: don't add new variable to ctx struct (Evan)
Fixes: c65b364c52ba ("drm/amdgpu/ctx: only reset stable pstate if the user changed it (v2)") Reviewed-by: Evan Quan evan.quan@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 60 ++++++++++++++----------- 1 file changed, 33 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 7dc92ef36b2b..8534c4c3b337 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -271,32 +271,6 @@ static ktime_t amdgpu_ctx_fini_entity(struct amdgpu_ctx_entity *entity) return res; }
-static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority, - struct drm_file *filp, struct amdgpu_ctx *ctx) -{ - int r; - - r = amdgpu_ctx_priority_permit(filp, priority); - if (r) - return r; - - memset(ctx, 0, sizeof(*ctx)); - - kref_init(&ctx->refcount); - ctx->mgr = mgr; - spin_lock_init(&ctx->ring_lock); - mutex_init(&ctx->lock); - - ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter); - ctx->reset_counter_query = ctx->reset_counter; - ctx->vram_lost_counter = atomic_read(&mgr->adev->vram_lost_counter); - ctx->init_priority = priority; - ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET; - ctx->stable_pstate = AMDGPU_CTX_STABLE_PSTATE_NONE; - - return 0; -} - static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx *ctx, u32 *stable_pstate) { @@ -325,6 +299,38 @@ static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx *ctx, return 0; }
+static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority, + struct drm_file *filp, struct amdgpu_ctx *ctx) +{ + u32 current_stable_pstate; + int r; + + r = amdgpu_ctx_priority_permit(filp, priority); + if (r) + return r; + + memset(ctx, 0, sizeof(*ctx)); + + kref_init(&ctx->refcount); + ctx->mgr = mgr; + spin_lock_init(&ctx->ring_lock); + mutex_init(&ctx->lock); + + ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter); + ctx->reset_counter_query = ctx->reset_counter; + ctx->vram_lost_counter = atomic_read(&mgr->adev->vram_lost_counter); + ctx->init_priority = priority; + ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET; + + r = amdgpu_ctx_get_stable_pstate(ctx, ¤t_stable_pstate); + if (r) + return r; + + ctx->stable_pstate = current_stable_pstate; + + return 0; +} + static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx, u32 stable_pstate) { @@ -396,7 +402,7 @@ static void amdgpu_ctx_fini(struct kref *ref) }
if (drm_dev_enter(&adev->ddev, &idx)) { - amdgpu_ctx_set_stable_pstate(ctx, AMDGPU_CTX_STABLE_PSTATE_NONE); + amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate); drm_dev_exit(idx); }
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit 87ac0d600943994444e24382a87aa19acc4cd3d4 ]
If BPF array map is bigger than 4GB, element pointer calculation can overflow because both index and elem_size are u32. Fix this everywhere by forcing 64-bit multiplication. Extract this formula into separate small helper and use it consistently in various places.
Speculative-preventing formula utilizing index_mask trick is left as is, but explicit u64 casts are added in both places.
Fixes: c85d69135a91 ("bpf: move memory size checks to bpf_map_charge_init()") Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/r/20220715053146.1291891-2-andrii@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/arraymap.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index fe40d3b9458f..1d05d63e6fa5 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c @@ -156,6 +156,11 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) return &array->map; }
+static void *array_map_elem_ptr(struct bpf_array* array, u32 index) +{ + return array->value + (u64)array->elem_size * index; +} + /* Called from syscall or from eBPF program */ static void *array_map_lookup_elem(struct bpf_map *map, void *key) { @@ -165,7 +170,7 @@ static void *array_map_lookup_elem(struct bpf_map *map, void *key) if (unlikely(index >= array->map.max_entries)) return NULL;
- return array->value + array->elem_size * (index & array->index_mask); + return array->value + (u64)array->elem_size * (index & array->index_mask); }
static int array_map_direct_value_addr(const struct bpf_map *map, u64 *imm, @@ -339,7 +344,7 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value, value, map->value_size); } else { val = array->value + - array->elem_size * (index & array->index_mask); + (u64)array->elem_size * (index & array->index_mask); if (map_flags & BPF_F_LOCK) copy_map_value_locked(map, val, value, false); else @@ -408,8 +413,7 @@ static void array_map_free_timers(struct bpf_map *map) return;
for (i = 0; i < array->map.max_entries; i++) - bpf_timer_cancel_and_free(array->value + array->elem_size * i + - map->timer_off); + bpf_timer_cancel_and_free(array_map_elem_ptr(array, i) + map->timer_off); }
/* Called when map->refcnt goes to zero, either from workqueue or from syscall */ @@ -420,7 +424,7 @@ static void array_map_free(struct bpf_map *map)
if (map_value_has_kptrs(map)) { for (i = 0; i < array->map.max_entries; i++) - bpf_map_free_kptrs(map, array->value + array->elem_size * i); + bpf_map_free_kptrs(map, array_map_elem_ptr(array, i)); bpf_map_free_kptr_off_tab(map); }
@@ -556,7 +560,7 @@ static void *bpf_array_map_seq_start(struct seq_file *seq, loff_t *pos) index = info->index & array->index_mask; if (info->percpu_value_buf) return array->pptrs[index]; - return array->value + array->elem_size * index; + return array_map_elem_ptr(array, index); }
static void *bpf_array_map_seq_next(struct seq_file *seq, void *v, loff_t *pos) @@ -575,7 +579,7 @@ static void *bpf_array_map_seq_next(struct seq_file *seq, void *v, loff_t *pos) index = info->index & array->index_mask; if (info->percpu_value_buf) return array->pptrs[index]; - return array->value + array->elem_size * index; + return array_map_elem_ptr(array, index); }
static int __bpf_array_map_seq_show(struct seq_file *seq, void *v) @@ -690,7 +694,7 @@ static int bpf_for_each_array_elem(struct bpf_map *map, bpf_callback_t callback_ if (is_percpu) val = this_cpu_ptr(array->pptrs[i]); else - val = array->value + array->elem_size * i; + val = array_map_elem_ptr(array, i); num_elems++; key = i; ret = callback_fn((u64)(long)map, (u64)(long)&key,
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit 597fbc4682969361dd141aaa58b8cc73a80da85d ]
Make libbpf adjust RINGBUF map size (rounding it up to closest power-of-2 of page_size) more eagerly: during open phase when initializing the map and on explicit calls to bpf_map__set_max_entries().
Such approach allows user to check actual size of BPF ringbuf even before it's created in the kernel, but also it prevents various edge case scenarios where BPF ringbuf size can get out of sync with what it would be in kernel. One of them (reported in [0]) is during an attempt to pin/reuse BPF ringbuf.
Move adjust_ringbuf_sz() helper closer to its first actual use. The implementation of the helper is unchanged.
Also make detection of whether bpf_object is already loaded more robust by checking obj->loaded explicitly, given that map->fd can be < 0 even if bpf_object is already loaded due to ability to disable map creation with bpf_map__set_autocreate(map, false).
[0] Closes: https://github.com/libbpf/libbpf/pull/530
Fixes: 0087a681fa8c ("libbpf: Automatically fix up BPF_MAP_TYPE_RINGBUF size, if necessary") Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/r/20220715230952.2219271-1-andrii@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 77 +++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 35 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 5b9b42ab7aa0..266357b1dca1 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -2398,6 +2398,37 @@ int parse_btf_map_def(const char *map_name, struct btf *btf, return 0; }
+static size_t adjust_ringbuf_sz(size_t sz) +{ + __u32 page_sz = sysconf(_SC_PAGE_SIZE); + __u32 mul; + + /* if user forgot to set any size, make sure they see error */ + if (sz == 0) + return 0; + /* Kernel expects BPF_MAP_TYPE_RINGBUF's max_entries to be + * a power-of-2 multiple of kernel's page size. If user diligently + * satisified these conditions, pass the size through. + */ + if ((sz % page_sz) == 0 && is_pow_of_2(sz / page_sz)) + return sz; + + /* Otherwise find closest (page_sz * power_of_2) product bigger than + * user-set size to satisfy both user size request and kernel + * requirements and substitute correct max_entries for map creation. + */ + for (mul = 1; mul <= UINT_MAX / page_sz; mul <<= 1) { + if (mul * page_sz > sz) + return mul * page_sz; + } + + /* if it's impossible to satisfy the conditions (i.e., user size is + * very close to UINT_MAX but is not a power-of-2 multiple of + * page_size) then just return original size and let kernel reject it + */ + return sz; +} + static void fill_map_from_def(struct bpf_map *map, const struct btf_map_def *def) { map->def.type = def->map_type; @@ -2411,6 +2442,10 @@ static void fill_map_from_def(struct bpf_map *map, const struct btf_map_def *def map->btf_key_type_id = def->key_type_id; map->btf_value_type_id = def->value_type_id;
+ /* auto-adjust BPF ringbuf map max_entries to be a multiple of page size */ + if (map->def.type == BPF_MAP_TYPE_RINGBUF) + map->def.max_entries = adjust_ringbuf_sz(map->def.max_entries); + if (def->parts & MAP_DEF_MAP_TYPE) pr_debug("map '%s': found type = %u.\n", map->name, def->map_type);
@@ -4401,9 +4436,15 @@ struct bpf_map *bpf_map__inner_map(struct bpf_map *map)
int bpf_map__set_max_entries(struct bpf_map *map, __u32 max_entries) { - if (map->fd >= 0) + if (map->obj->loaded) return libbpf_err(-EBUSY); + map->def.max_entries = max_entries; + + /* auto-adjust BPF ringbuf map max_entries to be a multiple of page size */ + if (map->def.type == BPF_MAP_TYPE_RINGBUF) + map->def.max_entries = adjust_ringbuf_sz(map->def.max_entries); + return 0; }
@@ -4948,37 +4989,6 @@ bpf_object__populate_internal_map(struct bpf_object *obj, struct bpf_map *map)
static void bpf_map__destroy(struct bpf_map *map);
-static size_t adjust_ringbuf_sz(size_t sz) -{ - __u32 page_sz = sysconf(_SC_PAGE_SIZE); - __u32 mul; - - /* if user forgot to set any size, make sure they see error */ - if (sz == 0) - return 0; - /* Kernel expects BPF_MAP_TYPE_RINGBUF's max_entries to be - * a power-of-2 multiple of kernel's page size. If user diligently - * satisified these conditions, pass the size through. - */ - if ((sz % page_sz) == 0 && is_pow_of_2(sz / page_sz)) - return sz; - - /* Otherwise find closest (page_sz * power_of_2) product bigger than - * user-set size to satisfy both user size request and kernel - * requirements and substitute correct max_entries for map creation. - */ - for (mul = 1; mul <= UINT_MAX / page_sz; mul <<= 1) { - if (mul * page_sz > sz) - return mul * page_sz; - } - - /* if it's impossible to satisfy the conditions (i.e., user size is - * very close to UINT_MAX but is not a power-of-2 multiple of - * page_size) then just return original size and let kernel reject it - */ - return sz; -} - static int bpf_object__create_map(struct bpf_object *obj, struct bpf_map *map, bool is_inner) { LIBBPF_OPTS(bpf_map_create_opts, create_attr); @@ -5017,9 +5027,6 @@ static int bpf_object__create_map(struct bpf_object *obj, struct bpf_map *map, b }
switch (def->type) { - case BPF_MAP_TYPE_RINGBUF: - map->def.max_entries = adjust_ringbuf_sz(map->def.max_entries); - /* fallthrough */ case BPF_MAP_TYPE_PERF_EVENT_ARRAY: case BPF_MAP_TYPE_CGROUP_ARRAY: case BPF_MAP_TYPE_STACK_TRACE:
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit c5d22f4cfe8dfb93f1db0a1e7e2e7ebc41395d98 ]
The snprintf() function returns the number of bytes which *would* have been copied if there were space. In other words, it can be
sizeof(pin_path).
Fixes: c0fa1b6c3efc ("bpf: btf: Add BTF tests") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Martin KaFai Lau kafai@fb.com Link: https://lore.kernel.org/r/YtZ+aD/tZMkgOUw+@kili Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/prog_tests/btf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/btf.c b/tools/testing/selftests/bpf/prog_tests/btf.c index ba5bde53d418..5af690063af5 100644 --- a/tools/testing/selftests/bpf/prog_tests/btf.c +++ b/tools/testing/selftests/bpf/prog_tests/btf.c @@ -5324,7 +5324,7 @@ static void do_test_pprint(int test_num) ret = snprintf(pin_path, sizeof(pin_path), "%s/%s", "/sys/fs/bpf", test->map_name);
- if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long", + if (CHECK(ret >= sizeof(pin_path), "pin_path %s/%s is too long", "/sys/fs/bpf", test->map_name)) { err = -1; goto done;
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit b77ffb30cfc5f58e957571d8541c6a7e3da19221 ]
The snprintf() function returns the number of bytes it *would* have copied if there were enough space. So it can return > the sizeof(gen->attach_target).
Fixes: 67234743736a ("libbpf: Generate loader program out of BPF ELF file.") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Martin KaFai Lau kafai@fb.com Link: https://lore.kernel.org/r/YtZ+oAySqIhFl6/J@kili Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/gen_loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c index 927745b08014..23f5c46708f8 100644 --- a/tools/lib/bpf/gen_loader.c +++ b/tools/lib/bpf/gen_loader.c @@ -533,7 +533,7 @@ void bpf_gen__record_attach_target(struct bpf_gen *gen, const char *attach_name, gen->attach_kind = kind; ret = snprintf(gen->attach_target, sizeof(gen->attach_target), "%s%s", prefix, attach_name); - if (ret == sizeof(gen->attach_target)) + if (ret >= sizeof(gen->attach_target)) gen->error = -ENOSPC; }
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit 3a5c7e4611ddcf0ef37a3a17296b964d986161a6 ]
During bus off, the error count is greater than 255 and can not fit in a u8.
Fixes: 0c78ab76a05c ("pch_can: Add setting TEC/REC statistics processing") Link: https://lore.kernel.org/all/20220719143550.3681-2-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/pch_can.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index fde3ac516d26..497ef77340ea 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -496,6 +496,9 @@ static void pch_can_error(struct net_device *ndev, u32 status) cf->can_id |= CAN_ERR_BUSOFF; priv->can.can_stats.bus_off++; can_bus_off(ndev); + } else { + cf->data[6] = errc & PCH_TEC; + cf->data[7] = (errc & PCH_REC) >> 8; }
errc = ioread32(&priv->regs->errc); @@ -556,9 +559,6 @@ static void pch_can_error(struct net_device *ndev, u32 status) break; }
- cf->data[6] = errc & PCH_TEC; - cf->data[7] = (errc & PCH_REC) >> 8; - priv->can.state = state; netif_receive_skb(skb); }
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit a37b7245e831a641df360ca41db6a71c023d3746 ]
During bus off, the error count is greater than 255 and can not fit in a u8.
Fixes: fd1159318e55 ("can: add Renesas R-Car CAN driver") Link: https://lore.kernel.org/all/20220719143550.3681-3-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/rcar/rcar_can.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c index d45762f1cf6b..24d7a71def6a 100644 --- a/drivers/net/can/rcar/rcar_can.c +++ b/drivers/net/can/rcar/rcar_can.c @@ -232,11 +232,8 @@ static void rcar_can_error(struct net_device *ndev) if (eifr & (RCAR_CAN_EIFR_EWIF | RCAR_CAN_EIFR_EPIF)) { txerr = readb(&priv->regs->tecr); rxerr = readb(&priv->regs->recr); - if (skb) { + if (skb) cf->can_id |= CAN_ERR_CRTL; - cf->data[6] = txerr; - cf->data[7] = rxerr; - } } if (eifr & RCAR_CAN_EIFR_BEIF) { int rx_errors = 0, tx_errors = 0; @@ -336,6 +333,9 @@ static void rcar_can_error(struct net_device *ndev) can_bus_off(ndev); if (skb) cf->can_id |= CAN_ERR_BUSOFF; + } else if (skb) { + cf->data[6] = txerr; + cf->data[7] = rxerr; } if (eifr & RCAR_CAN_EIFR_ORIF) { netdev_dbg(priv->ndev, "Receive overrun error interrupt\n");
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit 164d7cb2d5a30f1b3a5ab4fab1a27731fb1494a8 ]
During bus off, the error count is greater than 255 and can not fit in a u8.
Fixes: 215db1856e83 ("can: sja1000: Consolidate and unify state change handling") Link: https://lore.kernel.org/all/20220719143550.3681-4-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/sja1000/sja1000.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 2e7638f98cf1..84adf8b5945e 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -402,9 +402,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) txerr = priv->read_reg(priv, SJA1000_TXERR); rxerr = priv->read_reg(priv, SJA1000_RXERR);
- cf->data[6] = txerr; - cf->data[7] = rxerr; - if (isrc & IRQ_DOI) { /* data overrun interrupt */ netdev_dbg(dev, "data overrun interrupt\n"); @@ -426,6 +423,10 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) else state = CAN_STATE_ERROR_ACTIVE; } + if (state != CAN_STATE_BUS_OFF) { + cf->data[6] = txerr; + cf->data[7] = rxerr; + } if (isrc & IRQ_BEI) { /* bus error interrupt */ priv->can.can_stats.bus_error++;
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit a22bd630cfff496b270211745536e50e98eb3a45 ]
During bus off, the error count is greater than 255 and can not fit in a u8.
Fixes: 57e83fb9b746 ("can: hi311x: Add Holt HI-311x CAN driver") Link: https://lore.kernel.org/all/20220719143550.3681-6-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/spi/hi311x.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c index ebc4ebb44c98..bfb7c4bb5bc3 100644 --- a/drivers/net/can/spi/hi311x.c +++ b/drivers/net/can/spi/hi311x.c @@ -667,8 +667,6 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
txerr = hi3110_read(spi, HI3110_READ_TEC); rxerr = hi3110_read(spi, HI3110_READ_REC); - cf->data[6] = txerr; - cf->data[7] = rxerr; tx_state = txerr >= rxerr ? new_state : 0; rx_state = txerr <= rxerr ? new_state : 0; can_change_state(net, cf, tx_state, rx_state); @@ -681,6 +679,9 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) hi3110_hw_sleep(spi); break; } + } else { + cf->data[6] = txerr; + cf->data[7] = rxerr; } }
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit 0ac15a8f661b941519379831d09bfb12271b23ee ]
During bus off, the error count is greater than 255 and can not fit in a u8.
Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module") Link: https://lore.kernel.org/all/20220719143550.3681-7-mailhol.vincent@wanadoo.fr CC: Chen-Yu Tsai wens@csie.org Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/sun4i_can.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c index 155b90f6c767..afe9b541f037 100644 --- a/drivers/net/can/sun4i_can.c +++ b/drivers/net/can/sun4i_can.c @@ -535,11 +535,6 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) rxerr = (errc >> 16) & 0xFF; txerr = errc & 0xFF;
- if (skb) { - cf->data[6] = txerr; - cf->data[7] = rxerr; - } - if (isrc & SUN4I_INT_DATA_OR) { /* data overrun interrupt */ netdev_dbg(dev, "data overrun interrupt\n"); @@ -570,6 +565,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) else state = CAN_STATE_ERROR_ACTIVE; } + if (skb && state != CAN_STATE_BUS_OFF) { + cf->data[6] = txerr; + cf->data[7] = rxerr; + } if (isrc & SUN4I_INT_BUS_ERR) { /* bus error interrupt */ netdev_dbg(dev, "bus error interrupt\n");
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit 936e90595376e64b6247c72d3ea8b8b164b7ac96 ]
During bus off, the error count is greater than 255 and can not fit in a u8.
Fixes: aec5fb2268b7 ("can: kvaser_usb: Add support for Kvaser USB hydra family") Link: https://lore.kernel.org/all/20220719143550.3681-8-mailhol.vincent@wanadoo.fr CC: Jimmy Assarsson extja@kvaser.com Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c index 5d70844ac030..404093468b2f 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c @@ -917,8 +917,10 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv, new_state < CAN_STATE_BUS_OFF) priv->can.can_stats.restarts++;
- cf->data[6] = bec->txerr; - cf->data[7] = bec->rxerr; + if (new_state != CAN_STATE_BUS_OFF) { + cf->data[6] = bec->txerr; + cf->data[7] = bec->rxerr; + }
netif_rx(skb); } @@ -1069,8 +1071,10 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv, shhwtstamps->hwtstamp = hwtstamp;
cf->can_id |= CAN_ERR_BUSERROR; - cf->data[6] = bec.txerr; - cf->data[7] = bec.rxerr; + if (new_state != CAN_STATE_BUS_OFF) { + cf->data[6] = bec.txerr; + cf->data[7] = bec.rxerr; + }
netif_rx(skb);
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit a57732084e06791d37ea1ea447cca46220737abd ]
During bus off, the error count is greater than 255 and can not fit in a u8.
Fixes: 7259124eac7d1 ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c") Link: https://lore.kernel.org/all/20220719143550.3681-9-mailhol.vincent@wanadoo.fr CC: Jimmy Assarsson extja@kvaser.com Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c index cc809ecd1e62..f551fde16a70 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -853,8 +853,10 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev, break; }
- cf->data[6] = es->txerr; - cf->data[7] = es->rxerr; + if (new_state != CAN_STATE_BUS_OFF) { + cf->data[6] = es->txerr; + cf->data[7] = es->rxerr; + }
netif_rx(skb); }
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit aebe8a2433cd090ccdc222861f44bddb75eb01de ]
During bus off, the error count is greater than 255 and can not fit in a u8.
Fixes: 0024d8ad1639 ("can: usb_8dev: Add support for USB2CAN interface from 8 devices") Link: https://lore.kernel.org/all/20220719143550.3681-10-mailhol.vincent@wanadoo.f... Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/usb/usb_8dev.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c index f3363575bf32..4d38dc90472a 100644 --- a/drivers/net/can/usb/usb_8dev.c +++ b/drivers/net/can/usb/usb_8dev.c @@ -438,9 +438,10 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
if (rx_errors) stats->rx_errors++; - - cf->data[6] = txerr; - cf->data[7] = rxerr; + if (priv->can.state != CAN_STATE_BUS_OFF) { + cf->data[6] = txerr; + cf->data[7] = rxerr; + }
priv->bec.txerr = txerr; priv->bec.rxerr = rxerr;
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit e70a3263a7eed768d5f947b8f2aff8d2a79c9d97 ]
Currently, data[5..7] of struct can_frame, when used as a CAN error frame, are defined as being "controller specific". Device specific behaviours are problematic because it prevents someone from writing code which is portable between devices.
As a matter of fact, data[5] is never used, data[6] is always used to report TX error counter and data[7] is always used to report RX error counter. can-utils also relies on this.
This patch updates the comment in the uapi header to specify that data[5] is reserved (and thus should not be used) and that data[6..7] are used for error counters.
Fixes: 0d66548a10cb ("[CAN]: Add PF_CAN core module") Link: https://lore.kernel.org/all/20220719143550.3681-11-mailhol.vincent@wanadoo.f... Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/uapi/linux/can/error.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/can/error.h b/include/uapi/linux/can/error.h index 34633283de64..a1000cb63063 100644 --- a/include/uapi/linux/can/error.h +++ b/include/uapi/linux/can/error.h @@ -120,6 +120,9 @@ #define CAN_ERR_TRX_CANL_SHORT_TO_GND 0x70 /* 0111 0000 */ #define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80 /* 1000 0000 */
-/* controller specific additional information / data[5..7] */ +/* data[5] is reserved (do not use) */ + +/* TX error counter / data[6] */ +/* RX error counter / data[7] */
#endif /* _UAPI_CAN_ERROR_H */
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 14229b8153a3ca51d97a22a18c68deeae64afce0 ]
The return from strcmp() is inverted so it wrongly returns true instead of false and vice versa.
Fixes: a1c9d61b19cb ("libbpf: Improve library identification for uprobe binary path resolution") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Martin KaFai Lau kafai@fb.com Cc: Alan Maguire alan.maguire@oracle.com Link: https://lore.kernel.org/bpf/YtZ+/dAA195d99ak@kili Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf_internal.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index ef5d975078e5..230ac5699c3d 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -109,9 +109,9 @@ static inline bool str_has_sfx(const char *str, const char *sfx) size_t str_len = strlen(str); size_t sfx_len = strlen(sfx);
- if (sfx_len <= str_len) - return strcmp(str + str_len - sfx_len, sfx); - return false; + if (sfx_len > str_len) + return false; + return strcmp(str + str_len - sfx_len, sfx) == 0; }
/* Symbol versioning is different between static and shared library.
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit 9950f11211331180269867aef848c7cf56861742 ]
After commit 3a5c7e4611dd, the variable errc is accessed before being initialized, c.f. below W=2 warning:
| In function 'pch_can_error', | inlined from 'pch_can_poll' at drivers/net/can/pch_can.c:739:4: | drivers/net/can/pch_can.c:501:29: warning: 'errc' may be used uninitialized [-Wmaybe-uninitialized] | 501 | cf->data[6] = errc & PCH_TEC; | | ^ | drivers/net/can/pch_can.c: In function 'pch_can_poll': | drivers/net/can/pch_can.c:484:13: note: 'errc' was declared here | 484 | u32 errc, lec; | | ^~~~
Moving errc initialization up solves this issue.
Fixes: 3a5c7e4611dd ("can: pch_can: do not report txerr and rxerr during bus-off") Reported-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Reviewed-by: Nathan Chancellor nathan@kernel.org Link: https://lore.kernel.org/all/20220721160032.9348-1-mailhol.vincent@wanadoo.fr Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/pch_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 497ef77340ea..f1afab4f8a27 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -489,6 +489,7 @@ static void pch_can_error(struct net_device *ndev, u32 status) if (!skb) return;
+ errc = ioread32(&priv->regs->errc); if (status & PCH_BUS_OFF) { pch_can_set_tx_all(priv, 0); pch_can_set_rx_all(priv, 0); @@ -501,7 +502,6 @@ static void pch_can_error(struct net_device *ndev, u32 status) cf->data[7] = (errc & PCH_REC) >> 8; }
- errc = ioread32(&priv->regs->errc); /* Warning interrupt. */ if (status & PCH_EWARN) { state = CAN_STATE_ERROR_WARNING;
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit ab2d2a982ff721f4b029282d9a40602ea46a745e ]
As platform_driver_register() could fail, it should be better to deal with the return value in order to maintain the code consisitency.
Fixes: 1ab1f239bf17 ("Bluetooth: hci_intel: Add support for platform driver") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/hci_intel.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index 7249b91d9b91..78afb9a348e7 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -1217,7 +1217,11 @@ static struct platform_driver intel_driver = {
int __init intel_init(void) { - platform_driver_register(&intel_driver); + int err; + + err = platform_driver_register(&intel_driver); + if (err) + return err;
return hci_uart_register_proto(&intel_proto); }
From: Schspa Shi schspa@gmail.com
[ Upstream commit 877afadad2dce8aae1f2aad8ce47e072d4f6165e ]
The HCI command, event, and data packet processing workqueue is drained to avoid deadlock in commit 76727c02c1e1 ("Bluetooth: Call drain_workqueue() before resetting state").
There is another delayed work, which will queue command to this drained workqueue. Which results in the following error report:
Bluetooth: hci2: command 0x040f tx timeout WARNING: CPU: 1 PID: 18374 at kernel/workqueue.c:1438 __queue_work+0xdad/0x1140 Workqueue: events hci_cmd_timeout RIP: 0010:__queue_work+0xdad/0x1140 RSP: 0000:ffffc90002cffc60 EFLAGS: 00010093 RAX: 0000000000000000 RBX: ffff8880b9d3ec00 RCX: 0000000000000000 RDX: ffff888024ba0000 RSI: ffffffff814e048d RDI: ffff8880b9d3ec08 RBP: 0000000000000008 R08: 0000000000000000 R09: 00000000b9d39700 R10: ffffffff814f73c6 R11: 0000000000000000 R12: ffff88807cce4c60 R13: 0000000000000000 R14: ffff8880796d8800 R15: ffff8880796d8800 FS: 0000000000000000(0000) GS:ffff8880b9d00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000c0174b4000 CR3: 000000007cae9000 CR4: 00000000003506e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? queue_work_on+0xcb/0x110 ? lockdep_hardirqs_off+0x90/0xd0 queue_work_on+0xee/0x110 process_one_work+0x996/0x1610 ? pwq_dec_nr_in_flight+0x2a0/0x2a0 ? rwlock_bug.part.0+0x90/0x90 ? _raw_spin_lock_irq+0x41/0x50 worker_thread+0x665/0x1080 ? process_one_work+0x1610/0x1610 kthread+0x2e9/0x3a0 ? kthread_complete_and_exit+0x40/0x40 ret_from_fork+0x1f/0x30 </TASK>
To fix this, we can add a new HCI_DRAIN_WQ flag, and don't queue the timeout workqueue while command workqueue is draining.
Fixes: 76727c02c1e1 ("Bluetooth: Call drain_workqueue() before resetting state") Reported-by: syzbot+63bed493aebbf6872647@syzkaller.appspotmail.com Signed-off-by: Schspa Shi schspa@gmail.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/bluetooth/hci.h | 1 + net/bluetooth/hci_core.c | 10 +++++++++- net/bluetooth/hci_event.c | 5 +++-- 3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index fe7935be7dc4..4a45c48eb0d2 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -361,6 +361,7 @@ enum { HCI_QUALITY_REPORT, HCI_OFFLOAD_CODECS_ENABLED, HCI_LE_SIMULTANEOUS_ROLES, + HCI_CMD_DRAIN_WORKQUEUE,
__HCI_NUM_FLAGS, }; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a0f99baafd35..6a53bcc5cfbb 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -594,6 +594,11 @@ static int hci_dev_do_reset(struct hci_dev *hdev) skb_queue_purge(&hdev->rx_q); skb_queue_purge(&hdev->cmd_q);
+ /* Cancel these to avoid queueing non-chained pending work */ + hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE); + cancel_delayed_work(&hdev->cmd_timer); + cancel_delayed_work(&hdev->ncmd_timer); + /* Avoid potential lockdep warnings from the *_flush() calls by * ensuring the workqueue is empty up front. */ @@ -607,6 +612,8 @@ static int hci_dev_do_reset(struct hci_dev *hdev) if (hdev->flush) hdev->flush(hdev);
+ hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE); + atomic_set(&hdev->cmd_cnt, 1); hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
@@ -3864,7 +3871,8 @@ static void hci_cmd_work(struct work_struct *work) if (res < 0) __hci_cmd_sync_cancel(hdev, -res);
- if (test_bit(HCI_RESET, &hdev->flags)) + if (test_bit(HCI_RESET, &hdev->flags) || + hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) cancel_delayed_work(&hdev->cmd_timer); else schedule_delayed_work(&hdev->cmd_timer, diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index af17dfb20e01..7cb956d3abb2 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3768,8 +3768,9 @@ static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd) cancel_delayed_work(&hdev->ncmd_timer); atomic_set(&hdev->cmd_cnt, 1); } else { - schedule_delayed_work(&hdev->ncmd_timer, - HCI_NCMD_TIMEOUT); + if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) + schedule_delayed_work(&hdev->ncmd_timer, + HCI_NCMD_TIMEOUT); } } }
From: Zhengping Jiang jiangzp@google.com
[ Upstream commit d7b2fdfb53ea09382941c0a4950dc9b00d51d1c7 ]
Set the connection data before calling get_conn_info_sync, so it can be verified the connection is still connected, before refreshing cached values.
Fixes: 47db6b42991e6 ("Bluetooth: hci_sync: Convert MGMT_OP_GET_CONN_INFO") Signed-off-by: Zhengping Jiang jiangzp@google.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/mgmt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 2f91a8c2b678..cbdf0e2bc5ae 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6820,11 +6820,14 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
cmd = mgmt_pending_new(sk, MGMT_OP_GET_CONN_INFO, hdev, data, len); - if (!cmd) + if (!cmd) { err = -ENOMEM; - else + } else { + hci_conn_hold(conn); + cmd->user_data = hci_conn_get(conn); err = hci_cmd_sync_queue(hdev, get_conn_info_sync, cmd, get_conn_info_complete); + }
if (err < 0) { mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, @@ -6836,9 +6839,6 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data, goto unlock; }
- hci_conn_hold(conn); - cmd->user_data = hci_conn_get(conn); - conn->conn_info_timestamp = jiffies; } else { /* Cache is valid, just reply with values cached in hci_conn */
From: Zhengping Jiang jiangzp@google.com
[ Upstream commit 68253f3cd715e819bc4bff2b0e6b21234e259d56 ]
After resuming, remove setting scanning_paused to false, because it is checked and set to false in hci_resume_scan_sync. Also move setting the value to false before updating passive scan, because the value is used when resuming passive scan.
Fixes: 3b42055388c30 (Bluetooth: hci_sync: Fix attempting to suspend with unfiltered passive scan)
Signed-off-by: Zhengping Jiang jiangzp@google.com Reviewed-by: Abhishek Pandit-Subedi abhishekpandit@chromium.org Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hci_sync.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index c17021642234..1641db8722e0 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -5039,13 +5039,13 @@ static int hci_resume_scan_sync(struct hci_dev *hdev) if (!hdev->scanning_paused) return 0;
+ hdev->scanning_paused = false; + hci_update_scan_sync(hdev);
/* Reset passive scanning to normal */ hci_update_passive_scan_sync(hdev);
- hdev->scanning_paused = false; - return 0; }
@@ -5064,7 +5064,6 @@ int hci_resume_sync(struct hci_dev *hdev) return 0;
hdev->suspended = false; - hdev->scanning_paused = false;
/* Restore event mask */ hci_set_event_mask_sync(hdev);
From: Luiz Augusto von Dentz luiz.von.dentz@intel.com
[ Upstream commit 0900b1c62f43e495d04ca4bebdf80b34f3c12432 ]
When programming a new entry into the resolving list it shall default to network mode since the params may contain the mode programmed when the device was last added to the resolving list.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=209745 Fixes: 853b70b506a20 ("Bluetooth: hci_sync: Set Privacy Mode when updating the resolving list") Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Tested-by: Zhengping Jiang jiangzp@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hci_sync.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 1641db8722e0..b5e7d4b8ab24 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -1612,6 +1612,9 @@ static int hci_le_add_resolve_list_sync(struct hci_dev *hdev, bacpy(&cp.bdaddr, ¶ms->addr); memcpy(cp.peer_irk, irk->val, 16);
+ /* Default privacy mode is always Network */ + params->privacy_mode = HCI_NETWORK_PRIVACY; + done: if (hci_dev_test_flag(hdev, HCI_PRIVACY)) memcpy(cp.local_irk, hdev->irk, 16);
From: Ying Hsu yinghsu@chromium.org
[ Upstream commit bee5395ced44c5a312348557eb2dfb0c2a7bfaa2 ]
Bluetooth HCI devices indicate if they are able to wakeup in the wakeup callback since 'commit 4539ca67fe8e ("Bluetooth: Rename driver .prevent_wake to .wakeup")'. This patch adds a default wakeup callback for Bluetooth HCI UAR devices. It assumes Bluetooth HCI UART devices are wakeable for backward compatibility. For those who need a customized behavior, one can override it before calling hci_uart_register_device().
Fixes: 4539ca67fe8e ("Bluetooth: Rename driver .prevent_wake to .wakeup") Signed-off-by: Ying Hsu yinghsu@chromium.org Reviewed-by: Alain Michaud alainm@chromium.org Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/hci_serdev.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c index 4cda890ce647..c0e5f42ec6b7 100644 --- a/drivers/bluetooth/hci_serdev.c +++ b/drivers/bluetooth/hci_serdev.c @@ -231,6 +231,15 @@ static int hci_uart_setup(struct hci_dev *hdev) return 0; }
+/* Check if the device is wakeable */ +static bool hci_uart_wakeup(struct hci_dev *hdev) +{ + /* HCI UART devices are assumed to be wakeable by default. + * Implement wakeup callback to override this behavior. + */ + return true; +} + /** hci_uart_write_wakeup - transmit buffer wakeup * @serdev: serial device * @@ -342,6 +351,8 @@ int hci_uart_register_device(struct hci_uart *hu, hdev->flush = hci_uart_flush; hdev->send = hci_uart_send_frame; hdev->setup = hci_uart_setup; + if (!hdev->wakeup) + hdev->wakeup = hci_uart_wakeup; SET_HCIDEV_DEV(hdev, &hu->serdev->dev);
if (test_bit(HCI_UART_NO_SUSPEND_NOTIFIER, &hu->flags))
From: Lars-Peter Clausen lars@metafoo.de
[ Upstream commit 9fdf6d97f03035ad5298e2d1635036c74c2090ed ]
SMBus packet error checking (PEC) is implemented by appending one additional byte of checksum data at the end of the message. This provides additional protection and allows to detect data corruption on the I2C bus.
SMBus block reads support variable length reads. The first byte in the read message is the number of available data bytes.
The combination of PEC and block read is currently not supported by the Cadence I2C driver. * When PEC is enabled the maximum transfer length for block reads increases from 33 to 34 bytes. * The I2C core smbus emulation layer relies on the driver updating the `i2c_msg` `len` field with the number of received bytes. The updated length is used when checking the PEC.
Add support to the Cadence I2C driver for handling SMBus block reads with PEC. To determine the maximum transfer length uses the initial `len` value of the `i2c_msg`. When PEC is enabled this will be 2, when it is disabled it will be 1.
Once a read transfer is done also increment the `len` field by the amount of received data bytes.
This change has been tested with a UCM90320 PMBus power monitor, which requires block reads to access certain data fields, but also has PEC enabled by default.
Fixes: df8eb5691c48 ("i2c: Add driver for Cadence I2C controller") Signed-off-by: Lars-Peter Clausen lars@metafoo.de Tested-by: Shubhrajyoti Datta Shubhrajyoti.datta@amd.com Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-cadence.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 630cfa4ddd46..33f5588a50c0 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -573,8 +573,13 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET); ctrl_reg |= CDNS_I2C_CR_RW | CDNS_I2C_CR_CLR_FIFO;
+ /* + * Receive up to I2C_SMBUS_BLOCK_MAX data bytes, plus one message length + * byte, plus one checksum byte if PEC is enabled. p_msg->len will be 2 if + * PEC is enabled, otherwise 1. + */ if (id->p_msg->flags & I2C_M_RECV_LEN) - id->recv_count = I2C_SMBUS_BLOCK_MAX + 1; + id->recv_count = I2C_SMBUS_BLOCK_MAX + id->p_msg->len;
id->curr_recv_count = id->recv_count;
@@ -789,6 +794,9 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg, if (id->err_status & CDNS_I2C_IXR_ARB_LOST) return -EAGAIN;
+ if (msg->flags & I2C_M_RECV_LEN) + msg->len += min_t(unsigned int, msg->buf[0], I2C_SMBUS_BLOCK_MAX); + return 0; }
From: Bjorn Andersson bjorn.andersson@linaro.org
[ Upstream commit b3f0ceb7c2037c6e3affd7d9c84ac5f97af7a5b5 ]
The introduction of GPI support moved things around and instead of returning the result from geni_i2c_xfer() the number of messages in the request was returned, ignoring the actual result. Fix this.
Fixes: d8703554f4de ("i2c: qcom-geni: Add support for GPI DMA") Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Reviewed-by: Andrew Halaney ahalaney@redhat.com Reviewed-by: Vinod Koul vkoul@kernel.org Reviewed-by: Johan Hovold johan+linaro@kernel.org Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-qcom-geni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 6ac402ea58fb..3bec7c782824 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -688,7 +688,7 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, pm_runtime_put_autosuspend(gi2c->se.dev); gi2c->cur = NULL; gi2c->err = 0; - return num; + return ret; }
static u32 geni_i2c_func(struct i2c_adapter *adap)
From: Qu Wenruo wqu@suse.com
[ Upstream commit 4d10046613333508d31fe926c545c8c0b620508a ]
[BUG] With added debugging, it turns out the following write sequence would cause extra read which is unnecessary:
# xfs_io -f -s -c "pwrite -b 32k 0 32k" -c "pwrite -b 32k 32k 32k" \ -c "pwrite -b 32k 64k 32k" -c "pwrite -b 32k 96k 32k" \ $mnt/file
The debug message looks like this (btrfs header skipped):
partial rmw, full stripe=389152768 opf=0x0 devid=3 type=1 offset=32768 physical=323059712 len=32768 partial rmw, full stripe=389152768 opf=0x0 devid=1 type=2 offset=0 physical=67174400 len=65536 full stripe rmw, full stripe=389152768 opf=0x1 devid=3 type=1 offset=0 physical=323026944 len=32768 full stripe rmw, full stripe=389152768 opf=0x1 devid=2 type=-1 offset=0 physical=323026944 len=32768 partial rmw, full stripe=298844160 opf=0x0 devid=1 type=1 offset=32768 physical=22052864 len=32768 partial rmw, full stripe=298844160 opf=0x0 devid=2 type=2 offset=0 physical=277872640 len=65536 full stripe rmw, full stripe=298844160 opf=0x1 devid=1 type=1 offset=0 physical=22020096 len=32768 full stripe rmw, full stripe=298844160 opf=0x1 devid=3 type=-1 offset=0 physical=277872640 len=32768 partial rmw, full stripe=389152768 opf=0x0 devid=3 type=1 offset=0 physical=323026944 len=32768 partial rmw, full stripe=389152768 opf=0x0 devid=1 type=2 offset=0 physical=67174400 len=65536 ^^^^ Still partial read, even 389152768 is already cached by the first. write.
full stripe rmw, full stripe=389152768 opf=0x1 devid=3 type=1 offset=32768 physical=323059712 len=32768 full stripe rmw, full stripe=389152768 opf=0x1 devid=2 type=-1 offset=32768 physical=323059712 len=32768 partial rmw, full stripe=298844160 opf=0x0 devid=1 type=1 offset=0 physical=22020096 len=32768 partial rmw, full stripe=298844160 opf=0x0 devid=2 type=2 offset=0 physical=277872640 len=65536 ^^^^ Still partial read for 298844160.
full stripe rmw, full stripe=298844160 opf=0x1 devid=1 type=1 offset=32768 physical=22052864 len=32768 full stripe rmw, full stripe=298844160 opf=0x1 devid=3 type=-1 offset=32768 physical=277905408 len=32768
This means every 32K writes, even they are in the same full stripe, still trigger read for previously cached data.
This would cause extra RAID56 IO, making the btrfs raid56 cache useless.
[CAUSE] Commit d4e28d9b5f04 ("btrfs: raid56: make steal_rbio() subpage compatible") tries to make steal_rbio() subpage compatible, but during that conversion, there is one thing missing.
We no longer rely on PageUptodate(rbio->stripe_pages[i]), but rbio->stripe_nsectors[i].uptodate to determine if a sector is uptodate.
This means, previously if we switch the pointer, everything is done, as the PageUptodate flag is still bound to that page.
But now we have to manually mark the involved sectors uptodate, or later raid56_rmw_stripe() will find the stolen sector is not uptodate, and assemble the read bio for it, wasting IO.
[FIX] We can easily fix the bug, by also update the rbio->stripe_sectors[].uptodate in steal_rbio().
With this fixed, now the same write pattern no longer leads to the same unnecessary read:
partial rmw, full stripe=389152768 opf=0x0 devid=3 type=1 offset=32768 physical=323059712 len=32768 partial rmw, full stripe=389152768 opf=0x0 devid=1 type=2 offset=0 physical=67174400 len=65536 full stripe rmw, full stripe=389152768 opf=0x1 devid=3 type=1 offset=0 physical=323026944 len=32768 full stripe rmw, full stripe=389152768 opf=0x1 devid=2 type=-1 offset=0 physical=323026944 len=32768 partial rmw, full stripe=298844160 opf=0x0 devid=1 type=1 offset=32768 physical=22052864 len=32768 partial rmw, full stripe=298844160 opf=0x0 devid=2 type=2 offset=0 physical=277872640 len=65536 full stripe rmw, full stripe=298844160 opf=0x1 devid=1 type=1 offset=0 physical=22020096 len=32768 full stripe rmw, full stripe=298844160 opf=0x1 devid=3 type=-1 offset=0 physical=277872640 len=32768 ^^^ No more partial read, directly into the write path. full stripe rmw, full stripe=389152768 opf=0x1 devid=3 type=1 offset=32768 physical=323059712 len=32768 full stripe rmw, full stripe=389152768 opf=0x1 devid=2 type=-1 offset=32768 physical=323059712 len=32768 full stripe rmw, full stripe=298844160 opf=0x1 devid=1 type=1 offset=32768 physical=22052864 len=32768 full stripe rmw, full stripe=298844160 opf=0x1 devid=3 type=-1 offset=32768 physical=277905408 len=32768
Fixes: d4e28d9b5f04 ("btrfs: raid56: make steal_rbio() subpage compatible") Signed-off-by: Qu Wenruo wqu@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/raid56.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index a5b623ee6fac..13e0bb0479e6 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c @@ -347,6 +347,24 @@ static void index_stripe_sectors(struct btrfs_raid_bio *rbio) } }
+static void steal_rbio_page(struct btrfs_raid_bio *src, + struct btrfs_raid_bio *dest, int page_nr) +{ + const u32 sectorsize = src->bioc->fs_info->sectorsize; + const u32 sectors_per_page = PAGE_SIZE / sectorsize; + int i; + + if (dest->stripe_pages[page_nr]) + __free_page(dest->stripe_pages[page_nr]); + dest->stripe_pages[page_nr] = src->stripe_pages[page_nr]; + src->stripe_pages[page_nr] = NULL; + + /* Also update the sector->uptodate bits. */ + for (i = sectors_per_page * page_nr; + i < sectors_per_page * page_nr + sectors_per_page; i++) + dest->stripe_sectors[i].uptodate = true; +} + /* * Stealing an rbio means taking all the uptodate pages from the stripe array * in the source rbio and putting them into the destination rbio. @@ -358,7 +376,6 @@ static void steal_rbio(struct btrfs_raid_bio *src, struct btrfs_raid_bio *dest) { int i; struct page *s; - struct page *d;
if (!test_bit(RBIO_CACHE_READY_BIT, &src->flags)) return; @@ -368,12 +385,7 @@ static void steal_rbio(struct btrfs_raid_bio *src, struct btrfs_raid_bio *dest) if (!s || !full_page_sectors_uptodate(src, i)) continue;
- d = dest->stripe_pages[i]; - if (d) - __free_page(d); - - dest->stripe_pages[i] = s; - src->stripe_pages[i] = NULL; + steal_rbio_page(src, dest, i); } index_stripe_sectors(dest); index_stripe_sectors(src);
From: Paul Chaignon paul@isovalent.com
[ Upstream commit 451ef36bd229f8aa329cb2258a859b4c636d08ef ]
This commit extends the ip_tunnel_key struct with a new field for the flow flags, to pass them to the route lookups. This new field will be populated and used in subsequent commits.
Signed-off-by: Paul Chaignon paul@isovalent.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Nikolay Aleksandrov razor@blackwall.org Acked-by: Martin KaFai Lau kafai@fb.com Link: https://lore.kernel.org/bpf/f8bfd4983bd06685a59b1e3ba76ca27496f51ef3.1658759... Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/ip_tunnels.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index c24fa934221d..20f60d9da741 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -54,6 +54,7 @@ struct ip_tunnel_key { __be32 label; /* Flow Label for IPv6 */ __be16 tp_src; __be16 tp_dst; + __u8 flow_flags; };
/* Flags for ip_tunnel_info mode. */
From: Paul Chaignon paul@isovalent.com
[ Upstream commit b8fff748521c7178b9a7d32b5a34a81cec8396f3 ]
Commit 26101f5ab6bd ("bpf: Add source ip in "struct bpf_tunnel_key"") added support for getting and setting the outer source IP of encapsulated packets via the bpf_skb_{get,set}_tunnel_key BPF helper. This change allows BPF programs to set any IP address as the source, including for example the IP address of a container running on the same host.
In that last case, however, the encapsulated packets are dropped when looking up the route because the source IP address isn't assigned to any interface on the host. To avoid this, we need to set the FLOWI_FLAG_ANYSRC flag.
Fixes: 26101f5ab6bd ("bpf: Add source ip in "struct bpf_tunnel_key"") Signed-off-by: Paul Chaignon paul@isovalent.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Nikolay Aleksandrov razor@blackwall.org Acked-by: Martin KaFai Lau kafai@fb.com Link: https://lore.kernel.org/bpf/76873d384e21288abe5767551a0799ac93ec07fb.1658759... Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/filter.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/core/filter.c b/net/core/filter.c index 7950f7520765..5978984b752f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4653,6 +4653,7 @@ BPF_CALL_4(bpf_skb_set_tunnel_key, struct sk_buff *, skb, } else { info->key.u.ipv4.dst = cpu_to_be32(from->remote_ipv4); info->key.u.ipv4.src = cpu_to_be32(from->local_ipv4); + info->key.flow_flags = FLOWI_FLAG_ANYSRC; }
return 0;
On Mon, Aug 15, 2022 at 07:58:13PM +0200, Greg Kroah-Hartman wrote:
From: Paul Chaignon paul@isovalent.com
[ Upstream commit b8fff748521c7178b9a7d32b5a34a81cec8396f3 ]
Commit 26101f5ab6bd ("bpf: Add source ip in "struct bpf_tunnel_key"") added support for getting and setting the outer source IP of encapsulated packets via the bpf_skb_{get,set}_tunnel_key BPF helper. This change allows BPF programs to set any IP address as the source, including for example the IP address of a container running on the same host.
In that last case, however, the encapsulated packets are dropped when looking up the route because the source IP address isn't assigned to any interface on the host. To avoid this, we need to set the FLOWI_FLAG_ANYSRC flag.
This fix will also require upstream commits 861396ac0b47 ("geneve: Use ip_tunnel_key flow flags in route lookups") and 7e2fb8bc7ef6 ("vxlan: Use ip_tunnel_key flow flags in route lookups") to have the intended effect. In short, these two commits "consume" the new field introduced in 451ef36bd229 ("ip_tunnels: Add new flow flags field to ip_tunnel_key") and populated in the present commit.
Fixes: 26101f5ab6bd ("bpf: Add source ip in "struct bpf_tunnel_key"") Signed-off-by: Paul Chaignon paul@isovalent.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Nikolay Aleksandrov razor@blackwall.org Acked-by: Martin KaFai Lau kafai@fb.com Link: https://lore.kernel.org/bpf/76873d384e21288abe5767551a0799ac93ec07fb.1658759... Signed-off-by: Sasha Levin sashal@kernel.org
net/core/filter.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/core/filter.c b/net/core/filter.c index 7950f7520765..5978984b752f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4653,6 +4653,7 @@ BPF_CALL_4(bpf_skb_set_tunnel_key, struct sk_buff *, skb, } else { info->key.u.ipv4.dst = cpu_to_be32(from->remote_ipv4); info->key.u.ipv4.src = cpu_to_be32(from->local_ipv4);
}info->key.flow_flags = FLOWI_FLAG_ANYSRC;
return 0; -- 2.35.1
On Tue, Aug 16, 2022 at 04:35:54PM +0200, Paul Chaignon wrote:
On Mon, Aug 15, 2022 at 07:58:13PM +0200, Greg Kroah-Hartman wrote:
From: Paul Chaignon paul@isovalent.com
[ Upstream commit b8fff748521c7178b9a7d32b5a34a81cec8396f3 ]
Commit 26101f5ab6bd ("bpf: Add source ip in "struct bpf_tunnel_key"") added support for getting and setting the outer source IP of encapsulated packets via the bpf_skb_{get,set}_tunnel_key BPF helper. This change allows BPF programs to set any IP address as the source, including for example the IP address of a container running on the same host.
In that last case, however, the encapsulated packets are dropped when looking up the route because the source IP address isn't assigned to any interface on the host. To avoid this, we need to set the FLOWI_FLAG_ANYSRC flag.
This fix will also require upstream commits 861396ac0b47 ("geneve: Use ip_tunnel_key flow flags in route lookups") and 7e2fb8bc7ef6 ("vxlan: Use ip_tunnel_key flow flags in route lookups") to have the intended effect. In short, these two commits "consume" the new field introduced in 451ef36bd229 ("ip_tunnels: Add new flow flags field to ip_tunnel_key") and populated in the present commit.
Ick. Is it better to just drop this commit instead? Or is it ok to also backport those 2 patches to 5.19.y?
thanks,
greg k-h
On Tue, Aug 16, 2022 at 04:47:30PM +0200, Greg Kroah-Hartman wrote:
On Tue, Aug 16, 2022 at 04:35:54PM +0200, Paul Chaignon wrote:
On Mon, Aug 15, 2022 at 07:58:13PM +0200, Greg Kroah-Hartman wrote:
From: Paul Chaignon paul@isovalent.com
[ Upstream commit b8fff748521c7178b9a7d32b5a34a81cec8396f3 ]
Commit 26101f5ab6bd ("bpf: Add source ip in "struct bpf_tunnel_key"") added support for getting and setting the outer source IP of encapsulated packets via the bpf_skb_{get,set}_tunnel_key BPF helper. This change allows BPF programs to set any IP address as the source, including for example the IP address of a container running on the same host.
In that last case, however, the encapsulated packets are dropped when looking up the route because the source IP address isn't assigned to any interface on the host. To avoid this, we need to set the FLOWI_FLAG_ANYSRC flag.
This fix will also require upstream commits 861396ac0b47 ("geneve: Use ip_tunnel_key flow flags in route lookups") and 7e2fb8bc7ef6 ("vxlan: Use ip_tunnel_key flow flags in route lookups") to have the intended effect. In short, these two commits "consume" the new field introduced in 451ef36bd229 ("ip_tunnels: Add new flow flags field to ip_tunnel_key") and populated in the present commit.
Ick. Is it better to just drop this commit instead? Or is it ok to also backport those 2 patches to 5.19.y?
It should be okay to backport those additional 2 patches to 5.19.y.
Thank you,
-- Paul
On Tue, Aug 16, 2022 at 05:07:27PM +0200, Paul Chaignon wrote:
On Tue, Aug 16, 2022 at 04:47:30PM +0200, Greg Kroah-Hartman wrote:
On Tue, Aug 16, 2022 at 04:35:54PM +0200, Paul Chaignon wrote:
On Mon, Aug 15, 2022 at 07:58:13PM +0200, Greg Kroah-Hartman wrote:
From: Paul Chaignon paul@isovalent.com
[ Upstream commit b8fff748521c7178b9a7d32b5a34a81cec8396f3 ]
Commit 26101f5ab6bd ("bpf: Add source ip in "struct bpf_tunnel_key"") added support for getting and setting the outer source IP of encapsulated packets via the bpf_skb_{get,set}_tunnel_key BPF helper. This change allows BPF programs to set any IP address as the source, including for example the IP address of a container running on the same host.
In that last case, however, the encapsulated packets are dropped when looking up the route because the source IP address isn't assigned to any interface on the host. To avoid this, we need to set the FLOWI_FLAG_ANYSRC flag.
This fix will also require upstream commits 861396ac0b47 ("geneve: Use ip_tunnel_key flow flags in route lookups") and 7e2fb8bc7ef6 ("vxlan: Use ip_tunnel_key flow flags in route lookups") to have the intended effect. In short, these two commits "consume" the new field introduced in 451ef36bd229 ("ip_tunnels: Add new flow flags field to ip_tunnel_key") and populated in the present commit.
Ick. Is it better to just drop this commit instead? Or is it ok to also backport those 2 patches to 5.19.y?
It should be okay to backport those additional 2 patches to 5.19.y.
Thanks, both queued up now.
greg k-h
From: Joanne Koong joannelkoong@gmail.com
[ Upstream commit bbd52178e249fe893ef4a9b87cde5b6c473b0a7c ]
For the case where offset + len == size, bpf_xdp_pointer should return a valid pointer to the addr because that access is permitted. We should only return NULL in the case where offset + len exceeds size.
Fixes: 3f364222d032 ("net: xdp: introduce bpf_xdp_pointer utility routine") Signed-off-by: Joanne Koong joannelkoong@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Martin KaFai Lau kafai@fb.com Acked-by: Lorenzo Bianconi lorenzo@kernel.org Link: https://lore.kernel.org/bpf/20220722220105.2065466-1-joannelkoong@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/filter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/filter.c b/net/core/filter.c index 5978984b752f..74f05ed6aff2 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3918,7 +3918,7 @@ static void *bpf_xdp_pointer(struct xdp_buff *xdp, u32 offset, u32 len) offset -= frag_size; } out: - return offset + len < size ? addr + offset : NULL; + return offset + len <= size ? addr + offset : NULL; }
BPF_CALL_4(bpf_xdp_load_bytes, struct xdp_buff *, xdp, u32, offset,
From: Liang He windhl@126.com
[ Upstream commit 6435319c34704994e19b0767f6a4e6f37439867b ]
In i2c_mux_probe(), we should call of_node_put() when breaking out of for_each_child_of_node() which will automatically increase and decrease the refcount.
Fixes: ac8498f0ce53 ("i2c: i2c-mux-gpmux: new driver") Signed-off-by: Liang He windhl@126.com Acked-by: Peter Rosin peda@axentia.se Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/muxes/i2c-mux-gpmux.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/i2c/muxes/i2c-mux-gpmux.c b/drivers/i2c/muxes/i2c-mux-gpmux.c index d3acd8d66c32..33024acaac02 100644 --- a/drivers/i2c/muxes/i2c-mux-gpmux.c +++ b/drivers/i2c/muxes/i2c-mux-gpmux.c @@ -134,6 +134,7 @@ static int i2c_mux_probe(struct platform_device *pdev) return 0;
err_children: + of_node_put(child); i2c_mux_del_adapters(muxc); err_parent: i2c_put_adapter(parent);
From: Manikanta Pubbisetty quic_mpubbise@quicinc.com
[ Upstream commit 867f4eeee862d6568a0f142d6a38f8bb724ff80e ]
Commit 56c8ccf331bd ("ath11k: Add register access logic for WCN6750") regressed QCN9074. With the above mentioned commit, writes are failing for some registers on QCN9074 although the device seems to work normally.
ath11k_pci 0000:03:00.0: failed to set pcie link register0x01e0e0a8: 0xffffffff != 0x00000010 ath11k_pci 0000:03:00.0: failed to set sysclk: -110
PCIe devices in ath11k (QCA6390, WCN6855, QCN9074, WCN6750) use window concept for register accesses. There are two schemes, dynamic & static window.
In dynamic window scheme, a single window(region in the BAR) is mapped either to CE or DP register windows at any give time. QCA6390 & WCN6855 follow this scheme for register accesses.
In static window scheme, CE & DP register windows are statically mapped to separate regions with in the BAR so that there is no switching of register windows between CE & DP register accesses. QCN9074 & WCN6750 follow this scheme although the window start offsets are different for QCN9074 & WCN6750.
QCN9074 uses 3rd & 2nd window for DP & CE register accesses respectively whereas WCN6750 uses 1st & 2nd window for DP & CE. In QCN9074, along with 2nd & 3rd windows, 1st window is also used for certain configurations which commit 56c8ccf331bd ("ath11k: Add register access logic for WCN6750") did not account for and hence the regression.
Fix this by going back to the original way of accessing the registers on QCN9074. Since this diverges from WCN6750 way of accessing registers, it is required to register window_read32/window_write32() pci_ops for WCN6750. We can also get rid of dp_window_idx & ce_window_idx members in hw_params, so remove them.
Also add a new API ath11k_pcic_register_pci_ops() for registering pci_ops to the ath11k core. This API checks for mandatory pci_ops() and reports error if those are missing. Also initialize unused pci_ops to NULL.
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
Fixes: 56c8ccf331bd ("ath11k: Add register access logic for WCN6750") Reported-by: Maxime Bizon mbizon@freebox.fr Tested-by: Maxime Bizon mbizon@freebox.fr Signed-off-by: Manikanta Pubbisetty quic_mpubbise@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220608062954.27792-1-quic_mpubbise@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/ahb.c | 52 ++++++++++++++++++- drivers/net/wireless/ath/ath11k/core.c | 14 ------ drivers/net/wireless/ath/ath11k/hw.h | 2 - drivers/net/wireless/ath/ath11k/pci.c | 70 ++++++++++++++++++++------ drivers/net/wireless/ath/ath11k/pcic.c | 57 ++++++++------------- drivers/net/wireless/ath/ath11k/pcic.h | 2 + 6 files changed, 128 insertions(+), 69 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index d7d33d5cdfc5..c47414710138 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -140,8 +140,53 @@ ath11k_ahb_get_msi_irq_wcn6750(struct ath11k_base *ab, unsigned int vector) return ab->pci.msi.irqs[vector]; }
+static inline u32 +ath11k_ahb_get_window_start_wcn6750(struct ath11k_base *ab, u32 offset) +{ + u32 window_start = 0; + + /* If offset lies within DP register range, use 1st window */ + if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) + window_start = ATH11K_PCI_WINDOW_START; + /* If offset lies within CE register range, use 2nd window */ + else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < + ATH11K_PCI_WINDOW_RANGE_MASK) + window_start = 2 * ATH11K_PCI_WINDOW_START; + + return window_start; +} + +static void +ath11k_ahb_window_write32_wcn6750(struct ath11k_base *ab, u32 offset, u32 value) +{ + u32 window_start; + + /* WCN6750 uses static window based register access*/ + window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset); + + iowrite32(value, ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); +} + +static u32 ath11k_ahb_window_read32_wcn6750(struct ath11k_base *ab, u32 offset) +{ + u32 window_start; + u32 val; + + /* WCN6750 uses static window based register access */ + window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset); + + val = ioread32(ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + return val; +} + static const struct ath11k_pci_ops ath11k_ahb_pci_ops_wcn6750 = { + .wakeup = NULL, + .release = NULL, .get_msi_irq = ath11k_ahb_get_msi_irq_wcn6750, + .window_write32 = ath11k_ahb_window_write32_wcn6750, + .window_read32 = ath11k_ahb_window_read32_wcn6750, };
static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset) @@ -971,11 +1016,16 @@ static int ath11k_ahb_probe(struct platform_device *pdev) }
ab->hif.ops = hif_ops; - ab->pci.ops = pci_ops; ab->pdev = pdev; ab->hw_rev = hw_rev; platform_set_drvdata(pdev, ab);
+ ret = ath11k_pcic_register_pci_ops(ab, pci_ops); + if (ret) { + ath11k_err(ab, "failed to register PCI ops: %d\n", ret); + goto err_core_free; + } + ret = ath11k_core_pre_init(ab); if (ret) goto err_core_free; diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index c8e0bc935838..6ddc698f4a2d 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -107,8 +107,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = true, .static_window_map = false, .hybrid_bus_type = false, - .dp_window_idx = 0, - .ce_window_idx = 0, .fixed_fw_mem = false, .support_off_channel_tx = false, }, @@ -183,8 +181,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = true, .static_window_map = false, .hybrid_bus_type = false, - .dp_window_idx = 0, - .ce_window_idx = 0, .fixed_fw_mem = false, .support_off_channel_tx = false, }, @@ -258,8 +254,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = false, .hybrid_bus_type = false, - .dp_window_idx = 0, - .ce_window_idx = 0, .fixed_fw_mem = false, .support_off_channel_tx = true, }, @@ -333,8 +327,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = true, .hybrid_bus_type = false, - .dp_window_idx = 3, - .ce_window_idx = 2, .fixed_fw_mem = false, .support_off_channel_tx = false, }, @@ -408,8 +400,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = false, .hybrid_bus_type = false, - .dp_window_idx = 0, - .ce_window_idx = 0, .fixed_fw_mem = false, .support_off_channel_tx = true, }, @@ -482,8 +472,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = false, .hybrid_bus_type = false, - .dp_window_idx = 0, - .ce_window_idx = 0, .fixed_fw_mem = false, .support_off_channel_tx = true, }, @@ -556,8 +544,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = true, .hybrid_bus_type = true, - .dp_window_idx = 1, - .ce_window_idx = 2, .fixed_fw_mem = true, .support_off_channel_tx = false, }, diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 77dc5c851c9b..84c284fab5db 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -201,8 +201,6 @@ struct ath11k_hw_params { bool fixed_mem_region; bool static_window_map; bool hybrid_bus_type; - u8 dp_window_idx; - u8 ce_window_idx; bool fixed_fw_mem; bool support_off_channel_tx; }; diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 487a303b3077..5bd34a6273d9 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -50,6 +50,22 @@ static void ath11k_pci_bus_release(struct ath11k_base *ab) mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); }
+static u32 ath11k_pci_get_window_start(struct ath11k_base *ab, u32 offset) +{ + if (!ab->hw_params.static_window_map) + return ATH11K_PCI_WINDOW_START; + + if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) + /* if offset lies within DP register range, use 3rd window */ + return 3 * ATH11K_PCI_WINDOW_START; + else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < + ATH11K_PCI_WINDOW_RANGE_MASK) + /* if offset lies within CE register range, use 2nd window */ + return 2 * ATH11K_PCI_WINDOW_START; + else + return ATH11K_PCI_WINDOW_START; +} + static inline void ath11k_pci_select_window(struct ath11k_pci *ab_pci, u32 offset) { struct ath11k_base *ab = ab_pci->ab; @@ -70,26 +86,39 @@ static void ath11k_pci_window_write32(struct ath11k_base *ab, u32 offset, u32 value) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - u32 window_start = ATH11K_PCI_WINDOW_START; + u32 window_start;
- spin_lock_bh(&ab_pci->window_lock); - ath11k_pci_select_window(ab_pci, offset); - iowrite32(value, ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - spin_unlock_bh(&ab_pci->window_lock); + window_start = ath11k_pci_get_window_start(ab, offset); + + if (window_start == ATH11K_PCI_WINDOW_START) { + spin_lock_bh(&ab_pci->window_lock); + ath11k_pci_select_window(ab_pci, offset); + iowrite32(value, ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + spin_unlock_bh(&ab_pci->window_lock); + } else { + iowrite32(value, ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + } }
static u32 ath11k_pci_window_read32(struct ath11k_base *ab, u32 offset) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - u32 window_start = ATH11K_PCI_WINDOW_START; - u32 val; + u32 window_start, val;
- spin_lock_bh(&ab_pci->window_lock); - ath11k_pci_select_window(ab_pci, offset); - val = ioread32(ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - spin_unlock_bh(&ab_pci->window_lock); + window_start = ath11k_pci_get_window_start(ab, offset); + + if (window_start == ATH11K_PCI_WINDOW_START) { + spin_lock_bh(&ab_pci->window_lock); + ath11k_pci_select_window(ab_pci, offset); + val = ioread32(ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + spin_unlock_bh(&ab_pci->window_lock); + } else { + val = ioread32(ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + }
return val; } @@ -110,6 +139,8 @@ static const struct ath11k_pci_ops ath11k_pci_ops_qca6390 = { };
static const struct ath11k_pci_ops ath11k_pci_ops_qcn9074 = { + .wakeup = NULL, + .release = NULL, .get_msi_irq = ath11k_pci_get_msi_irq, .window_write32 = ath11k_pci_window_write32, .window_read32 = ath11k_pci_window_read32, @@ -697,6 +728,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev, struct ath11k_base *ab; struct ath11k_pci *ab_pci; u32 soc_hw_version_major, soc_hw_version_minor, addr; + const struct ath11k_pci_ops *pci_ops; int ret;
ab = ath11k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH11K_BUS_PCI); @@ -754,10 +786,10 @@ static int ath11k_pci_probe(struct pci_dev *pdev, goto err_pci_free_region; }
- ab->pci.ops = &ath11k_pci_ops_qca6390; + pci_ops = &ath11k_pci_ops_qca6390; break; case QCN9074_DEVICE_ID: - ab->pci.ops = &ath11k_pci_ops_qcn9074; + pci_ops = &ath11k_pci_ops_qcn9074; ab->hw_rev = ATH11K_HW_QCN9074_HW10; break; case WCN6855_DEVICE_ID: @@ -787,7 +819,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev, goto err_pci_free_region; }
- ab->pci.ops = &ath11k_pci_ops_qca6390; + pci_ops = &ath11k_pci_ops_qca6390; break; default: dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n", @@ -796,6 +828,12 @@ static int ath11k_pci_probe(struct pci_dev *pdev, goto err_pci_free_region; }
+ ret = ath11k_pcic_register_pci_ops(ab, pci_ops); + if (ret) { + ath11k_err(ab, "failed to register PCI ops: %d\n", ret); + goto err_pci_free_region; + } + ret = ath11k_pcic_init_msi_config(ab); if (ret) { ath11k_err(ab, "failed to init msi config: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c index cf12b98c480d..1adf20ebef27 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.c +++ b/drivers/net/wireless/ath/ath11k/pcic.c @@ -140,23 +140,8 @@ int ath11k_pcic_init_msi_config(struct ath11k_base *ab) } EXPORT_SYMBOL(ath11k_pcic_init_msi_config);
-static inline u32 ath11k_pcic_get_window_start(struct ath11k_base *ab, - u32 offset) -{ - u32 window_start = 0; - - if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) - window_start = ab->hw_params.dp_window_idx * ATH11K_PCI_WINDOW_START; - else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < - ATH11K_PCI_WINDOW_RANGE_MASK) - window_start = ab->hw_params.ce_window_idx * ATH11K_PCI_WINDOW_START; - - return window_start; -} - void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) { - u32 window_start; int ret = 0;
/* for offset beyond BAR + 4K - 32, may @@ -166,15 +151,10 @@ void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->wakeup) ret = ab->pci.ops->wakeup(ab);
- if (offset < ATH11K_PCI_WINDOW_START) { + if (offset < ATH11K_PCI_WINDOW_START) iowrite32(value, ab->mem + offset); - } else if (ab->hw_params.static_window_map) { - window_start = ath11k_pcic_get_window_start(ab, offset); - iowrite32(value, ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - } else if (ab->pci.ops->window_write32) { + else ab->pci.ops->window_write32(ab, offset, value); - }
if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) && offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->release && @@ -185,9 +165,8 @@ EXPORT_SYMBOL(ath11k_pcic_write32);
u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) { - u32 val = 0; - u32 window_start; int ret = 0; + u32 val;
/* for offset beyond BAR + 4K - 32, may * need to wakeup the device to access. @@ -196,15 +175,10 @@ u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->wakeup) ret = ab->pci.ops->wakeup(ab);
- if (offset < ATH11K_PCI_WINDOW_START) { + if (offset < ATH11K_PCI_WINDOW_START) val = ioread32(ab->mem + offset); - } else if (ab->hw_params.static_window_map) { - window_start = ath11k_pcic_get_window_start(ab, offset); - val = ioread32(ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - } else if (ab->pci.ops->window_read32) { + else val = ab->pci.ops->window_read32(ab, offset); - }
if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) && offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->release && @@ -516,11 +490,6 @@ static irqreturn_t ath11k_pcic_ext_interrupt_handler(int irq, void *arg) static int ath11k_pcic_get_msi_irq(struct ath11k_base *ab, unsigned int vector) { - if (!ab->pci.ops->get_msi_irq) { - WARN_ONCE(1, "get_msi_irq pci op not defined"); - return -EOPNOTSUPP; - } - return ab->pci.ops->get_msi_irq(ab, vector); }
@@ -746,3 +715,19 @@ int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, return 0; } EXPORT_SYMBOL(ath11k_pcic_map_service_to_pipe); + +int ath11k_pcic_register_pci_ops(struct ath11k_base *ab, + const struct ath11k_pci_ops *pci_ops) +{ + if (!pci_ops) + return 0; + + /* Return error if mandatory pci_ops callbacks are missing */ + if (!pci_ops->get_msi_irq || !pci_ops->window_write32 || + !pci_ops->window_read32) + return -EINVAL; + + ab->pci.ops = pci_ops; + return 0; +} +EXPORT_SYMBOL(ath11k_pcic_register_pci_ops); diff --git a/drivers/net/wireless/ath/ath11k/pcic.h b/drivers/net/wireless/ath/ath11k/pcic.h index c53d86289a8e..0afbb34510db 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.h +++ b/drivers/net/wireless/ath/ath11k/pcic.h @@ -43,4 +43,6 @@ int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab); void ath11k_pcic_ce_irq_disable_sync(struct ath11k_base *ab); int ath11k_pcic_init_msi_config(struct ath11k_base *ab); +int ath11k_pcic_register_pci_ops(struct ath11k_base *ab, + const struct ath11k_pci_ops *pci_ops); #endif
From: Ammar Faizi ammarfaizi2@gnuweeb.org
[ Upstream commit d578e0af3a003736f6c440188b156483d451b329 ]
Commit 7a4836560a61 changes simple_write_to_buffer() with memdup_user() but it forgets to change the value to be returned that came from simple_write_to_buffer() call. It results in the following warning:
warning: variable 'rc' is uninitialized when used here [-Wuninitialized] return rc; ^~
Remove rc variable and just return the passed in length if the memdup_user() succeeds.
Cc: Dan Carpenter dan.carpenter@oracle.com Reported-by: kernel test robot lkp@intel.com Fixes: 7a4836560a6198d245d5732e26f94898b12eb760 ("wifi: wil6210: debugfs: fix info leak in wil_write_file_wmi()") Fixes: ff974e4083341383d3dd4079e52ed30f57f376f0 ("wil6210: debugfs interface to send raw WMI command") Signed-off-by: Ammar Faizi ammarfaizi2@gnuweeb.org Reviewed-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220724202452.61846-1-ammar.faizi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wil6210/debugfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index fe84362718de..04d1aa0e2d35 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -1010,7 +1010,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf, void *cmd; int cmdlen = len - sizeof(struct wmi_cmd_hdr); u16 cmdid; - int rc, rc1; + int rc1;
if (cmdlen < 0 || *ppos != 0) return -EINVAL; @@ -1027,7 +1027,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
wil_info(wil, "0x%04x[%d] -> %d\n", cmdid, cmdlen, rc1);
- return rc; + return len; }
static const struct file_operations fops_wmi = {
From: Jose Ignacio Tornos Martinez jtornosm@redhat.com
[ Upstream commit 14a3aacf517a9de725dd3219dbbcf741e31763c4 ]
After successfull station association, if station queues are disabled for some reason, the related lists are not emptied. So if some new element is added to the list in iwl_mvm_mac_wake_tx_queue, it can match with the old one and produce a BUG like this:
[ 46.535263] list_add corruption. prev->next should be next (ffff94c1c318a360), but was 0000000000000000. (prev=ffff94c1d02d3388). [ 46.535283] ------------[ cut here ]------------ [ 46.535284] kernel BUG at lib/list_debug.c:26! [ 46.535290] invalid opcode: 0000 [#1] PREEMPT SMP PTI [ 46.585304] CPU: 0 PID: 623 Comm: wpa_supplicant Not tainted 5.19.0-rc3+ #1 [ 46.592380] Hardware name: Dell Inc. Inspiron 660s/0478VN , BIOS A07 08/24/2012 [ 46.600336] RIP: 0010:__list_add_valid.cold+0x3d/0x3f [ 46.605475] Code: f2 4c 89 c1 48 89 fe 48 c7 c7 c8 40 67 93 e8 20 cc fd ff 0f 0b 48 89 d1 4c 89 c6 4c 89 ca 48 c7 c7 70 40 67 93 e8 09 cc fd ff <0f> 0b 48 89 fe 48 c7 c7 00 41 67 93 e8 f8 cb fd ff 0f 0b 48 89 d1 [ 46.624469] RSP: 0018:ffffb20800ab76d8 EFLAGS: 00010286 [ 46.629854] RAX: 0000000000000075 RBX: ffff94c1c318a0e0 RCX: 0000000000000000 [ 46.637105] RDX: 0000000000000201 RSI: ffffffff9365e100 RDI: 00000000ffffffff [ 46.644356] RBP: ffff94c1c5f43370 R08: 0000000000000075 R09: 3064316334396666 [ 46.651607] R10: 3364323064316334 R11: 39666666663d7665 R12: ffff94c1c5f43388 [ 46.658857] R13: ffff94c1d02d3388 R14: ffff94c1c318a360 R15: ffff94c1cf2289c0 [ 46.666108] FS: 00007f65634ff7c0(0000) GS:ffff94c1da200000(0000) knlGS:0000000000000000 [ 46.674331] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 46.680170] CR2: 00007f7dfe984460 CR3: 000000010e894003 CR4: 00000000000606f0 [ 46.687422] Call Trace: [ 46.689906] <TASK> [ 46.691950] iwl_mvm_mac_wake_tx_queue+0xec/0x15c [iwlmvm] [ 46.697601] ieee80211_queue_skb+0x4b3/0x720 [mac80211] [ 46.702973] ? sta_info_get+0x46/0x60 [mac80211] [ 46.707703] ieee80211_tx+0xad/0x110 [mac80211] [ 46.712355] __ieee80211_tx_skb_tid_band+0x71/0x90 [mac80211] ...
In order to avoid this problem, we must also remove the related lists when station queues are disabled.
Fixes: cfbc6c4c5b91c ("iwlwifi: mvm: support mac80211 TXQs model") Reported-by: Takayuki Nagata tnagata@redhat.com Reported-by: Petr Stourac pstourac@redhat.com Tested-by: Petr Stourac pstourac@redhat.com Signed-off-by: Jose Ignacio Tornos Martinez jtornosm@redhat.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220719153542.81466-1-jtornosm@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index bbb1522e7280..ae23950d566f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1861,6 +1861,7 @@ static void iwl_mvm_disable_sta_queues(struct iwl_mvm *mvm, iwl_mvm_txq_from_mac80211(sta->txq[i]);
mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE; + list_del_init(&mvmtxq->list); } }
From: Hangyu Hua hbh25y@gmail.com
[ Upstream commit 6fd57e1d120bf13d4dc6c200a7cf914e6347a316 ]
usb_get_dev will be called before lbs_get_firmware_async which means that usb_put_dev need to be called when lbs_get_firmware_async fails.
Fixes: ce84bb69f50e ("libertas USB: convert to asynchronous firmware loading") Signed-off-by: Hangyu Hua hbh25y@gmail.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220620092350.39960-1-hbh25y@gmail.com Link: https://lore.kernel.org/r/20220622113402.16969-1-colin.i.king@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/libertas/if_usb.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c index 5d6dc1dd050d..32fdc4150b60 100644 --- a/drivers/net/wireless/marvell/libertas/if_usb.c +++ b/drivers/net/wireless/marvell/libertas/if_usb.c @@ -287,6 +287,7 @@ static int if_usb_probe(struct usb_interface *intf, return 0;
err_get_fw: + usb_put_dev(udev); lbs_remove_card(priv); err_add_card: if_usb_reset_device(cardp);
From: Jernej Skrabec jernej.skrabec@gmail.com
[ Upstream commit 143201a6435bf65f0115435e9dc6d95c66b908e9 ]
Not all DPB entries will be used most of the time. Unused entries will thus have invalid timestamps. They will produce negative buffer index which is not specifically handled. This works just by chance in current code. It will even produce bogus pointer, but since it's not used, it won't do any harm.
Let's fix that brittle design by skipping writing DPB entry altogether if timestamp is invalid.
Fixes: 86caab29da78 ("media: cedrus: Add HEVC/H.265 decoding support") Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Reviewed-by: Ezequiel Garcia ezequiel@vanguardiasur.com.ar Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c index 2f6404fccd5a..04419381ea56 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c @@ -147,6 +147,9 @@ static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx, dpb[i].pic_order_cnt_val };
+ if (buffer_index < 0) + continue; + cedrus_h265_frame_info_write_single(ctx, i, dpb[i].field_pic, pic_order_cnt, buffer_index);
From: Ezequiel Garcia ezequiel@vanguardiasur.com.ar
[ Upstream commit df9ec2fc8e70e01532fd9161cd98711969561ff6 ]
Currently, the driver tries to validat the HEVC SPS against the CAPTURE queue format (i.e. the decoded format). This is not correct, because typically the SPS control is set before the CAPTURE queue is negotiated.
Fixes: 135ad96cb4d6b ("media: hantro: Be more accurate on pixel formats step_width constraints") Signed-off-by: Ezequiel Garcia ezequiel@vanguardiasur.com.ar Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/hantro/hantro_drv.c | 12 ++++++------ drivers/staging/media/hantro/hantro_hevc.c | 9 +-------- drivers/staging/media/hantro/hantro_hw.h | 1 - 3 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index 01d33dcb0467..ac232b5f7825 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -253,11 +253,6 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
static int hantro_try_ctrl(struct v4l2_ctrl *ctrl) { - struct hantro_ctx *ctx; - - ctx = container_of(ctrl->handler, - struct hantro_ctx, ctrl_handler); - if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) { const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
@@ -273,7 +268,12 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl) } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_SPS) { const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
- return hantro_hevc_validate_sps(ctx, sps); + if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) + /* Luma and chroma bit depth mismatch */ + return -EINVAL; + if (sps->bit_depth_luma_minus8 != 0) + /* Only 8-bit is supported */ + return -EINVAL; } else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) { const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame;
diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c index 4f7e2acb46ec..df1f81952bba 100644 --- a/drivers/staging/media/hantro/hantro_hevc.c +++ b/drivers/staging/media/hantro/hantro_hevc.c @@ -154,15 +154,8 @@ static int tile_buffer_reallocate(struct hantro_ctx *ctx) return -ENOMEM; }
-int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps) +static int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps) { - if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) - /* Luma and chroma bit depth mismatch */ - return -EINVAL; - if (sps->bit_depth_luma_minus8 != 0) - /* Only 8-bit is supported */ - return -EINVAL; - /* * for tile pixel format check if the width and height match * hardware constraints diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 33d156ccbfeb..77769d2bb38e 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -359,7 +359,6 @@ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx); void hantro_hevc_ref_init(struct hantro_ctx *ctx); dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, s32 poc); int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr); -int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps);
static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension)
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 06ac561fb0edf868f7b292fb4a3c8ffbbb1e14bb ]
The "ret" variable needs to be signed for the error handling to work.
Fixes: 2ca97adccdc9 ("drm/amd/display: Add Synaptics Fifo Reset Workaround") Signed-off-by: Dan Carpenter dan.carpenter@oracle.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_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 7c799ddc1d27..82c04af09d18 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -571,7 +571,7 @@ static bool execute_synaptics_rc_command(struct drm_dp_aux *aux, unsigned char rc_cmd = 0; unsigned char rc_result = 0xFF; unsigned char i = 0; - uint8_t ret = 0; + int ret;
if (is_write_cmd) { // write rc data
From: Gal Pressman gal@nvidia.com
[ Upstream commit 115d9f95ea7ab780ef315dc356bebba2e07cb731 ]
The driver reports whether TX/RX TLS device offloads are supported, but not which ciphers/versions, these should be handled by returning -EOPNOTSUPP when .tls_dev_add() is called.
Remove the WARN_ON kernel trace when the driver gets a request to offload a cipher/version that is not supported as it is expected.
Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Gal Pressman gal@nvidia.com Reviewed-by: Tariq Toukan tariqt@nvidia.com Reviewed-by: Maxim Mikityanskiy maximmi@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_accel/ktls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c index 814f2a56f633..30a70d139046 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c @@ -54,7 +54,7 @@ static int mlx5e_ktls_add(struct net_device *netdev, struct sock *sk, struct mlx5_core_dev *mdev = priv->mdev; int err;
- if (WARN_ON(!mlx5e_ktls_type_check(mdev, crypto_info))) + if (!mlx5e_ktls_type_check(mdev, crypto_info)) return -EOPNOTSUPP;
if (direction == TLS_OFFLOAD_CTX_DIR_TX)
From: Maor Dickman maord@nvidia.com
[ Upstream commit 903f2194f74bbd289f3170114035d472a36a8ab4 ]
The cited commit changed CT to use multi table actions post act infrastructure instead of using it own post act infrastructure, this broke decap during VF tunnel offload (Stack devices) with CT due to wrong match on in_port metadata in the post act table. This changed only broke VF tunnel offload because it modify the packet in_port metadata to be VF metadata and it isn't propagate the post act creation.
Fixed by modify post act rules to match only on fte_id and not match on in_port metadata which isn't needed.
Fixes: a81283263bb0 ("net/mlx5e: Use multi table support for CT and sample actions") Signed-off-by: Maor Dickman maord@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/post_act.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c index dea137dd744b..2b64dd557b5d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c @@ -128,6 +128,7 @@ mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *at post_attr->inner_match_level = MLX5_MATCH_NONE; post_attr->outer_match_level = MLX5_MATCH_NONE; post_attr->action &= ~MLX5_FLOW_CONTEXT_ACTION_DECAP; + post_attr->flags |= MLX5_ATTR_FLAG_NO_IN_PORT;
handle->ns_type = post_act->ns_type; /* Splits were handled before post action */
From: Maxim Mikityanskiy maximmi@nvidia.com
[ Upstream commit 562696c3c62c7c23dd896e9447252ce9268cb812 ]
MLX5E_MAX_RQ_NUM_MTTS should be the maximum value, so that MLX5_MTT_OCTW(MLX5E_MAX_RQ_NUM_MTTS) fits into u16. The current value of 1 << 17 results in MLX5_MTT_OCTW(1 << 17) = 1 << 16, which doesn't fit into u16. This commit replaces it with the maximum value that still fits u16.
Fixes: 73281b78a37a ("net/mlx5e: Derive Striding RQ size from MTU") Signed-off-by: Maxim Mikityanskiy maximmi@nvidia.com Reviewed-by: Tariq Toukan tariqt@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.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index b6c15efe92ad..f794ffaf1e04 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -109,7 +109,7 @@ struct page_pool; #define MLX5E_REQUIRED_WQE_MTTS (MLX5_ALIGN_MTTS(MLX5_MPWRQ_PAGES_PER_WQE + 1)) #define MLX5E_REQUIRED_MTTS(wqes) (wqes * MLX5E_REQUIRED_WQE_MTTS) #define MLX5E_MAX_RQ_NUM_MTTS \ - ((1 << 16) * 2) /* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */ + (ALIGN_DOWN(U16_MAX, 4) * 2) /* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */ #define MLX5E_ORDER2_MAX_PACKET_MTU (order_base_2(10 * 1024)) #define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW \ (ilog2(MLX5E_MAX_RQ_NUM_MTTS / MLX5E_REQUIRED_WQE_MTTS))
From: Maxim Mikityanskiy maximmi@nvidia.com
[ Upstream commit 52586d2f56b3e4f528ca7268d65074e92c936681 ]
ICOSQ is used to post UMR WQEs for both regular RQ and XSK RQ. However, space in ICOSQ is reserved only for the regular RQ, which may cause ICOSQ overflows when using XSK (the most risk is on activating channels).
This commit fixes the issue by reserving space for XSK UMR WQEs as well. As XSK may be enabled without restarting the channel and recreating the ICOSQ, this space is reserved unconditionally.
Fixes: db05815b36cb ("net/mlx5e: Add XSK zero-copy support") Signed-off-by: Maxim Mikityanskiy maximmi@nvidia.com Reviewed-by: Tariq Toukan tariqt@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/params.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c index 3c1edfa33aa7..e025040350ba 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c @@ -790,8 +790,20 @@ static u8 mlx5e_build_icosq_log_wq_sz(struct mlx5_core_dev *mdev, return MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
wqebbs = MLX5E_UMR_WQEBBS * BIT(mlx5e_get_rq_log_wq_sz(rqp->rqc)); + + /* If XDP program is attached, XSK may be turned on at any time without + * restarting the channel. ICOSQ must be big enough to fit UMR WQEs of + * both regular RQ and XSK RQ. + * Although mlx5e_mpwqe_get_log_rq_size accepts mlx5e_xsk_param, it + * doesn't affect its return value, as long as params->xdp_prog != NULL, + * so we can just multiply by 2. + */ + if (params->xdp_prog) + wqebbs *= 2; + if (params->packet_merge.type == MLX5E_PACKET_MERGE_SHAMPO) wqebbs += mlx5e_shampo_icosq_sz(mdev, params, rqp); + return max_t(u8, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE, order_base_2(wqebbs)); }
From: Maxim Mikityanskiy maximmi@nvidia.com
[ Upstream commit 677e78c8d44f326a73a77d71acf3a49ea562c1d9 ]
Before commit 76c31e5f7585 ("net/mlx5e: Use FW limitation for max MPW WQEBBs"), the maximum size of MPWQE in WQEBBs was hardcoded as a driver constant. That commit started using the firmware capability that can further limit the size, however, it unintentionally changed a few things:
1. The calculation of MLX5E_MAX_KLM_PER_WQE used the size in DS, which was replaced by the size in WQEBBs, making the resulting value 4 times smaller.
2. MLX5E_TX_MPW_MAX_WQEBBS used to be aligned to the cache line size (either 64 or 128 bytes, i.e. 1 or 2 WQEBBs), but it's no longer the case if the firmware capability is smaller than the driver maximum.
Fix both issues by using the correct units for MLX5E_MAX_KLM_PER_WQE and by aligning mlx5e_get_sw_max_sq_mpw_wqebbs after taking the minimum.
Besides fixing the arithmetics in calculation of MLX5E_MAX_KLM_PER_WQE, also use appropriate constants: `size of BSF * num of DS per WQEBB * number of WQEBBs` (the calculation before the blamed commit) doesn't make much sense to calculate the WQE size in bytes, so just use `size of WQEBB * number of WQEBBs`.
While at it, replace the types that hold the number of WQEBBs by u8. These values don't exceed 16, and it allows to fill holes in two structs.
Fixes: 76c31e5f7585 ("net/mlx5e: Use FW limitation for max MPW WQEBBs") Signed-off-by: Maxim Mikityanskiy maximmi@nvidia.com Reviewed-by: Tariq Toukan tariqt@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.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index f794ffaf1e04..29b10ef787b9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -174,8 +174,8 @@ struct page_pool; ALIGN_DOWN(MLX5E_KLM_MAX_ENTRIES_PER_WQE(wqe_size), MLX5_UMR_KLM_ALIGNMENT)
#define MLX5E_MAX_KLM_PER_WQE(mdev) \ - MLX5E_KLM_ENTRIES_PER_WQE(mlx5e_get_sw_max_sq_mpw_wqebbs(mlx5e_get_max_sq_wqebbs(mdev)) \ - << MLX5_MKEY_BSF_OCTO_SIZE) + MLX5E_KLM_ENTRIES_PER_WQE(MLX5_SEND_WQE_BB * \ + mlx5e_get_sw_max_sq_mpw_wqebbs(mlx5e_get_max_sq_wqebbs(mdev)))
#define MLX5E_MSG_LEVEL NETIF_MSG_LINK
@@ -233,7 +233,7 @@ static inline u16 mlx5e_get_max_sq_wqebbs(struct mlx5_core_dev *mdev) MLX5_CAP_GEN(mdev, max_wqe_sz_sq) / MLX5_SEND_WQE_BB); }
-static inline u16 mlx5e_get_sw_max_sq_mpw_wqebbs(u16 max_sq_wqebbs) +static inline u8 mlx5e_get_sw_max_sq_mpw_wqebbs(u8 max_sq_wqebbs) { /* The return value will be multiplied by MLX5_SEND_WQEBB_NUM_DS. * Since max_sq_wqebbs may be up to MLX5_SEND_WQE_MAX_WQEBBS == 16, @@ -242,11 +242,12 @@ static inline u16 mlx5e_get_sw_max_sq_mpw_wqebbs(u16 max_sq_wqebbs) * than MLX5_SEND_WQE_MAX_WQEBBS to let a full-session WQE be * cache-aligned. */ -#if L1_CACHE_BYTES < 128 - return min_t(u16, max_sq_wqebbs, MLX5_SEND_WQE_MAX_WQEBBS - 1); -#else - return min_t(u16, max_sq_wqebbs, MLX5_SEND_WQE_MAX_WQEBBS - 2); + u8 wqebbs = min_t(u8, max_sq_wqebbs, MLX5_SEND_WQE_MAX_WQEBBS - 1); + +#if L1_CACHE_BYTES >= 128 + wqebbs = ALIGN_DOWN(wqebbs, 2); #endif + return wqebbs; }
struct mlx5e_tx_wqe { @@ -455,7 +456,7 @@ struct mlx5e_txqsq { struct netdev_queue *txq; u32 sqn; u16 stop_room; - u16 max_sq_mpw_wqebbs; + u8 max_sq_mpw_wqebbs; u8 min_inline_mode; struct device *pdev; __be32 mkey_be; @@ -570,7 +571,7 @@ struct mlx5e_xdpsq { struct device *pdev; __be32 mkey_be; u16 stop_room; - u16 max_sq_mpw_wqebbs; + u8 max_sq_mpw_wqebbs; u8 min_inline_mode; unsigned long state; unsigned int hw_mtu;
From: Vlad Buslov vladbu@nvidia.com
[ Upstream commit c0063a43700fa8c98cac2637aa1afcf40bb9e403 ]
While extending available range of supported chains/prios referenced commit also modified slow path rules to go to FT chain instead of actual slow FDB. However neither of existing users of the MLX5_ATTR_FLAG_SLOW_PATH flag (tunnel encap entries with invalid encap and flows with trap action) need to match on FT chain. After bridge offload was implemented packets of such flows can also be matched by bridge priority tables which is undesirable. Restore slow path flows implementation to redirect packets to slow_fdb.
Fixes: 278d51f24330 ("net/mlx5: E-Switch, Increase number of chains and priorities") Signed-off-by: Vlad Buslov vladbu@nvidia.com Reviewed-by: Roi Dayan roid@nvidia.com Reviewed-by: Paul Blakey paulb@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../mellanox/mlx5/core/eswitch_offloads.c | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 2ce3728576d1..eb79810199d3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -230,10 +230,8 @@ esw_setup_ft_dest(struct mlx5_flow_destination *dest, }
static void -esw_setup_slow_path_dest(struct mlx5_flow_destination *dest, - struct mlx5_flow_act *flow_act, - struct mlx5_fs_chains *chains, - int i) +esw_setup_accept_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *flow_act, + struct mlx5_fs_chains *chains, int i) { if (mlx5_chains_ignore_flow_level_supported(chains)) flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL; @@ -241,6 +239,16 @@ esw_setup_slow_path_dest(struct mlx5_flow_destination *dest, dest[i].ft = mlx5_chains_get_tc_end_ft(chains); }
+static void +esw_setup_slow_path_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *flow_act, + struct mlx5_eswitch *esw, int i) +{ + if (MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, ignore_flow_level)) + flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL; + dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; + dest[i].ft = esw->fdb_table.offloads.slow_fdb; +} + static int esw_setup_chain_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *flow_act, @@ -475,8 +483,11 @@ esw_setup_dests(struct mlx5_flow_destination *dest, } else if (attr->dest_ft) { esw_setup_ft_dest(dest, flow_act, esw, attr, spec, *i); (*i)++; - } else if (mlx5e_tc_attr_flags_skip(attr->flags)) { - esw_setup_slow_path_dest(dest, flow_act, chains, *i); + } else if (attr->flags & MLX5_ATTR_FLAG_SLOW_PATH) { + esw_setup_slow_path_dest(dest, flow_act, esw, *i); + (*i)++; + } else if (attr->flags & MLX5_ATTR_FLAG_ACCEPT) { + esw_setup_accept_dest(dest, flow_act, chains, *i); (*i)++; } else if (attr->dest_chain) { err = esw_setup_chain_dest(dest, flow_act, chains, attr->dest_chain,
From: Maher Sanalla msanalla@nvidia.com
[ Upstream commit a6e9085d791f8306084fd5bc44dd3fdd4e1ac27b ]
The cited commit limited log_max_qp to be 17 due to FW capabilities. Recently, it turned out that there are old FW versions that supported more than 17, so the cited commit caused a degradation.
Thus, set the maximum log_max_qp back to 18 as it was before the cited commit.
Fixes: 7f839965b2d7 ("net/mlx5: Update log_max_qp value to be 17 at most") Signed-off-by: Maher Sanalla msanalla@nvidia.com Reviewed-by: Maor Gottlieb maorg@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index c9b4e50a593e..95f26624b57c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -524,7 +524,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
/* Check log_max_qp from HCA caps to set in current profile */ if (prof->log_max_qp == LOG_MAX_SUPPORTED_QPS) { - prof->log_max_qp = min_t(u8, 17, MLX5_CAP_GEN_MAX(dev, log_max_qp)); + prof->log_max_qp = min_t(u8, 18, MLX5_CAP_GEN_MAX(dev, log_max_qp)); } else if (MLX5_CAP_GEN_MAX(dev, log_max_qp) < prof->log_max_qp) { mlx5_core_warn(dev, "log_max_qp value in current profile is %d, changing it to HCA capability limit (%d)\n", prof->log_max_qp,
From: Yevgeny Kliteynik kliteyn@nvidia.com
[ Upstream commit 62d2664351ef37da34f6f3a3fd8ab34257d6fe30 ]
Fix several issues in SMFS steering info dump: - Fix outdated macro value for matcher mask in the SMFS debug dump format. The existing value denotes the old format of the matcher mask, as it was used during the early stages of development, and it results in wrong parsing by the steering dump parser - wrong fields are shown in the parsed output. - Add the missing destination table to the dumped action. The missing dest table handle breaks the ability to associate between the "go to table" action and the actual table in the steering info.
Fixes: 9222f0b27da2 ("net/mlx5: DR, Add support for dumping steering info") Signed-off-by: Yevgeny Kliteynik kliteyn@nvidia.com Signed-off-by: Muhammad Sammar muhammads@nvidia.com Reviewed-by: Alex Vesker valex@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../ethernet/mellanox/mlx5/core/steering/dr_dbg.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_dbg.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_dbg.c index d5998ef59be4..7adcf0eec13b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_dbg.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_dbg.c @@ -21,10 +21,11 @@ enum dr_dump_rec_type { DR_DUMP_REC_TYPE_TABLE_TX = 3102,
DR_DUMP_REC_TYPE_MATCHER = 3200, - DR_DUMP_REC_TYPE_MATCHER_MASK = 3201, + DR_DUMP_REC_TYPE_MATCHER_MASK_DEPRECATED = 3201, DR_DUMP_REC_TYPE_MATCHER_RX = 3202, DR_DUMP_REC_TYPE_MATCHER_TX = 3203, DR_DUMP_REC_TYPE_MATCHER_BUILDER = 3204, + DR_DUMP_REC_TYPE_MATCHER_MASK = 3205,
DR_DUMP_REC_TYPE_RULE = 3300, DR_DUMP_REC_TYPE_RULE_RX_ENTRY_V0 = 3301, @@ -114,13 +115,15 @@ dr_dump_rule_action_mem(struct seq_file *file, const u64 rule_id, break; case DR_ACTION_TYP_FT: if (action->dest_tbl->is_fw_tbl) - seq_printf(file, "%d,0x%llx,0x%llx,0x%x\n", + seq_printf(file, "%d,0x%llx,0x%llx,0x%x,0x%x\n", DR_DUMP_REC_TYPE_ACTION_FT, action_id, - rule_id, action->dest_tbl->fw_tbl.id); + rule_id, action->dest_tbl->fw_tbl.id, + -1); else - seq_printf(file, "%d,0x%llx,0x%llx,0x%x\n", + seq_printf(file, "%d,0x%llx,0x%llx,0x%x,0x%llx\n", DR_DUMP_REC_TYPE_ACTION_FT, action_id, - rule_id, action->dest_tbl->tbl->table_id); + rule_id, action->dest_tbl->tbl->table_id, + DR_DBG_PTR_TO_ID(action->dest_tbl->tbl));
break; case DR_ACTION_TYP_CTR:
From: Shay Drory shayd@nvidia.com
[ Upstream commit 42b4f7f66a43cdb9216e76e595c8a9af154806da ]
Currently, driver is setting default values to all timeouts during function setup. The offending commit is using a timeout before function setup, meaning: the timeout is 0 (or garbage), since no value have been set. This may result in failure to probe the driver: mlx5_function_setup:1034:(pid 69850): Firmware over 4294967296 MS in pre-initializing state, aborting probe_one:1591:(pid 69850): mlx5_init_one failed with error code -16
Hence, set default values to timeouts during tout_init()
Fixes: 37ca95e62ee2 ("net/mlx5: Increase FW pre-init timeout for health recovery") Signed-off-by: Shay Drory shayd@nvidia.com Reviewed-by: Moshe Shemesh moshe@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c | 11 ++++------- drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h | 1 - drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 -- 3 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c index d758848d34d0..696e45e2bd06 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c @@ -32,20 +32,17 @@ static void tout_set(struct mlx5_core_dev *dev, u64 val, enum mlx5_timeouts_type dev->timeouts->to[type] = val; }
-void mlx5_tout_set_def_val(struct mlx5_core_dev *dev) +int mlx5_tout_init(struct mlx5_core_dev *dev) { int i;
- for (i = 0; i < MAX_TIMEOUT_TYPES; i++) - tout_set(dev, tout_def_sw_val[i], i); -} - -int mlx5_tout_init(struct mlx5_core_dev *dev) -{ dev->timeouts = kmalloc(sizeof(*dev->timeouts), GFP_KERNEL); if (!dev->timeouts) return -ENOMEM;
+ for (i = 0; i < MAX_TIMEOUT_TYPES; i++) + tout_set(dev, tout_def_sw_val[i], i); + return 0; }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h index 257c03eeab36..bc9e9aeda847 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h @@ -35,7 +35,6 @@ int mlx5_tout_init(struct mlx5_core_dev *dev); void mlx5_tout_cleanup(struct mlx5_core_dev *dev); void mlx5_tout_query_iseg(struct mlx5_core_dev *dev); int mlx5_tout_query_dtor(struct mlx5_core_dev *dev); -void mlx5_tout_set_def_val(struct mlx5_core_dev *dev); u64 _mlx5_tout_ms(struct mlx5_core_dev *dev, enum mlx5_timeouts_types type);
#define mlx5_tout_ms(dev, type) _mlx5_tout_ms(dev, MLX5_TO_##type##_MS) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 95f26624b57c..ba2e5232b90b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -1023,8 +1023,6 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, u64 timeout) if (mlx5_core_is_pf(dev)) pcie_print_link_status(dev->pdev);
- mlx5_tout_set_def_val(dev); - /* wait for firmware to accept initialization segments configurations */ err = wait_fw_init(dev, timeout,
From: Eric Dumazet edumazet@google.com
[ Upstream commit d7c4c9e075f8cc6d88d277bc24e5d99297f03c06 ]
While investigating a separate rose issue [1], and enabling CONFIG_NET_DEV_REFCNT_TRACKER=y, Bernard reported an orthogonal ax25 issue [2]
An ax25_dev can be used by one (or many) struct ax25_cb. We thus need different dev_tracker, one per struct ax25_cb.
After this patch is applied, we are able to focus on rose.
[1] https://lore.kernel.org/netdev/fb7544a1-f42e-9254-18cc-c9b071f4ca70@free.fr/
[2] [ 205.798723] reference already released. [ 205.798732] allocated in: [ 205.798734] ax25_bind+0x1a2/0x230 [ax25] [ 205.798747] __sys_bind+0xea/0x110 [ 205.798753] __x64_sys_bind+0x18/0x20 [ 205.798758] do_syscall_64+0x5c/0x80 [ 205.798763] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 205.798768] freed in: [ 205.798770] ax25_release+0x115/0x370 [ax25] [ 205.798778] __sock_release+0x42/0xb0 [ 205.798782] sock_close+0x15/0x20 [ 205.798785] __fput+0x9f/0x260 [ 205.798789] ____fput+0xe/0x10 [ 205.798792] task_work_run+0x64/0xa0 [ 205.798798] exit_to_user_mode_prepare+0x18b/0x190 [ 205.798804] syscall_exit_to_user_mode+0x26/0x40 [ 205.798808] do_syscall_64+0x69/0x80 [ 205.798812] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 205.798827] ------------[ cut here ]------------ [ 205.798829] WARNING: CPU: 2 PID: 2605 at lib/ref_tracker.c:136 ref_tracker_free.cold+0x60/0x81 [ 205.798837] Modules linked in: rose netrom mkiss ax25 rfcomm cmac algif_hash algif_skcipher af_alg bnep snd_hda_codec_hdmi nls_iso8859_1 i915 rtw88_8821ce rtw88_8821c x86_pkg_temp_thermal rtw88_pci intel_powerclamp rtw88_core snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio coretemp snd_hda_intel kvm_intel snd_intel_dspcfg mac80211 snd_hda_codec kvm i2c_algo_bit drm_buddy drm_dp_helper btusb drm_kms_helper snd_hwdep btrtl snd_hda_core btbcm joydev crct10dif_pclmul btintel crc32_pclmul ghash_clmulni_intel mei_hdcp btmtk intel_rapl_msr aesni_intel bluetooth input_leds snd_pcm crypto_simd syscopyarea processor_thermal_device_pci_legacy sysfillrect cryptd intel_soc_dts_iosf snd_seq sysimgblt ecdh_generic fb_sys_fops rapl libarc4 processor_thermal_device intel_cstate processor_thermal_rfim cec snd_timer ecc snd_seq_device cfg80211 processor_thermal_mbox mei_me processor_thermal_rapl mei rc_core at24 snd intel_pch_thermal intel_rapl_common ttm soundcore int340x_thermal_zone video [ 205.798948] mac_hid acpi_pad sch_fq_codel ipmi_devintf ipmi_msghandler drm msr parport_pc ppdev lp parport ramoops pstore_blk reed_solomon pstore_zone efi_pstore ip_tables x_tables autofs4 hid_generic usbhid hid i2c_i801 i2c_smbus r8169 xhci_pci ahci libahci realtek lpc_ich xhci_pci_renesas [last unloaded: ax25] [ 205.798992] CPU: 2 PID: 2605 Comm: ax25ipd Not tainted 5.18.11-F6BVP #3 [ 205.798996] Hardware name: To be filled by O.E.M. To be filled by O.E.M./CK3, BIOS 5.011 09/16/2020 [ 205.798999] RIP: 0010:ref_tracker_free.cold+0x60/0x81 [ 205.799005] Code: e8 d2 01 9b ff 83 7b 18 00 74 14 48 c7 c7 2f d7 ff 98 e8 10 6e fc ff 8b 7b 18 e8 b8 01 9b ff 4c 89 ee 4c 89 e7 e8 5d fd 07 00 <0f> 0b b8 ea ff ff ff e9 30 05 9b ff 41 0f b6 f7 48 c7 c7 a0 fa 4e [ 205.799008] RSP: 0018:ffffaf5281073958 EFLAGS: 00010286 [ 205.799011] RAX: 0000000080000000 RBX: ffff9a0bd687ebe0 RCX: 0000000000000000 [ 205.799014] RDX: 0000000000000001 RSI: 0000000000000282 RDI: 00000000ffffffff [ 205.799016] RBP: ffffaf5281073a10 R08: 0000000000000003 R09: fffffffffffd5618 [ 205.799019] R10: 0000000000ffff10 R11: 000000000000000f R12: ffff9a0bc53384d0 [ 205.799022] R13: 0000000000000282 R14: 00000000ae000001 R15: 0000000000000001 [ 205.799024] FS: 0000000000000000(0000) GS:ffff9a0d0f300000(0000) knlGS:0000000000000000 [ 205.799028] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 205.799031] CR2: 00007ff6b8311554 CR3: 000000001ac10004 CR4: 00000000001706e0 [ 205.799033] Call Trace: [ 205.799035] <TASK> [ 205.799038] ? ax25_dev_device_down+0xd9/0x1b0 [ax25] [ 205.799047] ? ax25_device_event+0x9f/0x270 [ax25] [ 205.799055] ? raw_notifier_call_chain+0x49/0x60 [ 205.799060] ? call_netdevice_notifiers_info+0x52/0xa0 [ 205.799065] ? dev_close_many+0xc8/0x120 [ 205.799070] ? unregister_netdevice_many+0x13d/0x890 [ 205.799073] ? unregister_netdevice_queue+0x90/0xe0 [ 205.799076] ? unregister_netdev+0x1d/0x30 [ 205.799080] ? mkiss_close+0x7c/0xc0 [mkiss] [ 205.799084] ? tty_ldisc_close+0x2e/0x40 [ 205.799089] ? tty_ldisc_hangup+0x137/0x210 [ 205.799092] ? __tty_hangup.part.0+0x208/0x350 [ 205.799098] ? tty_vhangup+0x15/0x20 [ 205.799103] ? pty_close+0x127/0x160 [ 205.799108] ? tty_release+0x139/0x5e0 [ 205.799112] ? __fput+0x9f/0x260 [ 205.799118] ax25_dev_device_down+0xd9/0x1b0 [ax25] [ 205.799126] ax25_device_event+0x9f/0x270 [ax25] [ 205.799135] raw_notifier_call_chain+0x49/0x60 [ 205.799140] call_netdevice_notifiers_info+0x52/0xa0 [ 205.799146] dev_close_many+0xc8/0x120 [ 205.799152] unregister_netdevice_many+0x13d/0x890 [ 205.799157] unregister_netdevice_queue+0x90/0xe0 [ 205.799161] unregister_netdev+0x1d/0x30 [ 205.799165] mkiss_close+0x7c/0xc0 [mkiss] [ 205.799170] tty_ldisc_close+0x2e/0x40 [ 205.799173] tty_ldisc_hangup+0x137/0x210 [ 205.799178] __tty_hangup.part.0+0x208/0x350 [ 205.799184] tty_vhangup+0x15/0x20 [ 205.799188] pty_close+0x127/0x160 [ 205.799193] tty_release+0x139/0x5e0 [ 205.799199] __fput+0x9f/0x260 [ 205.799203] ____fput+0xe/0x10 [ 205.799208] task_work_run+0x64/0xa0 [ 205.799213] do_exit+0x33b/0xab0 [ 205.799217] ? __handle_mm_fault+0xc4f/0x15f0 [ 205.799224] do_group_exit+0x35/0xa0 [ 205.799228] __x64_sys_exit_group+0x18/0x20 [ 205.799232] do_syscall_64+0x5c/0x80 [ 205.799238] ? handle_mm_fault+0xba/0x290 [ 205.799242] ? debug_smp_processor_id+0x17/0x20 [ 205.799246] ? fpregs_assert_state_consistent+0x26/0x50 [ 205.799251] ? exit_to_user_mode_prepare+0x49/0x190 [ 205.799256] ? irqentry_exit_to_user_mode+0x9/0x20 [ 205.799260] ? irqentry_exit+0x33/0x40 [ 205.799263] ? exc_page_fault+0x87/0x170 [ 205.799268] ? asm_exc_page_fault+0x8/0x30 [ 205.799273] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 205.799277] RIP: 0033:0x7ff6b80eaca1 [ 205.799281] Code: Unable to access opcode bytes at RIP 0x7ff6b80eac77. [ 205.799283] RSP: 002b:00007fff6dfd4738 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 [ 205.799287] RAX: ffffffffffffffda RBX: 00007ff6b8215a00 RCX: 00007ff6b80eaca1 [ 205.799290] RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000001 [ 205.799293] RBP: 0000000000000001 R08: ffffffffffffff80 R09: 0000000000000028 [ 205.799295] R10: 0000000000000000 R11: 0000000000000246 R12: 00007ff6b8215a00 [ 205.799298] R13: 0000000000000000 R14: 00007ff6b821aee8 R15: 00007ff6b821af00 [ 205.799304] </TASK>
Fixes: feef318c855a ("ax25: fix UAF bugs of net_device caused by rebinding operation") Reported-by: Bernard F6BVP f6bvp@free.fr Signed-off-by: Eric Dumazet edumazet@google.com Cc: Duoming Zhou duoming@zju.edu.cn Link: https://lore.kernel.org/r/20220728051821.3160118-1-eric.dumazet@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/ax25.h | 1 + net/ax25/af_ax25.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/net/ax25.h b/include/net/ax25.h index a427a05672e2..f8cf3629a419 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -236,6 +236,7 @@ typedef struct ax25_cb { ax25_address source_addr, dest_addr; ax25_digi *digipeat; ax25_dev *ax25_dev; + netdevice_tracker dev_tracker; unsigned char iamdigi; unsigned char state, modulus, pidincl; unsigned short vs, vr, va; diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 4c7030ed8d33..5b5363c99ed5 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1065,7 +1065,7 @@ static int ax25_release(struct socket *sock) del_timer_sync(&ax25->t3timer); del_timer_sync(&ax25->idletimer); } - dev_put_track(ax25_dev->dev, &ax25_dev->dev_tracker); + dev_put_track(ax25_dev->dev, &ax25->dev_tracker); ax25_dev_put(ax25_dev); }
@@ -1146,7 +1146,7 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (ax25_dev) { ax25_fillin_cb(ax25, ax25_dev); - dev_hold_track(ax25_dev->dev, &ax25_dev->dev_tracker, GFP_ATOMIC); + dev_hold_track(ax25_dev->dev, &ax25->dev_tracker, GFP_ATOMIC); }
done:
From: Zhengchao Shao shaozhengchao@huawei.com
[ Upstream commit 98dfa9343f37bdd4112966292751e3a93aaf2e56 ]
The hpre encryption driver may be used to encrypt and decrypt packets during the rx softirq, it is not allowed to use GFP_KERNEL.
Fixes: c8b4b477079d ("crypto: hisilicon - add HiSilicon HPRE accelerator") Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/hisilicon/hpre/hpre_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c index 97d54c1465c2..3ba6f15deafc 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c +++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c @@ -252,7 +252,7 @@ static int hpre_prepare_dma_buf(struct hpre_asym_request *hpre_req, if (unlikely(shift < 0)) return -EINVAL;
- ptr = dma_alloc_coherent(dev, ctx->key_sz, tmp, GFP_KERNEL); + ptr = dma_alloc_coherent(dev, ctx->key_sz, tmp, GFP_ATOMIC); if (unlikely(!ptr)) return -ENOMEM;
From: Pali Rohár pali@kernel.org
[ Upstream commit fa4d57b85786ec0e16565c75a51c208834b0c24d ]
Without MODULE_DEVICE_TABLE, crypto_safexcel.ko module is not automatically loaded on platforms where inside-secure crypto HW is specified in device tree (e.g. Armada 3720). So add missing MODULE_DEVICE_TABLE for of.
Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver") Signed-off-by: Pali Rohár pali@kernel.org Acked-by: Marek Behún kabel@kernel.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/inside-secure/safexcel.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c index 9b1a158aec29..ad0d8c4a71ac 100644 --- a/drivers/crypto/inside-secure/safexcel.c +++ b/drivers/crypto/inside-secure/safexcel.c @@ -1831,6 +1831,8 @@ static const struct of_device_id safexcel_of_match_table[] = { {}, };
+MODULE_DEVICE_TABLE(of, safexcel_of_match_table); + static struct platform_driver crypto_safexcel = { .probe = safexcel_probe, .remove = safexcel_remove,
From: Kai Ye yekai13@huawei.com
[ Upstream commit 45f5d0176d8426cc1ab0bab84fbd8ef5c57526c6 ]
The authentication algorithm supports a maximum of 128-byte keys. The allocated key memory is insufficient.
Fixes: 2f072d75d1ab ("crypto: hisilicon - Add aead support on SEC2") Signed-off-by: Kai Ye yekai13@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/hisilicon/sec2/sec_crypto.c | 6 +++--- drivers/crypto/hisilicon/sec2/sec_crypto.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c index 71dfa7db6394..77c9f13cf69a 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -620,7 +620,7 @@ static int sec_auth_init(struct sec_ctx *ctx) { struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
- a_ctx->a_key = dma_alloc_coherent(ctx->dev, SEC_MAX_KEY_SIZE, + a_ctx->a_key = dma_alloc_coherent(ctx->dev, SEC_MAX_AKEY_SIZE, &a_ctx->a_key_dma, GFP_KERNEL); if (!a_ctx->a_key) return -ENOMEM; @@ -632,8 +632,8 @@ static void sec_auth_uninit(struct sec_ctx *ctx) { struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
- memzero_explicit(a_ctx->a_key, SEC_MAX_KEY_SIZE); - dma_free_coherent(ctx->dev, SEC_MAX_KEY_SIZE, + memzero_explicit(a_ctx->a_key, SEC_MAX_AKEY_SIZE); + dma_free_coherent(ctx->dev, SEC_MAX_AKEY_SIZE, a_ctx->a_key, a_ctx->a_key_dma); }
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.h b/drivers/crypto/hisilicon/sec2/sec_crypto.h index 5e039b50e9d4..d033f63b583f 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.h +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.h @@ -7,6 +7,7 @@ #define SEC_AIV_SIZE 12 #define SEC_IV_SIZE 24 #define SEC_MAX_KEY_SIZE 64 +#define SEC_MAX_AKEY_SIZE 128 #define SEC_COMM_SCENE 0 #define SEC_MIN_BLOCK_SZ 1
From: Mike Manning mvrmanning@gmail.com
[ Upstream commit 944fd1aeacb627fa617f85f8e5a34f7ae8ea4d8e ]
The commit 3c82a21f4320 ("net: allow binding socket in a VRF when there's an unbound socket") changed the inet socket lookup to avoid packets in a VRF from matching an unbound socket. This is to ensure the necessary isolation between the default and other VRFs for routing and forwarding. VRF-unaware processes running in the default VRF cannot access another VRF and have to be run with 'ip vrf exec <vrf>'. This is to be expected with tcp_l3mdev_accept disabled, but could be reallowed when this sysctl option is enabled. So instead of directly checking dif and sdif in inet[6]_match, here call inet_sk_bound_dev_eq(). This allows a match on unbound socket for non-zero sdif i.e. for packets in a VRF, if tcp_l3mdev_accept is enabled.
Fixes: 3c82a21f4320 ("net: allow binding socket in a VRF when there's an unbound socket") Signed-off-by: Mike Manning mvrmanning@gmail.com Link: https://lore.kernel.org/netdev/a54c149aed38fded2d3b5fdb1a6c89e36a083b74.came... Reviewed-by: David Ahern dsahern@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/inet6_hashtables.h | 7 +++---- include/net/inet_hashtables.h | 19 +++---------------- include/net/inet_sock.h | 11 +++++++++++ 3 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index f259e1ae14ba..56f1286583d3 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h @@ -110,8 +110,6 @@ static inline bool inet6_match(struct net *net, const struct sock *sk, const __portpair ports, const int dif, const int sdif) { - int bound_dev_if; - if (!net_eq(sock_net(sk), net) || sk->sk_family != AF_INET6 || sk->sk_portpair != ports || @@ -119,8 +117,9 @@ static inline bool inet6_match(struct net *net, const struct sock *sk, !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr)) return false;
- bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); - return bound_dev_if == dif || bound_dev_if == sdif; + /* READ_ONCE() paired with WRITE_ONCE() in sock_bindtoindex_locked() */ + return inet_sk_bound_dev_eq(net, READ_ONCE(sk->sk_bound_dev_if), dif, + sdif); } #endif /* IS_ENABLED(CONFIG_IPV6) */
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index fd6b510d114b..e9cf2157ed8a 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -175,17 +175,6 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo) hashinfo->ehash_locks = NULL; }
-static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if, - int dif, int sdif) -{ -#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) - return inet_bound_dev_eq(!!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept), - bound_dev_if, dif, sdif); -#else - return inet_bound_dev_eq(true, bound_dev_if, dif, sdif); -#endif -} - struct inet_bind_bucket * inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net, struct inet_bind_hashbucket *head, @@ -271,16 +260,14 @@ static inline bool inet_match(struct net *net, const struct sock *sk, const __addrpair cookie, const __portpair ports, int dif, int sdif) { - int bound_dev_if; - if (!net_eq(sock_net(sk), net) || sk->sk_portpair != ports || sk->sk_addrpair != cookie) return false;
- /* Paired with WRITE_ONCE() from sock_bindtoindex_locked() */ - bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); - return bound_dev_if == dif || bound_dev_if == sdif; + /* READ_ONCE() paired with WRITE_ONCE() in sock_bindtoindex_locked() */ + return inet_sk_bound_dev_eq(net, READ_ONCE(sk->sk_bound_dev_if), dif, + sdif); }
/* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 6395f6b9a5d2..bf5654ce711e 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -149,6 +149,17 @@ static inline bool inet_bound_dev_eq(bool l3mdev_accept, int bound_dev_if, return bound_dev_if == dif || bound_dev_if == sdif; }
+static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if, + int dif, int sdif) +{ +#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) + return inet_bound_dev_eq(!!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept), + bound_dev_if, dif, sdif); +#else + return inet_bound_dev_eq(true, bound_dev_if, dif, sdif); +#endif +} + struct inet_cork { unsigned int flags; __be32 addr;
From: Ido Schimmel idosch@nvidia.com
[ Upstream commit 180a6a3ee60a7cb69ed1232388460644f6a21f00 ]
As part of FIB offload simulation, netdevsim stores IPv4 and IPv6 routes and holds a reference on FIB info structures that in turn hold a reference on the associated nexthop device(s).
In the unlikely case where we are unable to allocate memory to process a route deletion request, netdevsim will not release the reference from the associated FIB info structure, thereby preventing the associated nexthop device(s) from ever being removed [1].
Fix this by scheduling a work item that will flush netdevsim's FIB table upon route deletion failure. This will cause netdevsim to release its reference from all the FIB info structures in its table.
Reported by Lucas Leong of Trend Micro Zero Day Initiative.
Fixes: 0ae3eb7b4611 ("netdevsim: fib: Perform the route programming in a non-atomic context") Signed-off-by: Ido Schimmel idosch@nvidia.com Reviewed-by: Amit Cohen amcohen@nvidia.com Reviewed-by: David Ahern dsahern@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/netdevsim/fib.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c index c8f398f5bc5b..57371c697d5c 100644 --- a/drivers/net/netdevsim/fib.c +++ b/drivers/net/netdevsim/fib.c @@ -54,6 +54,7 @@ struct nsim_fib_data { struct rhashtable nexthop_ht; struct devlink *devlink; struct work_struct fib_event_work; + struct work_struct fib_flush_work; struct list_head fib_event_queue; spinlock_t fib_event_queue_lock; /* Protects fib event queue list */ struct mutex nh_lock; /* Protects NH HT */ @@ -978,7 +979,7 @@ static int nsim_fib_event_schedule_work(struct nsim_fib_data *data,
fib_event = kzalloc(sizeof(*fib_event), GFP_ATOMIC); if (!fib_event) - return NOTIFY_BAD; + goto err_fib_event_alloc;
fib_event->data = data; fib_event->event = event; @@ -1006,6 +1007,9 @@ static int nsim_fib_event_schedule_work(struct nsim_fib_data *data,
err_fib_prepare_event: kfree(fib_event); +err_fib_event_alloc: + if (event == FIB_EVENT_ENTRY_DEL) + schedule_work(&data->fib_flush_work); return NOTIFY_BAD; }
@@ -1483,6 +1487,24 @@ static void nsim_fib_event_work(struct work_struct *work) mutex_unlock(&data->fib_lock); }
+static void nsim_fib_flush_work(struct work_struct *work) +{ + struct nsim_fib_data *data = container_of(work, struct nsim_fib_data, + fib_flush_work); + struct nsim_fib_rt *fib_rt, *fib_rt_tmp; + + /* Process pending work. */ + flush_work(&data->fib_event_work); + + mutex_lock(&data->fib_lock); + list_for_each_entry_safe(fib_rt, fib_rt_tmp, &data->fib_rt_list, list) { + rhashtable_remove_fast(&data->fib_rt_ht, &fib_rt->ht_node, + nsim_fib_rt_ht_params); + nsim_fib_rt_free(fib_rt, data); + } + mutex_unlock(&data->fib_lock); +} + static int nsim_fib_debugfs_init(struct nsim_fib_data *data, struct nsim_dev *nsim_dev) { @@ -1541,6 +1563,7 @@ struct nsim_fib_data *nsim_fib_create(struct devlink *devlink, goto err_rhashtable_nexthop_destroy;
INIT_WORK(&data->fib_event_work, nsim_fib_event_work); + INIT_WORK(&data->fib_flush_work, nsim_fib_flush_work); INIT_LIST_HEAD(&data->fib_event_queue); spin_lock_init(&data->fib_event_queue_lock);
@@ -1587,6 +1610,7 @@ struct nsim_fib_data *nsim_fib_create(struct devlink *devlink, err_nexthop_nb_unregister: unregister_nexthop_notifier(devlink_net(devlink), &data->nexthop_nb); err_rhashtable_fib_destroy: + cancel_work_sync(&data->fib_flush_work); flush_work(&data->fib_event_work); rhashtable_free_and_destroy(&data->fib_rt_ht, nsim_fib_rt_free, data); @@ -1616,6 +1640,7 @@ void nsim_fib_destroy(struct devlink *devlink, struct nsim_fib_data *data) NSIM_RESOURCE_IPV4_FIB); unregister_fib_notifier(devlink_net(devlink), &data->fib_nb); unregister_nexthop_notifier(devlink_net(devlink), &data->nexthop_nb); + cancel_work_sync(&data->fib_flush_work); flush_work(&data->fib_event_work); rhashtable_free_and_destroy(&data->fib_rt_ht, nsim_fib_rt_free, data);
From: William Dean williamsukatube@gmail.com
[ Upstream commit 42bbf810e155efc6129a3a648ae5300f00b79d7b ]
The function alloc_workqueue() in rtw_core_init() can fail, but there is no check of its return value. To fix this bug, its return value should be checked with new error handling code.
Fixes: fe101716c7c9d ("rtw88: replace tx tasklet with work queue") Reported-by: Hacash Robot hacashRobot@santino.com Signed-off-by: William Dean williamsukatube@gmail.com Reviewed-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220723063756.2956189-1-williamsukatube@163.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/main.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index efabd5b1bf5b..645ef1d01895 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -1984,6 +1984,10 @@ int rtw_core_init(struct rtw_dev *rtwdev) timer_setup(&rtwdev->tx_report.purge_timer, rtw_tx_report_purge_timer, 0); rtwdev->tx_wq = alloc_workqueue("rtw_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0); + if (!rtwdev->tx_wq) { + rtw_warn(rtwdev, "alloc_workqueue rtw_tx_wq failed\n"); + return -ENOMEM; + }
INIT_DELAYED_WORK(&rtwdev->watch_dog_work, rtw_watch_dog_work); INIT_DELAYED_WORK(&coex->bt_relink_work, rtw_coex_bt_relink_work);
From: Przemyslaw Patynowski przemyslawx.patynowski@intel.com
[ Upstream commit ec60d54cb9a3d43a02c5612a03093c18233e6601 ]
Fix max_rate option in TC, check for proper quanta boundaries. Check for minimum value provided and if it fits expected 50Mbps quanta.
Without this patch, iavf could send settings for max_rate limiting that would be accepted from by PF even the max_rate option is less than expected 50Mbps quanta. It results in no rate limiting on traffic as rate limiting will be floored to 0.
Example: tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \ 2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \ max_rate 50Mbps 500Mbps 500Mbps
Should limit TC0 to circa 50 Mbps
tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \ 2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \ max_rate 0Mbps 100Kbit 500Mbps
Should return error
Fixes: d5b33d024496 ("i40evf: add ndo_setup_tc callback to i40evf") Signed-off-by: Przemyslaw Patynowski przemyslawx.patynowski@intel.com Signed-off-by: Jun Zhang xuejun.zhang@intel.com Tested-by: Bharathi Sreenivas bharathi.sreenivas@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf.h | 1 + drivers/net/ethernet/intel/iavf/iavf_main.c | 25 +++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h index 0ea0361cd86b..c241fbc30f93 100644 --- a/drivers/net/ethernet/intel/iavf/iavf.h +++ b/drivers/net/ethernet/intel/iavf/iavf.h @@ -92,6 +92,7 @@ struct iavf_vsi { #define IAVF_HKEY_ARRAY_SIZE ((IAVF_VFQF_HKEY_MAX_INDEX + 1) * 4) #define IAVF_HLUT_ARRAY_SIZE ((IAVF_VFQF_HLUT_MAX_INDEX + 1) * 4) #define IAVF_MBPS_DIVISOR 125000 /* divisor to convert to Mbps */ +#define IAVF_MBPS_QUANTA 50
#define IAVF_VIRTCHNL_VF_RESOURCE_SIZE (sizeof(struct virtchnl_vf_resource) + \ (IAVF_MAX_VF_VSI * \ diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 2e2c153ce46a..51ae10eb348c 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -3322,6 +3322,7 @@ static int iavf_validate_ch_config(struct iavf_adapter *adapter, struct tc_mqprio_qopt_offload *mqprio_qopt) { u64 total_max_rate = 0; + u32 tx_rate_rem = 0; int i, num_qps = 0; u64 tx_rate = 0; int ret = 0; @@ -3336,12 +3337,32 @@ static int iavf_validate_ch_config(struct iavf_adapter *adapter, return -EINVAL; if (mqprio_qopt->min_rate[i]) { dev_err(&adapter->pdev->dev, - "Invalid min tx rate (greater than 0) specified\n"); + "Invalid min tx rate (greater than 0) specified for TC%d\n", + i); return -EINVAL; } - /*convert to Mbps */ + + /* convert to Mbps */ tx_rate = div_u64(mqprio_qopt->max_rate[i], IAVF_MBPS_DIVISOR); + + if (mqprio_qopt->max_rate[i] && + tx_rate < IAVF_MBPS_QUANTA) { + dev_err(&adapter->pdev->dev, + "Invalid max tx rate for TC%d, minimum %dMbps\n", + i, IAVF_MBPS_QUANTA); + return -EINVAL; + } + + (void)div_u64_rem(tx_rate, IAVF_MBPS_QUANTA, &tx_rate_rem); + + if (tx_rate_rem != 0) { + dev_err(&adapter->pdev->dev, + "Invalid max tx rate for TC%d, not divisible by %d\n", + i, IAVF_MBPS_QUANTA); + return -EINVAL; + } + total_max_rate += tx_rate; num_qps += mqprio_qopt->qopt.count[i]; }
From: Przemyslaw Patynowski przemyslawx.patynowski@intel.com
[ Upstream commit 93cb804edab1b9a5bb7bb7b6824012dbb20abf22 ]
Fix tc qdisc show dev <ethX> root displaying too many fq_codel qdiscs. tc_modify_qdisc, which is caller of ndo_setup_tc, expects driver to call netif_set_real_num_tx_queues, which prepares qdiscs. Without this patch, fq_codel qdiscs would not be adjusted to number of queues on VF. e.g.: tc qdisc show dev <ethX> qdisc mq 0: root qdisc fq_codel 0: parent :4 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent :3 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent :2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent :1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 tc qdisc add dev <ethX> root mqprio num_tc 2 map 1 0 0 0 0 0 0 0 queues 1@0 1@1 hw 1 mode channel shaper bw_rlimit max_rate 5000Mbit 150Mbit tc qdisc show dev <ethX> qdisc mqprio 8003: root tc 2 map 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 queues:(0:0) (1:1) mode:channel shaper:bw_rlimit max_rate:5Gbit 150Mbit qdisc fq_codel 0: parent 8003:4 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent 8003:3 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent 8003:2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent 8003:1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
While after fix: tc qdisc add dev <ethX> root mqprio num_tc 2 map 1 0 0 0 0 0 0 0 queues 1@0 1@1 hw 1 mode channel shaper bw_rlimit max_rate 5000Mbit 150Mbit tc qdisc show dev <ethX> #should show 2, shows 4 qdisc mqprio 8004: root tc 2 map 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 queues:(0:0) (1:1) mode:channel shaper:bw_rlimit max_rate:5Gbit 150Mbit qdisc fq_codel 0: parent 8004:2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 qdisc fq_codel 0: parent 8004:1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
Fixes: d5b33d024496 ("i40evf: add ndo_setup_tc callback to i40evf") Signed-off-by: Przemyslaw Patynowski przemyslawx.patynowski@intel.com Co-developed-by: Grzegorz Szczurek grzegorzx.szczurek@intel.com Signed-off-by: Grzegorz Szczurek grzegorzx.szczurek@intel.com Co-developed-by: Kiran Patil kiran.patil@intel.com Signed-off-by: Kiran Patil kiran.patil@intel.com Signed-off-by: Jedrzej Jagielski jedrzej.jagielski@intel.com Tested-by: Bharathi Sreenivas bharathi.sreenivas@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf.h | 5 +++++ drivers/net/ethernet/intel/iavf/iavf_main.c | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+)
diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h index c241fbc30f93..a988c08e906f 100644 --- a/drivers/net/ethernet/intel/iavf/iavf.h +++ b/drivers/net/ethernet/intel/iavf/iavf.h @@ -431,6 +431,11 @@ struct iavf_adapter { /* lock to protect access to the cloud filter list */ spinlock_t cloud_filter_list_lock; u16 num_cloud_filters; + /* snapshot of "num_active_queues" before setup_tc for qdisc add + * is invoked. This information is useful during qdisc del flow, + * to restore correct number of queues + */ + int orig_num_active_queues;
#define IAVF_MAX_FDIR_FILTERS 128 /* max allowed Flow Director filters */ u16 fdir_active_fltr; diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 51ae10eb348c..3dbfaead2ac7 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -3429,6 +3429,7 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data) netif_tx_disable(netdev); iavf_del_all_cloud_filters(adapter); adapter->aq_required = IAVF_FLAG_AQ_DISABLE_CHANNELS; + total_qps = adapter->orig_num_active_queues; goto exit; } else { return -EINVAL; @@ -3472,7 +3473,21 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data) adapter->ch_config.ch_info[i].offset = 0; } } + + /* Take snapshot of original config such as "num_active_queues" + * It is used later when delete ADQ flow is exercised, so that + * once delete ADQ flow completes, VF shall go back to its + * original queue configuration + */ + + adapter->orig_num_active_queues = adapter->num_active_queues; + + /* Store queue info based on TC so that VF gets configured + * with correct number of queues when VF completes ADQ config + * flow + */ adapter->ch_config.total_qps = total_qps; + netif_tx_stop_all_queues(netdev); netif_tx_disable(netdev); adapter->aq_required |= IAVF_FLAG_AQ_ENABLE_CHANNELS; @@ -3489,6 +3504,12 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data) } } exit: + if (test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) + return 0; + + netif_set_real_num_rx_queues(netdev, total_qps); + netif_set_real_num_tx_queues(netdev, total_qps); + return ret; }
From: Jakub Kicinski kuba@kernel.org
[ Upstream commit d0b80a9edb1a029ff913e81b47540e57ad034329 ]
We need to suppress warnings from sily map sizes. Also switch from GFP_USER to GFP_KERNEL_ACCOUNT, I'm pretty sure I misunderstood the flags when writing this code.
Fixes: 395cacb5f1a0 ("netdevsim: bpf: support fake map offload") Reported-by: syzbot+ad24705d3fd6463b18c6@syzkaller.appspotmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20220726213605.154204-1-kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/netdevsim/bpf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c index a43820212932..50854265864d 100644 --- a/drivers/net/netdevsim/bpf.c +++ b/drivers/net/netdevsim/bpf.c @@ -351,10 +351,12 @@ nsim_map_alloc_elem(struct bpf_offloaded_map *offmap, unsigned int idx) { struct nsim_bpf_bound_map *nmap = offmap->dev_priv;
- nmap->entry[idx].key = kmalloc(offmap->map.key_size, GFP_USER); + nmap->entry[idx].key = kmalloc(offmap->map.key_size, + GFP_KERNEL_ACCOUNT | __GFP_NOWARN); if (!nmap->entry[idx].key) return -ENOMEM; - nmap->entry[idx].value = kmalloc(offmap->map.value_size, GFP_USER); + nmap->entry[idx].value = kmalloc(offmap->map.value_size, + GFP_KERNEL_ACCOUNT | __GFP_NOWARN); if (!nmap->entry[idx].value) { kfree(nmap->entry[idx].key); nmap->entry[idx].key = NULL; @@ -496,7 +498,7 @@ nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap) if (offmap->map.map_flags) return -EINVAL;
- nmap = kzalloc(sizeof(*nmap), GFP_USER); + nmap = kzalloc(sizeof(*nmap), GFP_KERNEL_ACCOUNT); if (!nmap) return -ENOMEM;
From: Eric Dumazet edumazet@google.com
[ Upstream commit 931027820e4dafabc78aff82af59f8c1c4bd3128 ]
Bernard reported that trying to unload rose module would lead to infamous messages:
unregistered_netdevice: waiting for rose0 to become free. Usage count = xx
This patch solves the issue, by making sure each socket referring to a netdevice holds a reference count on it, and properly releases it in rose_release().
rose_dev_first() is also fixed to take a device reference before leaving the rcu_read_locked section.
Following patch will add ref_tracker annotations to ease future bug hunting.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: Bernard Pidoux f6bvp@free.fr Signed-off-by: Eric Dumazet edumazet@google.com Tested-by: Bernard Pidoux f6bvp@free.fr Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/rose/af_rose.c | 11 +++++++++-- net/rose/rose_route.c | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index bf2d986a6bc3..a8e3ec800a9c 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -192,6 +192,7 @@ static void rose_kill_by_device(struct net_device *dev) rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0); if (rose->neighbour) rose->neighbour->use--; + dev_put(rose->device); rose->device = NULL; } } @@ -592,6 +593,8 @@ static struct sock *rose_make_new(struct sock *osk) rose->idle = orose->idle; rose->defer = orose->defer; rose->device = orose->device; + if (rose->device) + dev_hold(rose->device); rose->qbitincl = orose->qbitincl;
return sk; @@ -645,6 +648,7 @@ static int rose_release(struct socket *sock) break; }
+ dev_put(rose->device); sock->sk = NULL; release_sock(sk); sock_put(sk); @@ -721,7 +725,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le struct rose_sock *rose = rose_sk(sk); struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr; unsigned char cause, diagnostic; - struct net_device *dev; ax25_uid_assoc *user; int n, err = 0;
@@ -778,9 +781,12 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le }
if (sock_flag(sk, SOCK_ZAPPED)) { /* Must bind first - autobinding in this may or may not work */ + struct net_device *dev; + sock_reset_flag(sk, SOCK_ZAPPED);
- if ((dev = rose_dev_first()) == NULL) { + dev = rose_dev_first(); + if (!dev) { err = -ENETUNREACH; goto out_release; } @@ -788,6 +794,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le user = ax25_findbyuid(current_euid()); if (!user) { err = -EINVAL; + dev_put(dev); goto out_release; }
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index eb0b8197ac82..fee772b4637c 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c @@ -615,6 +615,8 @@ struct net_device *rose_dev_first(void) if (first == NULL || strncmp(dev->name, first->name, 3) < 0) first = dev; } + if (first) + dev_hold(first); rcu_read_unlock();
return first;
From: Jian Shen shenjian15@huawei.com
[ Upstream commit 7dc839fe47611e6995f370cae37b9797cf7d2672 ]
vsi->current_netdev_flags is used store the current net device flags, not the active netdevice features. So it should use vsi->netdev->featurs, rather than vsi->current_netdev_flags to check NETIF_F_HW_VLAN_CTAG_FILTER.
Fixes: 1babaf77f49d ("ice: Advertise 802.1ad VLAN filtering and offloads for PF netdev") Signed-off-by: Jian Shen shenjian15@huawei.com Signed-off-by: Guangbin Huang huangguangbin2@huawei.com Acked-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/ice/ice_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 9f02b60459f1..bc68dc5c6927 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -433,7 +433,7 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi) IFF_PROMISC; goto out_promisc; } - if (vsi->current_netdev_flags & + if (vsi->netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER) vlan_ops->ena_rx_filtering(vsi); }
From: Jian Shen shenjian15@huawei.com
[ Upstream commit a86e86db5e6d72c82724a63ca1c5293409a21518 ]
The prototype of input features of ionic_set_nic_features() is netdev_features_t, but the vlan_flags is using the private definition of ionic drivers. It should use the variable ctx.cmd.lif_setattr.features, rather than features to check the vlan flags. So fixes it.
Fixes: beead698b173 ("ionic: Add the basic NDO callbacks for netdev support") Signed-off-by: Jian Shen shenjian15@huawei.com Signed-off-by: Guangbin Huang huangguangbin2@huawei.com Acked-by: Shannon Nelson snelson@pensando.io Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index f3568901eb91..1443f788ee37 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -1437,7 +1437,7 @@ static int ionic_set_nic_features(struct ionic_lif *lif, if ((old_hw_features ^ lif->hw_features) & IONIC_ETH_HW_RX_HASH) ionic_lif_rss_config(lif, lif->rss_types, NULL, NULL);
- if ((vlan_flags & features) && + if ((vlan_flags & le64_to_cpu(ctx.cmd.lif_setattr.features)) && !(vlan_flags & le64_to_cpu(ctx.comp.lif_setattr.features))) dev_info_once(lif->ionic->dev, "NIC is not supporting vlan offload, likely in SmartNIC mode\n");
From: Hangyu Hua hbh25y@gmail.com
[ Upstream commit a41b17ff9dacd22f5f118ee53d82da0f3e52d5e3 ]
In the case of sk->dccps_qpolicy == DCCPQ_POLICY_PRIO, dccp_qpolicy_full will drop a skb when qpolicy is full. And the lock in dccp_sendmsg is released before sock_alloc_send_skb and then relocked after sock_alloc_send_skb. The following conditions may lead dccp_qpolicy_push to add skb to an already full sk_write_queue:
thread1--->lock thread1--->dccp_qpolicy_full: queue is full. drop a skb thread1--->unlock thread2--->lock thread2--->dccp_qpolicy_full: queue is not full. no need to drop. thread2--->unlock thread1--->lock thread1--->dccp_qpolicy_push: add a skb. queue is full. thread1--->unlock thread2--->lock thread2--->dccp_qpolicy_push: add a skb! thread2--->unlock
Fix this by moving dccp_qpolicy_full.
Fixes: b1308dc015eb ("[DCCP]: Set TX Queue Length Bounds via Sysctl") Signed-off-by: Hangyu Hua hbh25y@gmail.com Link: https://lore.kernel.org/r/20220729110027.40569-1-hbh25y@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dccp/proto.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index eb8e128e43e8..e13641c65f88 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -736,11 +736,6 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
lock_sock(sk);
- if (dccp_qpolicy_full(sk)) { - rc = -EAGAIN; - goto out_release; - } - timeo = sock_sndtimeo(sk, noblock);
/* @@ -759,6 +754,11 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) if (skb == NULL) goto out_release;
+ if (dccp_qpolicy_full(sk)) { + rc = -EAGAIN; + goto out_discard; + } + if (sk->sk_state == DCCP_CLOSED) { rc = -ENOTCONN; goto out_discard;
From: Maciej Żenczykowski maze@google.com
[ Upstream commit f56530dcdb0684406661ac9f1accf48319d07600 ]
This refixes:
commit 7da17624e7948d5d9660b910f8079d26d26ce453 nt: usb: USB_RTL8153_ECM should not default to y
In general, device drivers should not be enabled by default.
which basically broke the commit it claimed to fix, ie:
commit 657bc1d10bfc23ac06d5d687ce45826c760744f9 r8153_ecm: avoid to be prior to r8152 driver
Avoid r8153_ecm is compiled as built-in, if r8152 driver is compiled as modules. Otherwise, the r8153_ecm would be used, even though the device is supported by r8152 driver.
this commit amounted to:
drivers/net/usb/Kconfig:
+config USB_RTL8153_ECM + tristate "RTL8153 ECM support" + depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n) + default y + help + This option supports ECM mode for RTL8153 ethernet adapter, when + CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not + supported by r8152 driver.
drivers/net/usb/Makefile:
-obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r8153_ecm.o +obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o +obj-$(CONFIG_USB_RTL8153_ECM) += r8153_ecm.o
And as can be seen it pulls a piece of the cdc_ether driver out into a separate config option to be able to make this piece modular in case cdc_ether is builtin, while r8152 is modular.
While in general, device drivers should indeed not be enabled by default: this isn't a device driver per say, but rather this is support code for the CDCETHER (ECM) driver, and should thus be enabled if it is enabled.
See also email thread at: https://www.spinics.net/lists/netdev/msg767649.html
In: https://www.spinics.net/lists/netdev/msg768284.html
Jakub wrote: And when we say "removed" we can just hide it from what's prompted to the user (whatever such internal options are called)? I believe this way we don't bring back Marek's complaint.
Side note: these incorrect defaults will result in Android 13 on 5.15 GKI kernels lacking USB_RTL8153_ECM support while having USB_NET_CDCETHER (luckily we also have USB_RTL8150 and USB_RTL8152, so it's probably only an issue for very new RTL815x hardware with no native 5.15 driver).
Fixes: 7da17624e7948d5d ("nt: usb: USB_RTL8153_ECM should not default to y") Cc: Geert Uytterhoeven geert+renesas@glider.be Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Hayes Wang hayeswang@realtek.com Cc: Jakub Kicinski kuba@kernel.org Signed-off-by: Maciej Żenczykowski maze@google.com Link: https://lore.kernel.org/r/20220730230113.4138858-1-zenczykowski@gmail.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/usb/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index e62fc4f2aee0..76659c1c525a 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -637,8 +637,9 @@ config USB_NET_AQC111 * Aquantia AQtion USB to 5GbE
config USB_RTL8153_ECM - tristate "RTL8153 ECM support" + tristate depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n) + default y help This option supports ECM mode for RTL8153 ethernet adapter, when CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not
From: Maxim Mikityanskiy maximmi@nvidia.com
[ Upstream commit 8eaa1d110800fac050bab44001732747a1c39894 ]
Striding RQ uses MTT page mapping, where each page corresponds to an XSK frame. MTT pages have alignment requirements, and XSK frames don't have any alignment guarantees in the unaligned mode. Frames with improper alignment must be discarded, otherwise the packet data will be written at a wrong address.
Fixes: 282c0c798f8e ("net/mlx5e: Allow XSK frames smaller than a page") Signed-off-by: Maxim Mikityanskiy maximmi@nvidia.com Reviewed-by: Tariq Toukan tariqt@nvidia.com Reviewed-by: Saeed Mahameed saeedm@nvidia.com Reviewed-by: Maciej Fijalkowski maciej.fijalkowski@intel.com Link: https://lore.kernel.org/r/20220729121356.3990867-1-maximmi@nvidia.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/mellanox/mlx5/core/en/xsk/rx.h | 14 ++++++++++++++ include/net/xdp_sock_drv.h | 11 +++++++++++ 2 files changed, 25 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.h index a8cfab4a393c..cc18d97d8ee0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.h @@ -7,6 +7,8 @@ #include "en.h" #include <net/xdp_sock_drv.h>
+#define MLX5E_MTT_PTAG_MASK 0xfffffffffffffff8ULL + /* RX data path */
struct sk_buff *mlx5e_xsk_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq, @@ -21,6 +23,7 @@ struct sk_buff *mlx5e_xsk_skb_from_cqe_linear(struct mlx5e_rq *rq, static inline int mlx5e_xsk_page_alloc_pool(struct mlx5e_rq *rq, struct mlx5e_dma_info *dma_info) { +retry: dma_info->xsk = xsk_buff_alloc(rq->xsk_pool); if (!dma_info->xsk) return -ENOMEM; @@ -32,6 +35,17 @@ static inline int mlx5e_xsk_page_alloc_pool(struct mlx5e_rq *rq, */ dma_info->addr = xsk_buff_xdp_get_frame_dma(dma_info->xsk);
+ /* MTT page mapping has alignment requirements. If they are not + * satisfied, leak the descriptor so that it won't come again, and try + * to allocate a new one. + */ + if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { + if (unlikely(dma_info->addr & ~MLX5E_MTT_PTAG_MASK)) { + xsk_buff_discard(dma_info->xsk); + goto retry; + } + } + return 0; }
diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h index 4aa031849668..0774ce97c2f1 100644 --- a/include/net/xdp_sock_drv.h +++ b/include/net/xdp_sock_drv.h @@ -95,6 +95,13 @@ static inline void xsk_buff_free(struct xdp_buff *xdp) xp_free(xskb); }
+static inline void xsk_buff_discard(struct xdp_buff *xdp) +{ + struct xdp_buff_xsk *xskb = container_of(xdp, struct xdp_buff_xsk, xdp); + + xp_release(xskb); +} + static inline void xsk_buff_set_size(struct xdp_buff *xdp, u32 size) { xdp->data = xdp->data_hard_start + XDP_PACKET_HEADROOM; @@ -238,6 +245,10 @@ static inline void xsk_buff_free(struct xdp_buff *xdp) { }
+static inline void xsk_buff_discard(struct xdp_buff *xdp) +{ +} + static inline void xsk_buff_set_size(struct xdp_buff *xdp, u32 size) { }
From: Jason A. Donenfeld Jason@zx2c4.com
[ Upstream commit 151c8e499f4705010780189377f85b57400ccbf5 ]
Using msleep() is problematic because it's compared against ratelimiter.c's ktime_get_coarse_boottime_ns(), which means on systems with slow jiffies (such as UML's forced HZ=100), the result is inaccurate. So switch to using schedule_hrtimeout().
However, hrtimer gives us access only to the traditional posix timers, and none of the _COARSE variants. So now, rather than being too imprecise like jiffies, it's too precise.
One solution would be to give it a large "range" value, but this will still fire early on a loaded system. A better solution is to align the timeout to the actual coarse timer, and then round up to the nearest tick, plus change.
So add the timeout to the current coarse time, and then schedule_hrtimer() until the absolute computed time.
This should hopefully reduce flakes in CI as well. Note that we keep the retry loop in case the entire function is running behind, because the test could still be scheduled out, by either the kernel or by the hypervisor's kernel, in which case restarting the test and hoping to not be scheduled out still helps.
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel") Suggested-by: Thomas Gleixner tglx@linutronix.de Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireguard/selftest/ratelimiter.c | 25 +++++++++++--------- kernel/time/hrtimer.c | 1 + 2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireguard/selftest/ratelimiter.c b/drivers/net/wireguard/selftest/ratelimiter.c index 007cd4457c5f..ba87d294604f 100644 --- a/drivers/net/wireguard/selftest/ratelimiter.c +++ b/drivers/net/wireguard/selftest/ratelimiter.c @@ -6,28 +6,29 @@ #ifdef DEBUG
#include <linux/jiffies.h> +#include <linux/hrtimer.h>
static const struct { bool result; - unsigned int msec_to_sleep_before; + u64 nsec_to_sleep_before; } expected_results[] __initconst = { [0 ... PACKETS_BURSTABLE - 1] = { true, 0 }, [PACKETS_BURSTABLE] = { false, 0 }, - [PACKETS_BURSTABLE + 1] = { true, MSEC_PER_SEC / PACKETS_PER_SECOND }, + [PACKETS_BURSTABLE + 1] = { true, NSEC_PER_SEC / PACKETS_PER_SECOND }, [PACKETS_BURSTABLE + 2] = { false, 0 }, - [PACKETS_BURSTABLE + 3] = { true, (MSEC_PER_SEC / PACKETS_PER_SECOND) * 2 }, + [PACKETS_BURSTABLE + 3] = { true, (NSEC_PER_SEC / PACKETS_PER_SECOND) * 2 }, [PACKETS_BURSTABLE + 4] = { true, 0 }, [PACKETS_BURSTABLE + 5] = { false, 0 } };
static __init unsigned int maximum_jiffies_at_index(int index) { - unsigned int total_msecs = 2 * MSEC_PER_SEC / PACKETS_PER_SECOND / 3; + u64 total_nsecs = 2 * NSEC_PER_SEC / PACKETS_PER_SECOND / 3; int i;
for (i = 0; i <= index; ++i) - total_msecs += expected_results[i].msec_to_sleep_before; - return msecs_to_jiffies(total_msecs); + total_nsecs += expected_results[i].nsec_to_sleep_before; + return nsecs_to_jiffies(total_nsecs); }
static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4, @@ -42,8 +43,12 @@ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4, loop_start_time = jiffies;
for (i = 0; i < ARRAY_SIZE(expected_results); ++i) { - if (expected_results[i].msec_to_sleep_before) - msleep(expected_results[i].msec_to_sleep_before); + if (expected_results[i].nsec_to_sleep_before) { + ktime_t timeout = ktime_add(ktime_add_ns(ktime_get_coarse_boottime(), TICK_NSEC * 4 / 3), + ns_to_ktime(expected_results[i].nsec_to_sleep_before)); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_hrtimeout_range_clock(&timeout, 0, HRTIMER_MODE_ABS, CLOCK_BOOTTIME); + }
if (time_is_before_jiffies(loop_start_time + maximum_jiffies_at_index(i))) @@ -127,7 +132,7 @@ bool __init wg_ratelimiter_selftest(void) if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN)) return true;
- BUILD_BUG_ON(MSEC_PER_SEC % PACKETS_PER_SECOND != 0); + BUILD_BUG_ON(NSEC_PER_SEC % PACKETS_PER_SECOND != 0);
if (wg_ratelimiter_init()) goto out; @@ -176,7 +181,6 @@ bool __init wg_ratelimiter_selftest(void) test += test_count; goto err; } - msleep(500); continue; } else if (ret < 0) { test += test_count; @@ -195,7 +199,6 @@ bool __init wg_ratelimiter_selftest(void) test += test_count; goto err; } - msleep(50); continue; } test += test_count; diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 0ea8702eb516..23af5eca11b1 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -2311,6 +2311,7 @@ schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta,
return !t.task ? 0 : -EINTR; } +EXPORT_SYMBOL_GPL(schedule_hrtimeout_range_clock);
/** * schedule_hrtimeout_range - sleep until timeout
From: Jason A. Donenfeld Jason@zx2c4.com
[ Upstream commit c31b14d86dfe7174361e8c6e5df6c2c3a4d5918c ]
In case push_rcu() and related functions are buggy, there's a WARN_ON(len >= 128), which the selftest tries to hit by being tricky. In case it is hit, we shouldn't corrupt the kernel's stack, though; otherwise it may be hard to even receive the report that it's buggy. So conditionalize the stack write based on that WARN_ON()'s return value.
Note that this never *actually* happens anyway. The WARN_ON() in the first place is bounded by IS_ENABLED(DEBUG), and isn't expected to ever actually hit. This is just a debugging sanity check.
Additionally, hoist the constant 128 into a named enum, MAX_ALLOWEDIPS_BITS, so that it's clear why this value is chosen.
Suggested-by: Linus Torvalds torvalds@linux-foundation.org Link: https://lore.kernel.org/all/CAHk-=wjJZGA6w_DxA+k7Ejbqsq+uGK==koPai3sqdsfJqem... Fixes: e7096c131e51 ("net: WireGuard secure network tunnel") Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireguard/allowedips.c | 9 ++++++--- drivers/net/wireguard/selftest/allowedips.c | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireguard/allowedips.c b/drivers/net/wireguard/allowedips.c index 9a4c8ff32d9d..5bf7822c53f1 100644 --- a/drivers/net/wireguard/allowedips.c +++ b/drivers/net/wireguard/allowedips.c @@ -6,6 +6,8 @@ #include "allowedips.h" #include "peer.h"
+enum { MAX_ALLOWEDIPS_BITS = 128 }; + static struct kmem_cache *node_cache;
static void swap_endian(u8 *dst, const u8 *src, u8 bits) @@ -40,7 +42,8 @@ static void push_rcu(struct allowedips_node **stack, struct allowedips_node __rcu *p, unsigned int *len) { if (rcu_access_pointer(p)) { - WARN_ON(IS_ENABLED(DEBUG) && *len >= 128); + if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_BITS)) + return; stack[(*len)++] = rcu_dereference_raw(p); } } @@ -52,7 +55,7 @@ static void node_free_rcu(struct rcu_head *rcu)
static void root_free_rcu(struct rcu_head *rcu) { - struct allowedips_node *node, *stack[128] = { + struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = { container_of(rcu, struct allowedips_node, rcu) }; unsigned int len = 1;
@@ -65,7 +68,7 @@ static void root_free_rcu(struct rcu_head *rcu)
static void root_remove_peer_lists(struct allowedips_node *root) { - struct allowedips_node *node, *stack[128] = { root }; + struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = { root }; unsigned int len = 1;
while (len > 0 && (node = stack[--len])) { diff --git a/drivers/net/wireguard/selftest/allowedips.c b/drivers/net/wireguard/selftest/allowedips.c index e173204ae7d7..41db10f9be49 100644 --- a/drivers/net/wireguard/selftest/allowedips.c +++ b/drivers/net/wireguard/selftest/allowedips.c @@ -593,10 +593,10 @@ bool __init wg_allowedips_selftest(void) wg_allowedips_remove_by_peer(&t, a, &mutex); test_negative(4, a, 192, 168, 0, 1);
- /* These will hit the WARN_ON(len >= 128) in free_node if something - * goes wrong. + /* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_BITS) in free_node + * if something goes wrong. */ - for (i = 0; i < 128; ++i) { + for (i = 0; i < MAX_ALLOWEDIPS_BITS; ++i) { part = cpu_to_be64(~(1LLU << (i % 64))); memset(&ip, 0xff, 16); memcpy((u8 *)&ip + (i < 64) * 8, &part, 8);
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit e51d8d3ea3d773334d2c047c8d1623dba66f592a ]
When sensor discovery fails, this means that the system doesn't have any sensors connected and a user should only be notified at most one time. A message is already displayed at WARN level of "failed to discover, sensors not enabled". It's pointless to show that the client init failed at ERR level for the same condition.
Check the return code and don't display this message in those conditions.
Fixes: b5d7f43e97da ("HID: amd_sfh: Add support for sensor discovery") Reported-by: David Chang David.Chang@amd.com Signed-off-by: Mario Limonciello mario.limonciello@amd.com Acked-by: Basavaraj Natikar Basavaraj.Natikar@amd.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c index dadc491bbf6b..1441787a154a 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c @@ -327,7 +327,8 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i rc = amd_sfh_hid_client_init(privdata); if (rc) { amd_sfh_clear_intr(privdata); - dev_err(&pdev->dev, "amd_sfh_hid_client_init failed\n"); + if (rc != -EOPNOTSUPP) + dev_err(&pdev->dev, "amd_sfh_hid_client_init failed\n"); return rc; }
From: Ralph Siemsen ralph.siemsen@linaro.org
[ Upstream commit 2dee50ab9e72a3cae75b65e5934c8dd3e9bf01bc ]
There are two UART clock groups, each having a mux to select its upstream clock source. The register/bit definitions for accessing these two muxes appear to have been reversed since introduction. Correct them so as to match the hardware manual.
Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver")
Signed-off-by: Ralph Siemsen ralph.siemsen@linaro.org Reviewed-by: Phil Edworthy phil.edworthy@renesas.com Link: https://lore.kernel.org/r/20220518182527.1693156-1-ralph.siemsen@linaro.org Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/renesas/r9a06g032-clocks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index 35ffc462af1a..864b3dabecd9 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -290,8 +290,8 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] = { .name = "uart_group_012", .type = K_BITSEL, .source = 1 + R9A06G032_DIV_UART, - /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */ - .dual.sel = ((0xec / 4) << 5) | 24, + /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */ + .dual.sel = ((0x34 / 4) << 5) | 30, .dual.group = 0, }, { @@ -299,8 +299,8 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] = { .name = "uart_group_34567", .type = K_BITSEL, .source = 1 + R9A06G032_DIV_P2_PG, - /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */ - .dual.sel = ((0x34 / 4) << 5) | 30, + /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */ + .dual.sel = ((0xec / 4) << 5) | 24, .dual.group = 1, }, D_UGATE(CLK_UART0, "clk_uart0", UART_GROUP_012, 0, 0, 0x1b2, 0x1b3, 0x1b4, 0x1b5),
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 33ec82a6d2b119938f26e5c8040ed5d92378eb54 ]
of_find_matching_node_and_match() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: b0afd44bc192 ("mtd: physmap_of: add a hook for Versatile write protection") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220523140205.48625-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/maps/physmap-versatile.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/maps/physmap-versatile.c b/drivers/mtd/maps/physmap-versatile.c index ad7cd9cfaee0..297a50957356 100644 --- a/drivers/mtd/maps/physmap-versatile.c +++ b/drivers/mtd/maps/physmap-versatile.c @@ -207,6 +207,7 @@ int of_flash_probe_versatile(struct platform_device *pdev,
versatile_flashprot = (enum versatile_flashprot)devid->data; rmap = syscon_node_to_regmap(sysnp); + of_node_put(sysnp); if (IS_ERR(rmap)) return PTR_ERR(rmap);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 77087a04c8fd554134bddcb8a9ff87b21f357926 ]
of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: b0afd44bc192 ("mtd: physmap_of: add a hook for Versatile write protection") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220523143255.4376-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/maps/physmap-versatile.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/maps/physmap-versatile.c b/drivers/mtd/maps/physmap-versatile.c index 297a50957356..a1b8b7b25f88 100644 --- a/drivers/mtd/maps/physmap-versatile.c +++ b/drivers/mtd/maps/physmap-versatile.c @@ -93,6 +93,7 @@ static int ap_flash_init(struct platform_device *pdev) return -ENODEV; } ebi_base = of_iomap(ebi, 0); + of_node_put(ebi); if (!ebi_base) return -ENODEV;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit ec0da06337751b18f6dee06b6526e0f0d6e80369 ]
When meson_nfc_nand_chip_cleanup() is called, it will call: meson_nfc_free_buffer(&meson_chip->nand); nand_cleanup(&meson_chip->nand);
nand_cleanup() in turn will call nand_detach() which calls the .detach_chip() which is here meson_nand_detach_chip().
meson_nand_detach_chip() already calls meson_nfc_free_buffer(), so we could double free some memory.
Fix it by removing the unneeded explicit call to meson_nfc_free_buffer().
Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Acked-by: Liang Yang liang.yang@amlogic.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/ec15c358b8063f7c50ff4cd628cf0d2e14e43f49.1... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/nand/raw/meson_nand.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c index ac3be92872d0..032180183339 100644 --- a/drivers/mtd/nand/raw/meson_nand.c +++ b/drivers/mtd/nand/raw/meson_nand.c @@ -1307,7 +1307,6 @@ static int meson_nfc_nand_chip_cleanup(struct meson_nfc *nfc) if (ret) return ret;
- meson_nfc_free_buffer(&meson_chip->nand); nand_cleanup(&meson_chip->nand); list_del(&meson_chip->node); }
From: Biju Das biju.das.jz@bp.renesas.com
[ Upstream commit 02c96ed9e4cd1f47bfcd10296fec6b0b69d6b3c6 ]
As per RZ/G2L HW(Rev.1.10) manual, reset monitor register value 0 means reset signal is not applied (deassert state) and 1 means reset signal is applied (assert state).
reset_control_status() expects a positive value if the reset line is asserted. But rzg2l_cpg_status function returns zero for asserted state.
This patch fixes the issue by adding double inverted logic, so that reset_control_status returns a positive value if the reset line is asserted.
Fixes: ef3c613ccd68 ("clk: renesas: Add CPG core wrapper for RZ/G2L SoC") Signed-off-by: Biju Das biju.das.jz@bp.renesas.com Link: https://lore.kernel.org/r/20220531071657.104121-1-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/renesas/rzg2l-cpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index e2999ab2b53c..3ff6ecd61756 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -1180,7 +1180,7 @@ static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, s8 monbit = info->resets[id].monbit;
if (info->has_clk_mon_regs) { - return !(readl(priv->base + CLK_MRST_R(reg)) & bitmask); + return !!(readl(priv->base + CLK_MRST_R(reg)) & bitmask); } else if (monbit >= 0) { u32 monbitmask = BIT(monbit);
From: Vaibhav Jain vaibhav@linux.ibm.com
[ Upstream commit cbf9c4b9617b6767886a913705ca14b7600c77db ]
Presently ima_get_kexec_buffer() doesn't check if the previous kernel's ima-kexec-buffer lies outside the addressable memory range. This can result in a kernel panic if the new kernel is booted with 'mem=X' arg and the ima-kexec-buffer was allocated beyond that range by the previous kernel. The panic is usually of the form below:
$ sudo kexec --initrd initrd vmlinux --append='mem=16G'
<snip> BUG: Unable to handle kernel data access on read at 0xc000c01fff7f0000 Faulting instruction address: 0xc000000000837974 Oops: Kernel access of bad area, sig: 11 [#1] <snip> NIP [c000000000837974] ima_restore_measurement_list+0x94/0x6c0 LR [c00000000083b55c] ima_load_kexec_buffer+0xac/0x160 Call Trace: [c00000000371fa80] [c00000000083b55c] ima_load_kexec_buffer+0xac/0x160 [c00000000371fb00] [c0000000020512c4] ima_init+0x80/0x108 [c00000000371fb70] [c0000000020514dc] init_ima+0x4c/0x120 [c00000000371fbf0] [c000000000012240] do_one_initcall+0x60/0x2c0 [c00000000371fcc0] [c000000002004ad0] kernel_init_freeable+0x344/0x3ec [c00000000371fda0] [c0000000000128a4] kernel_init+0x34/0x1b0 [c00000000371fe10] [c00000000000ce64] ret_from_kernel_thread+0x5c/0x64 Instruction dump: f92100b8 f92100c0 90e10090 910100a0 4182050c 282a0017 3bc00000 40810330 7c0802a6 fb610198 7c9b2378 f80101d0 <a1240000> 2c090001 40820614 e9240010 ---[ end trace 0000000000000000 ]---
Fix this issue by checking returned PFN range of previous kernel's ima-kexec-buffer with page_is_ram() to ensure correct memory bounds.
Fixes: 467d27824920 ("powerpc: ima: get the kexec buffer passed by the previous kernel") Cc: Frank Rowand frowand.list@gmail.com Cc: Prakhar Srivastava prsriva@linux.microsoft.com Cc: Lakshmi Ramasubramanian nramas@linux.microsoft.com Cc: Thiago Jung Bauermann bauerman@linux.ibm.com Cc: Rob Herring robh@kernel.org Cc: Ritesh Harjani ritesh.list@gmail.com Cc: Robin Murphy robin.murphy@arm.com Signed-off-by: Vaibhav Jain vaibhav@linux.ibm.com Signed-off-by: Rob Herring robh@kernel.org Link: https://lore.kernel.org/r/20220531041446.3334259-1-vaibhav@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/kexec.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c index 8d374cc552be..91b04b04eec4 100644 --- a/drivers/of/kexec.c +++ b/drivers/of/kexec.c @@ -126,6 +126,7 @@ int ima_get_kexec_buffer(void **addr, size_t *size) { int ret, len; unsigned long tmp_addr; + unsigned long start_pfn, end_pfn; size_t tmp_size; const void *prop;
@@ -140,6 +141,22 @@ int ima_get_kexec_buffer(void **addr, size_t *size) if (ret) return ret;
+ /* Do some sanity on the returned size for the ima-kexec buffer */ + if (!tmp_size) + return -ENOENT; + + /* + * Calculate the PFNs for the buffer and ensure + * they are with in addressable memory. + */ + start_pfn = PHYS_PFN(tmp_addr); + end_pfn = PHYS_PFN(tmp_addr + tmp_size - 1); + if (!page_is_ram(start_pfn) || !page_is_ram(end_pfn)) { + pr_warn("IMA buffer at 0x%lx, size = 0x%zx beyond memory\n", + tmp_addr, tmp_size); + return -EINVAL; + } + *addr = __va(tmp_addr); *size = tmp_size;
From: Quinn Tran qutran@marvell.com
[ Upstream commit 9c40c36e75ffd49952cd4ead0672defc4b4dbdf7 ]
This patch uses GFFID switch command to scan whether remote device is Target or Initiator mode. Based on that info, driver will not pass up Initiator info to authentication application. This helps reduce unnecessary stress for authentication application to deal with unused connections.
Link: https://lore.kernel.org/r/20220607044627.19563-2-njavali@marvell.com Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs") Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_def.h | 2 + drivers/scsi/qla2xxx/qla_edif.c | 32 ++++++++- drivers/scsi/qla2xxx/qla_gbl.h | 3 +- drivers/scsi/qla2xxx/qla_gs.c | 118 +++++++++++++++++++++++--------- drivers/scsi/qla2xxx/qla_iocb.c | 2 +- 5 files changed, 120 insertions(+), 37 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index f25a131fb07e..5f22276927dd 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3204,6 +3204,8 @@ struct ct_sns_rsp { #define GFF_NVME_OFFSET 23 /* type = 28h */ struct { uint8_t fc4_features[128]; +#define FC4_FF_TARGET BIT_0 +#define FC4_FF_INITIATOR BIT_1 } gff_id; struct { uint8_t reserved; diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index cb8145a9ac09..e789f59395ce 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -517,16 +517,28 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) if (atomic_read(&vha->loop_state) == LOOP_DOWN) break;
- fcport->edif.app_started = 1; fcport->login_retry = vha->hw->login_retry_count;
- /* no activity */ fcport->edif.app_stop = 0; + fcport->edif.app_sess_online = 0; + fcport->edif.app_started = 1; + + if (fcport->scan_state != QLA_FCPORT_FOUND) + continue; + + if (fcport->port_type == FCT_UNKNOWN && + !fcport->fc4_features) + rval = qla24xx_async_gffid(vha, fcport, true); + + if (!rval && !(fcport->fc4_features & FC4_FF_TARGET || + fcport->port_type & (FCT_TARGET|FCT_NVME_TARGET))) + continue; + + rval = 0;
ql_dbg(ql_dbg_edif, vha, 0x911e, "%s wwpn %8phC calling qla_edif_reset_auth_wait\n", __func__, fcport->port_name); - fcport->edif.app_sess_online = 0; qlt_schedule_sess_for_deletion(fcport); qla_edif_sa_ctl_init(vha, fcport); } @@ -883,6 +895,20 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) app_reply->ports[pcnt].rekey_count = fcport->edif.rekey_cnt;
+ if (fcport->scan_state != QLA_FCPORT_FOUND) + continue; + + if (fcport->port_type == FCT_UNKNOWN && !fcport->fc4_features) + rval = qla24xx_async_gffid(vha, fcport, true); + + if (!rval && + !(fcport->fc4_features & FC4_FF_TARGET || + fcport->port_type & + (FCT_TARGET | FCT_NVME_TARGET))) + continue; + + rval = 0; + app_reply->ports[pcnt].remote_type = VND_CMD_RTYPE_UNKNOWN; if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET)) diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index dac27b5ff0ac..84b44454c231 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -335,6 +335,7 @@ extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *); extern int qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e); void qla2x00_sp_release(struct kref *kref); +void qla2x00_els_dcmd2_iocb_timeout(void *data);
/* * Global Function Prototypes in qla_mbx.c source file. @@ -727,7 +728,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *); void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *); int qla2x00_mgmt_svr_login(scsi_qla_host_t *); void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea); -int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport); +int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool); int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *); void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *); void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *); diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index f8005ce65082..574251b2e0ef 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3277,19 +3277,12 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) return rval; }
-void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea) -{ - fc_port_t *fcport = ea->fcport; - - qla24xx_post_gnl_work(vha, fcport); -}
void qla24xx_async_gffid_sp_done(srb_t *sp, int res) { struct scsi_qla_host *vha = sp->vha; fc_port_t *fcport = sp->fcport; struct ct_sns_rsp *ct_rsp; - struct event_arg ea; uint8_t fc4_scsi_feat; uint8_t fc4_nvme_feat;
@@ -3297,10 +3290,10 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res) "Async done-%s res %x ID %x. %8phC\n", sp->name, res, fcport->d_id.b24, fcport->port_name);
- fcport->flags &= ~FCF_ASYNC_SENT; - ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; + ct_rsp = sp->u.iocb_cmd.u.ctarg.rsp; fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; + sp->rc = res;
/* * FC-GS-7, 5.2.3.12 FC-4 Features - format @@ -3321,24 +3314,42 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res) } }
- memset(&ea, 0, sizeof(ea)); - ea.sp = sp; - ea.fcport = sp->fcport; - ea.rc = res; + if (sp->flags & SRB_WAKEUP_ON_COMP) { + complete(sp->comp); + } else { + if (sp->u.iocb_cmd.u.ctarg.req) { + dma_free_coherent(&vha->hw->pdev->dev, + sp->u.iocb_cmd.u.ctarg.req_allocated_size, + sp->u.iocb_cmd.u.ctarg.req, + sp->u.iocb_cmd.u.ctarg.req_dma); + sp->u.iocb_cmd.u.ctarg.req = NULL; + }
- qla24xx_handle_gffid_event(vha, &ea); - /* ref: INIT */ - kref_put(&sp->cmd_kref, qla2x00_sp_release); + if (sp->u.iocb_cmd.u.ctarg.rsp) { + dma_free_coherent(&vha->hw->pdev->dev, + sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, + sp->u.iocb_cmd.u.ctarg.rsp, + sp->u.iocb_cmd.u.ctarg.rsp_dma); + sp->u.iocb_cmd.u.ctarg.rsp = NULL; + } + + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); + /* we should not be here */ + dump_stack(); + } }
/* Get FC4 Feature with Nport ID. */ -int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport) +int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool wait) { int rval = QLA_FUNCTION_FAILED; struct ct_sns_req *ct_req; srb_t *sp; + DECLARE_COMPLETION_ONSTACK(comp);
- if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) + /* this routine does not have handling for no wait */ + if (!vha->flags.online || !wait) return rval;
/* ref: INIT */ @@ -3346,43 +3357,86 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport) if (!sp) return rval;
- fcport->flags |= FCF_ASYNC_SENT; sp->type = SRB_CT_PTHRU_CMD; sp->name = "gffid"; sp->gen1 = fcport->rscn_gen; sp->gen2 = fcport->login_gen; qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2, qla24xx_async_gffid_sp_done); + sp->comp = ∁ + sp->u.iocb_cmd.timeout = qla2x00_els_dcmd2_iocb_timeout; + + if (wait) + sp->flags = SRB_WAKEUP_ON_COMP; + + sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt); + sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, + sp->u.iocb_cmd.u.ctarg.req_allocated_size, + &sp->u.iocb_cmd.u.ctarg.req_dma, + GFP_KERNEL); + if (!sp->u.iocb_cmd.u.ctarg.req) { + ql_log(ql_log_warn, vha, 0xd041, + "%s: Failed to allocate ct_sns request.\n", + __func__); + goto done_free_sp; + } + + sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt); + sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev, + sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, + &sp->u.iocb_cmd.u.ctarg.rsp_dma, + GFP_KERNEL); + if (!sp->u.iocb_cmd.u.ctarg.req) { + ql_log(ql_log_warn, vha, 0xd041, + "%s: Failed to allocate ct_sns request.\n", + __func__); + goto done_free_sp; + }
/* CT_IU preamble */ - ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD, - GFF_ID_RSP_SIZE); + ct_req = qla2x00_prep_ct_req(sp->u.iocb_cmd.u.ctarg.req, GFF_ID_CMD, GFF_ID_RSP_SIZE);
ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain; ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area; ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
- sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; - sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; - sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; - sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE; sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE; sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
- ql_dbg(ql_dbg_disc, vha, 0x2132, - "Async-%s hdl=%x %8phC.\n", sp->name, - sp->handle, fcport->port_name); - rval = qla2x00_start_sp(sp); - if (rval != QLA_SUCCESS) + + if (rval != QLA_SUCCESS) { + rval = QLA_FUNCTION_FAILED; goto done_free_sp; + } else { + ql_dbg(ql_dbg_disc, vha, 0x3074, + "Async-%s hdl=%x portid %06x\n", + sp->name, sp->handle, fcport->d_id.b24); + } + + wait_for_completion(sp->comp); + rval = sp->rc;
- return rval; done_free_sp: + if (sp->u.iocb_cmd.u.ctarg.req) { + dma_free_coherent(&vha->hw->pdev->dev, + sp->u.iocb_cmd.u.ctarg.req_allocated_size, + sp->u.iocb_cmd.u.ctarg.req, + sp->u.iocb_cmd.u.ctarg.req_dma); + sp->u.iocb_cmd.u.ctarg.req = NULL; + } + + if (sp->u.iocb_cmd.u.ctarg.rsp) { + dma_free_coherent(&vha->hw->pdev->dev, + sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, + sp->u.iocb_cmd.u.ctarg.rsp, + sp->u.iocb_cmd.u.ctarg.rsp_dma); + sp->u.iocb_cmd.u.ctarg.rsp = NULL; + } + /* ref: INIT */ kref_put(&sp->cmd_kref, qla2x00_sp_release); - fcport->flags &= ~FCF_ASYNC_SENT; return rval; }
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index e0fe9ddb4bd2..46c879923da1 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2819,7 +2819,7 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) sp->vha->qla_stats.control_requests++; }
-static void +void qla2x00_els_dcmd2_iocb_timeout(void *data) { srb_t *sp = data;
From: Quinn Tran qutran@marvell.com
[ Upstream commit 7a7b0b4865d3490f62d6ef1a3aa39fa2b47859a4 ]
- Add version field to edif bsg for future enhancement.
- Add version edif bsg version check
- Remove unused interfaces and fields.
Link: https://lore.kernel.org/r/20220607044627.19563-3-njavali@marvell.com Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update") Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 32 +++++++--- drivers/scsi/qla2xxx/qla_edif_bsg.h | 90 ++++++++++++++++++----------- 2 files changed, 79 insertions(+), 43 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index e789f59395ce..0a49834198ca 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -280,14 +280,19 @@ qla_edif_app_check(scsi_qla_host_t *vha, struct app_id appid) { /* check that the app is allow/known to the driver */
- if (appid.app_vid == EDIF_APP_ID) { - ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x911d, "%s app id ok\n", __func__); - return true; + if (appid.app_vid != EDIF_APP_ID) { + ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app id not ok (%x)", + __func__, appid.app_vid); + return false; + } + + if (appid.version != EDIF_VERSION1) { + ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app version is not ok (%x)", + __func__, appid.version); + return false; } - ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app id not ok (%x)", - __func__, appid.app_vid);
- return false; + return true; }
static void @@ -555,6 +560,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) appreply.host_support_edif = vha->hw->flags.edif_enabled; appreply.edif_enode_active = vha->pur_cinfo.enode_flags; appreply.edif_edb_active = vha->e_dbell.db_flags; + appreply.version = EDIF_VERSION1;
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
@@ -684,6 +690,7 @@ qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job) portid.b.area = appplogiok.u.d_id.b.area; portid.b.al_pa = appplogiok.u.d_id.b.al_pa;
+ appplogireply.version = EDIF_VERSION1; switch (appplogiok.type) { case PL_TYPE_WWPN: fcport = qla2x00_find_fcport_by_wwpn(vha, @@ -876,6 +883,8 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) } else { struct fc_port *fcport = NULL, *tf;
+ app_reply->version = EDIF_VERSION1; + list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { if (!(fcport->flags & FCF_FCSP_DEVICE)) continue; @@ -892,9 +901,6 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24) continue;
- app_reply->ports[pcnt].rekey_count = - fcport->edif.rekey_cnt; - if (fcport->scan_state != QLA_FCPORT_FOUND) continue;
@@ -909,6 +915,7 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
rval = 0;
+ app_reply->ports[pcnt].version = EDIF_VERSION1; app_reply->ports[pcnt].remote_type = VND_CMD_RTYPE_UNKNOWN; if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET)) @@ -1005,6 +1012,8 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job) } else { struct fc_port *fcport = NULL, *tf;
+ app_reply->version = EDIF_VERSION1; + list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { if (fcport->edif.enable) { if (pcnt > app_req.num_ports) @@ -2036,6 +2045,7 @@ qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype, edbnode->u.sa_aen.port_id = fcport->d_id; edbnode->u.sa_aen.status = data; edbnode->u.sa_aen.key_type = data2; + edbnode->u.sa_aen.version = EDIF_VERSION1; break; default: ql_dbg(ql_dbg_edif, vha, 0x09102, @@ -3379,6 +3389,10 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job) port_id_t d_id; struct qla_bsg_auth_els_request *p = (struct qla_bsg_auth_els_request *)bsg_job->request; + struct qla_bsg_auth_els_reply *rpl = + (struct qla_bsg_auth_els_reply *)bsg_job->reply; + + rpl->version = EDIF_VERSION1;
d_id.b.al_pa = bsg_request->rqst_data.h_els.port_id[2]; d_id.b.area = bsg_request->rqst_data.h_els.port_id[1]; diff --git a/drivers/scsi/qla2xxx/qla_edif_bsg.h b/drivers/scsi/qla2xxx/qla_edif_bsg.h index 5a26c77157da..301523e4f483 100644 --- a/drivers/scsi/qla2xxx/qla_edif_bsg.h +++ b/drivers/scsi/qla2xxx/qla_edif_bsg.h @@ -7,13 +7,15 @@ #ifndef __QLA_EDIF_BSG_H #define __QLA_EDIF_BSG_H
+#define EDIF_VERSION1 1 + /* BSG Vendor specific commands */ #define ELS_MAX_PAYLOAD 2112 #ifndef WWN_SIZE #define WWN_SIZE 8 #endif -#define VND_CMD_APP_RESERVED_SIZE 32 - +#define VND_CMD_APP_RESERVED_SIZE 28 +#define VND_CMD_PAD_SIZE 3 enum auth_els_sub_cmd { SEND_ELS = 0, SEND_ELS_REPLY, @@ -28,7 +30,9 @@ struct extra_auth_els { #define BSG_CTL_FLAG_LS_ACC 1 #define BSG_CTL_FLAG_LS_RJT 2 #define BSG_CTL_FLAG_TRM 3 - uint8_t extra_rsvd[3]; + uint8_t version; + uint8_t pad[2]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; } __packed;
struct qla_bsg_auth_els_request { @@ -39,51 +43,46 @@ struct qla_bsg_auth_els_request { struct qla_bsg_auth_els_reply { struct fc_bsg_reply r; uint32_t rx_xchg_address; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; };
struct app_id { int app_vid; - uint8_t app_key[32]; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; } __packed;
struct app_start_reply { uint32_t host_support_edif; uint32_t edif_enode_active; uint32_t edif_edb_active; - uint32_t reserved[VND_CMD_APP_RESERVED_SIZE]; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; } __packed;
struct app_start { struct app_id app_info; - uint32_t prli_to; - uint32_t key_shred; uint8_t app_start_flags; - uint8_t reserved[VND_CMD_APP_RESERVED_SIZE - 1]; + uint8_t version; + uint8_t pad[2]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; } __packed;
struct app_stop { struct app_id app_info; - char buf[16]; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; } __packed;
struct app_plogi_reply { uint32_t prli_status; - uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; -} __packed; - -#define RECFG_TIME 1 -#define RECFG_BYTES 2 - -struct app_rekey_cfg { - struct app_id app_info; - uint8_t rekey_mode; - port_id_t d_id; - uint8_t force; - union { - int64_t bytes; - int64_t time; - } rky_units; - + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; } __packed;
@@ -91,7 +90,9 @@ struct app_pinfo_req { struct app_id app_info; uint8_t num_ports; port_id_t remote_pid; - uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; } __packed;
struct app_pinfo { @@ -103,11 +104,8 @@ struct app_pinfo { #define VND_CMD_RTYPE_INITIATOR 2 uint8_t remote_state; uint8_t auth_state; - uint8_t rekey_mode; - int64_t rekey_count; - int64_t rekey_config_value; - int64_t rekey_consumed_value; - + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; } __packed;
@@ -120,6 +118,8 @@ struct app_pinfo {
struct app_pinfo_reply { uint8_t port_count; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; struct app_pinfo ports[]; } __packed; @@ -127,6 +127,8 @@ struct app_pinfo_reply { struct app_sinfo_req { struct app_id app_info; uint8_t num_ports; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; } __packed;
@@ -140,6 +142,9 @@ struct app_sinfo {
struct app_stats_reply { uint8_t elem_count; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; struct app_sinfo elem[]; } __packed;
@@ -163,9 +168,11 @@ struct qla_sa_update_frame { uint8_t node_name[WWN_SIZE]; uint8_t port_name[WWN_SIZE]; port_id_t port_id; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; + uint8_t reserved2[VND_CMD_APP_RESERVED_SIZE]; } __packed;
-// used for edif mgmt bsg interface #define QL_VND_SC_UNDEF 0 #define QL_VND_SC_SA_UPDATE 1 #define QL_VND_SC_APP_START 2 @@ -175,6 +182,8 @@ struct qla_sa_update_frame { #define QL_VND_SC_REKEY_CONFIG 6 #define QL_VND_SC_GET_FCINFO 7 #define QL_VND_SC_GET_STATS 8 +#define QL_VND_SC_AEN_COMPLETE 9 +
/* Application interface data structure for rtn data */ #define EXT_DEF_EVENT_DATA_SIZE 64 @@ -191,7 +200,9 @@ struct edif_sa_update_aen { port_id_t port_id; uint32_t key_type; /* Tx (1) or RX (2) */ uint32_t status; /* 0 succes, 1 failed, 2 timeout , 3 error */ - uint8_t reserved[16]; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; } __packed;
#define QL_VND_SA_STAT_SUCCESS 0 @@ -212,7 +223,18 @@ struct auth_complete_cmd { uint8_t wwpn[WWN_SIZE]; port_id_t d_id; } u; - uint32_t reserved[VND_CMD_APP_RESERVED_SIZE]; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; +} __packed; + +struct aen_complete_cmd { + struct app_id app_info; + port_id_t port_id; + uint32_t event_code; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; } __packed;
#define RX_DELAY_DELETE_TIMEOUT 20
From: Quinn Tran qutran@marvell.com
[ Upstream commit df648afa39da9c4d3af99c6c03dc3e9c7dfa99b0 ]
On session deletion, wait for app to acknowledge before moving on. This allows both app and driver to stay in sync. In addition, this gives a chance for authentication app to do any type of cleanup before moving on.
Link: https://lore.kernel.org/r/20220607044627.19563-4-njavali@marvell.com Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update") Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_edif.c | 66 +++++++++++++++++++++++++------ drivers/scsi/qla2xxx/qla_init.c | 4 -- drivers/scsi/qla2xxx/qla_target.c | 35 ++++++++-------- 4 files changed, 74 insertions(+), 33 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 5f22276927dd..c2b92a6fef90 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2626,7 +2626,6 @@ typedef struct fc_port { struct { uint32_t enable:1; /* device is edif enabled/req'd */ uint32_t app_stop:2; - uint32_t app_started:1; uint32_t aes_gmac:1; uint32_t app_sess_online:1; uint32_t tx_sa_set:1; @@ -2637,6 +2636,7 @@ typedef struct fc_port { uint32_t rx_rekey_cnt; uint64_t tx_bytes; uint64_t rx_bytes; + uint8_t sess_down_acked; uint8_t auth_state; uint16_t authok:1; uint16_t rekey_cnt; diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 0a49834198ca..fffdf87d823a 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -257,14 +257,8 @@ qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id)
f = NULL; list_for_each_entry_safe(f, tf, &vha->vp_fcports, list) { - if ((f->flags & FCF_FCSP_DEVICE)) { - ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x2058, - "Found secure fcport - nn %8phN pn %8phN portid=0x%x, 0x%x.\n", - f->node_name, f->port_name, - f->d_id.b24, id->b24); - if (f->d_id.b24 == id->b24) - return f; - } + if (f->d_id.b24 == id->b24) + return f; } return NULL; } @@ -526,7 +520,6 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
fcport->edif.app_stop = 0; fcport->edif.app_sess_online = 0; - fcport->edif.app_started = 1;
if (fcport->scan_state != QLA_FCPORT_FOUND) continue; @@ -628,9 +621,6 @@ qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
fcport->send_els_logo = 1; qlt_schedule_sess_for_deletion(fcport); - - /* qla_edif_flush_sa_ctl_lists(fcport); */ - fcport->edif.app_started = 0; } }
@@ -1047,6 +1037,40 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job) return rval; }
+static int32_t +qla_edif_ack(scsi_qla_host_t *vha, struct bsg_job *bsg_job) +{ + struct fc_port *fcport; + struct aen_complete_cmd ack; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + + sg_copy_to_buffer(bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, &ack, sizeof(ack)); + + ql_dbg(ql_dbg_edif, vha, 0x70cf, + "%s: %06x event_code %x\n", + __func__, ack.port_id.b24, ack.event_code); + + fcport = qla2x00_find_fcport_by_pid(vha, &ack.port_id); + SET_DID_STATUS(bsg_reply->result, DID_OK); + + if (!fcport) { + ql_dbg(ql_dbg_edif, vha, 0x70cf, + "%s: unable to find fcport %06x \n", + __func__, ack.port_id.b24); + return 0; + } + + switch (ack.event_code) { + case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN: + fcport->edif.sess_down_acked = 1; + break; + default: + break; + } + return 0; +} + int32_t qla_edif_app_mgmt(struct bsg_job *bsg_job) { @@ -1109,6 +1133,9 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job) case QL_VND_SC_GET_STATS: rval = qla_edif_app_getstats(vha, bsg_job); break; + case QL_VND_SC_AEN_COMPLETE: + rval = qla_edif_ack(vha, bsg_job); + break; default: ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n", __func__, @@ -3512,14 +3539,29 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess) { + u16 cnt = 0; + if (sess->edif.app_sess_online && DBELL_ACTIVE(vha)) { ql_dbg(ql_dbg_disc, vha, 0xf09c, "%s: sess %8phN send port_offline event\n", __func__, sess->port_name); sess->edif.app_sess_online = 0; + sess->edif.sess_down_acked = 0; qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SESSION_SHUTDOWN, sess->d_id.b24, 0, sess); qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24); + + while (!READ_ONCE(sess->edif.sess_down_acked) && + !test_bit(VPORT_DELETE, &vha->dpc_flags)) { + msleep(100); + cnt++; + if (cnt > 100) + break; + } + sess->edif.sess_down_acked = 0; + ql_dbg(ql_dbg_disc, vha, 0xf09c, + "%s: sess %8phN port_offline event completed\n", + __func__, sess->port_name); } }
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 4c0f76021c47..5f077f9217e5 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1480,7 +1480,6 @@ static int qla_chk_secure_login(scsi_qla_host_t *vha, fc_port_t *fcport, ql_dbg(ql_dbg_disc, vha, 0x20ef, "%s %d %8phC EDIF: post DB_AUTH: AUTH needed\n", __func__, __LINE__, fcport->port_name); - fcport->edif.app_started = 1; fcport->edif.app_sess_online = 1;
qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED, @@ -5275,9 +5274,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) INIT_LIST_HEAD(&fcport->edif.tx_sa_list); INIT_LIST_HEAD(&fcport->edif.rx_sa_list);
- if (vha->e_dbell.db_flags == EDB_ACTIVE) - fcport->edif.app_started = 1; - spin_lock_init(&fcport->edif.indx_list_lock); INIT_LIST_HEAD(&fcport->edif.edif_indx_list);
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index cb97f625970d..2b2f68288375 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -981,22 +981,6 @@ void qlt_free_session_done(struct work_struct *work) sess->send_els_logo);
if (!IS_SW_RESV_ADDR(sess->d_id)) { - if (ha->flags.edif_enabled && - (!own || own->iocb.u.isp24.status_subcode == ELS_PLOGI)) { - sess->edif.authok = 0; - if (!ha->flags.host_shutting_down) { - ql_dbg(ql_dbg_edif, vha, 0x911e, - "%s wwpn %8phC calling qla2x00_release_all_sadb\n", - __func__, sess->port_name); - qla2x00_release_all_sadb(vha, sess); - } else { - ql_dbg(ql_dbg_edif, vha, 0x911e, - "%s bypassing release_all_sadb\n", - __func__); - } - qla_edif_clear_appdata(vha, sess); - qla_edif_sess_down(vha, sess); - } qla2x00_mark_device_lost(vha, sess, 0);
if (sess->send_els_logo) { @@ -1042,6 +1026,25 @@ void qlt_free_session_done(struct work_struct *work) sess->nvme_flag |= NVME_FLAG_DELETING; qla_nvme_unregister_remote_port(sess); } + + if (ha->flags.edif_enabled && + (!own || (own && + own->iocb.u.isp24.status_subcode == ELS_PLOGI))) { + sess->edif.authok = 0; + if (!ha->flags.host_shutting_down) { + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s wwpn %8phC calling qla2x00_release_all_sadb\n", + __func__, sess->port_name); + qla2x00_release_all_sadb(vha, sess); + } else { + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s bypassing release_all_sadb\n", + __func__); + } + + qla_edif_clear_appdata(vha, sess); + qla_edif_sess_down(vha, sess); + } }
/*
From: Quinn Tran qutran@marvell.com
[ Upstream commit 5ecd241bd7b1088a189581c0b560a13fe93621f6 ]
Add bsg interface for app to read doorbell events. This interface lets driver know how much app can read based on return buffer size. When the next event(s) occur, driver will return the bsg_job with the event(s) in the return buffer.
If there is no event to read, driver will hold on to the bsg_job up to few seconds as a way to control the polling interval.
Link: https://lore.kernel.org/r/20220607044627.19563-5-njavali@marvell.com Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update") Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_dbg.h | 2 +- drivers/scsi/qla2xxx/qla_edif.c | 249 ++++++++++++++++++++-------- drivers/scsi/qla2xxx/qla_edif.h | 3 +- drivers/scsi/qla2xxx/qla_edif_bsg.h | 14 ++ 4 files changed, 195 insertions(+), 73 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index f1f6c740bdcd..feeb1666227f 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -383,5 +383,5 @@ ql_mask_match(uint level) if (ql2xextended_error_logging == 1) ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK;
- return (level & ql2xextended_error_logging) == level; + return level && ((level & ql2xextended_error_logging) == level); } diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index fffdf87d823a..0d84dad2612c 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -52,6 +52,31 @@ const char *sc_to_str(uint16_t cmd) return "unknown"; }
+static struct edb_node *qla_edb_getnext(scsi_qla_host_t *vha) +{ + unsigned long flags; + struct edb_node *edbnode = NULL; + + spin_lock_irqsave(&vha->e_dbell.db_lock, flags); + + /* db nodes are fifo - no qualifications done */ + if (!list_empty(&vha->e_dbell.head)) { + edbnode = list_first_entry(&vha->e_dbell.head, + struct edb_node, list); + list_del_init(&edbnode->list); + } + + spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags); + + return edbnode; +} + +static void qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node) +{ + list_del_init(&node->list); + kfree(node); +} + static struct edif_list_entry *qla_edif_list_find_sa_index(fc_port_t *fcport, uint16_t handle) { @@ -1071,6 +1096,130 @@ qla_edif_ack(scsi_qla_host_t *vha, struct bsg_job *bsg_job) return 0; }
+static int qla_edif_consume_dbell(scsi_qla_host_t *vha, struct bsg_job *bsg_job) +{ + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + u32 sg_skip, reply_payload_len; + bool keep; + struct edb_node *dbnode = NULL; + struct edif_app_dbell ap; + int dat_size = 0; + + sg_skip = 0; + reply_payload_len = bsg_job->reply_payload.payload_len; + + while ((reply_payload_len - sg_skip) >= sizeof(struct edb_node)) { + dbnode = qla_edb_getnext(vha); + if (dbnode) { + keep = true; + dat_size = 0; + ap.event_code = dbnode->ntype; + switch (dbnode->ntype) { + case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN: + case VND_CMD_AUTH_STATE_NEEDED: + ap.port_id = dbnode->u.plogi_did; + dat_size += sizeof(ap.port_id); + break; + case VND_CMD_AUTH_STATE_ELS_RCVD: + ap.port_id = dbnode->u.els_sid; + dat_size += sizeof(ap.port_id); + break; + case VND_CMD_AUTH_STATE_SAUPDATE_COMPL: + ap.port_id = dbnode->u.sa_aen.port_id; + memcpy(&ap.event_data, &dbnode->u, + sizeof(struct edif_sa_update_aen)); + dat_size += sizeof(struct edif_sa_update_aen); + break; + default: + keep = false; + ql_log(ql_log_warn, vha, 0x09102, + "%s unknown DB type=%d %p\n", + __func__, dbnode->ntype, dbnode); + break; + } + ap.event_data_size = dat_size; + /* 8 = sizeof(ap.event_code + ap.event_data_size) */ + dat_size += 8; + if (keep) + sg_skip += sg_copy_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, + &ap, dat_size, sg_skip, false); + + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s Doorbell consumed : type=%d %p\n", + __func__, dbnode->ntype, dbnode); + + kfree(dbnode); + } else { + break; + } + } + + SET_DID_STATUS(bsg_reply->result, DID_OK); + bsg_reply->reply_payload_rcv_len = sg_skip; + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + + return 0; +} + +static void __qla_edif_dbell_bsg_done(scsi_qla_host_t *vha, struct bsg_job *bsg_job, + u32 delay) +{ + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + + /* small sleep for doorbell events to accumulate */ + if (delay) + msleep(delay); + + qla_edif_consume_dbell(vha, bsg_job); + + bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); +} + +static void qla_edif_dbell_bsg_done(scsi_qla_host_t *vha) +{ + unsigned long flags; + struct bsg_job *prev_bsg_job = NULL; + + spin_lock_irqsave(&vha->e_dbell.db_lock, flags); + if (vha->e_dbell.dbell_bsg_job) { + prev_bsg_job = vha->e_dbell.dbell_bsg_job; + vha->e_dbell.dbell_bsg_job = NULL; + } + spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags); + + if (prev_bsg_job) + __qla_edif_dbell_bsg_done(vha, prev_bsg_job, 0); +} + +static int +qla_edif_dbell_bsg(scsi_qla_host_t *vha, struct bsg_job *bsg_job) +{ + unsigned long flags; + bool return_bsg = false; + + /* flush previous dbell bsg */ + qla_edif_dbell_bsg_done(vha); + + spin_lock_irqsave(&vha->e_dbell.db_lock, flags); + if (list_empty(&vha->e_dbell.head) && DBELL_ACTIVE(vha)) { + /* + * when the next db event happens, bsg_job will return. + * Otherwise, timer will return it. + */ + vha->e_dbell.dbell_bsg_job = bsg_job; + vha->e_dbell.bsg_expire = jiffies + 10 * HZ; + } else { + return_bsg = true; + } + spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags); + + if (return_bsg) + __qla_edif_dbell_bsg_done(vha, bsg_job, 1); + + return 0; +} + int32_t qla_edif_app_mgmt(struct bsg_job *bsg_job) { @@ -1082,8 +1231,13 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job) bool done = true; int32_t rval = 0; uint32_t vnd_sc = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; + u32 level = ql_dbg_edif;
- ql_dbg(ql_dbg_edif, vha, 0x911d, "%s vnd subcmd=%x\n", + /* doorbell is high traffic */ + if (vnd_sc == QL_VND_SC_READ_DBELL) + level = 0; + + ql_dbg(level, vha, 0x911d, "%s vnd subcmd=%x\n", __func__, vnd_sc);
sg_copy_to_buffer(bsg_job->request_payload.sg_list, @@ -1092,7 +1246,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
if (!vha->hw->flags.edif_enabled || test_bit(VPORT_DELETE, &vha->dpc_flags)) { - ql_dbg(ql_dbg_edif, vha, 0x911d, + ql_dbg(level, vha, 0x911d, "%s edif not enabled or vp delete. bsg ptr done %p. dpc_flags %lx\n", __func__, bsg_job, vha->dpc_flags);
@@ -1101,7 +1255,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job) }
if (!qla_edif_app_check(vha, appcheck)) { - ql_dbg(ql_dbg_edif, vha, 0x911d, + ql_dbg(level, vha, 0x911d, "%s app checked failed.\n", __func__);
@@ -1136,6 +1290,10 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job) case QL_VND_SC_AEN_COMPLETE: rval = qla_edif_ack(vha, bsg_job); break; + case QL_VND_SC_READ_DBELL: + rval = qla_edif_dbell_bsg(vha, bsg_job); + done = false; + break; default: ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n", __func__, @@ -1147,7 +1305,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
done: if (done) { - ql_dbg(ql_dbg_user, vha, 0x7009, + ql_dbg(level, vha, 0x7009, "%s: %d bsg ptr done %p\n", __func__, __LINE__, bsg_job); bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); @@ -1859,30 +2017,6 @@ qla_edb_init(scsi_qla_host_t *vha) /* initialize lock which protects doorbell & init list */ spin_lock_init(&vha->e_dbell.db_lock); INIT_LIST_HEAD(&vha->e_dbell.head); - - /* create and initialize doorbell */ - init_completion(&vha->e_dbell.dbell); -} - -static void -qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node) -{ - /* - * releases the space held by this edb node entry - * this function does _not_ free the edb node itself - * NB: the edb node entry passed should not be on any list - * - * currently for doorbell there's no additional cleanup - * needed, but here as a placeholder for furture use. - */ - - if (!node) { - ql_dbg(ql_dbg_edif, vha, 0x09122, - "%s error - no valid node passed\n", __func__); - return; - } - - node->ntype = N_UNDEF; }
static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid) @@ -1929,11 +2063,8 @@ static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid) } spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
- list_for_each_entry_safe(e, tmp, &edb_list, list) { + list_for_each_entry_safe(e, tmp, &edb_list, list) qla_edb_node_free(vha, e); - list_del_init(&e->list); - kfree(e); - } }
/* function called when app is stopping */ @@ -1961,14 +2092,10 @@ qla_edb_stop(scsi_qla_host_t *vha) "%s freeing edb_node type=%x\n", __func__, node->ntype); qla_edb_node_free(vha, node); - list_del(&node->list); - - kfree(node); } spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
- /* wake up doorbell waiters - they'll be dismissed with error code */ - complete_all(&vha->e_dbell.dbell); + qla_edif_dbell_bsg_done(vha); }
static struct edb_node * @@ -2006,9 +2133,6 @@ qla_edb_node_add(scsi_qla_host_t *vha, struct edb_node *ptr) list_add_tail(&ptr->list, &vha->e_dbell.head); spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
- /* ring doorbell for waiters */ - complete(&vha->e_dbell.dbell); - return true; }
@@ -2077,43 +2201,24 @@ qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype, default: ql_dbg(ql_dbg_edif, vha, 0x09102, "%s unknown type: %x\n", __func__, dbtype); - qla_edb_node_free(vha, edbnode); kfree(edbnode); edbnode = NULL; break; }
- if (edbnode && (!qla_edb_node_add(vha, edbnode))) { + if (edbnode) { + if (!qla_edb_node_add(vha, edbnode)) { + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s unable to add dbnode\n", __func__); + kfree(edbnode); + return; + } ql_dbg(ql_dbg_edif, vha, 0x09102, - "%s unable to add dbnode\n", __func__); - qla_edb_node_free(vha, edbnode); - kfree(edbnode); - return; - } - if (edbnode && fcport) - fcport->edif.auth_state = dbtype; - ql_dbg(ql_dbg_edif, vha, 0x09102, - "%s Doorbell produced : type=%d %p\n", __func__, dbtype, edbnode); -} - -static struct edb_node * -qla_edb_getnext(scsi_qla_host_t *vha) -{ - unsigned long flags; - struct edb_node *edbnode = NULL; - - spin_lock_irqsave(&vha->e_dbell.db_lock, flags); - - /* db nodes are fifo - no qualifications done */ - if (!list_empty(&vha->e_dbell.head)) { - edbnode = list_first_entry(&vha->e_dbell.head, - struct edb_node, list); - list_del(&edbnode->list); + "%s Doorbell produced : type=%d %p\n", __func__, dbtype, edbnode); + qla_edif_dbell_bsg_done(vha); + if (fcport) + fcport->edif.auth_state = dbtype; } - - spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags); - - return edbnode; }
void @@ -2141,6 +2246,9 @@ qla_edif_timer(scsi_qla_host_t *vha) ha->edif_post_stop_cnt_down = 60; } } + + if (vha->e_dbell.dbell_bsg_job && time_after_eq(jiffies, vha->e_dbell.bsg_expire)) + qla_edif_dbell_bsg_done(vha); }
/* @@ -2208,7 +2316,6 @@ edif_doorbell_show(struct device *dev, struct device_attribute *attr, "%s Doorbell consumed : type=%d %p\n", __func__, dbnode->ntype, dbnode); /* we're done with the db node, so free it up */ - qla_edb_node_free(vha, dbnode); kfree(dbnode); } else { break; diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h index a965ca8e47ce..3561e22b8f0f 100644 --- a/drivers/scsi/qla2xxx/qla_edif.h +++ b/drivers/scsi/qla2xxx/qla_edif.h @@ -51,7 +51,8 @@ struct edif_dbell { enum db_flags_t db_flags; spinlock_t db_lock; struct list_head head; - struct completion dbell; + struct bsg_job *dbell_bsg_job; + unsigned long bsg_expire; };
#define SA_UPDATE_IOCB_TYPE 0x71 /* Security Association Update IOCB entry */ diff --git a/drivers/scsi/qla2xxx/qla_edif_bsg.h b/drivers/scsi/qla2xxx/qla_edif_bsg.h index 301523e4f483..110843b13767 100644 --- a/drivers/scsi/qla2xxx/qla_edif_bsg.h +++ b/drivers/scsi/qla2xxx/qla_edif_bsg.h @@ -183,6 +183,20 @@ struct qla_sa_update_frame { #define QL_VND_SC_GET_FCINFO 7 #define QL_VND_SC_GET_STATS 8 #define QL_VND_SC_AEN_COMPLETE 9 +#define QL_VND_SC_READ_DBELL 10 + +/* + * bsg caller to provide empty buffer for doorbell events. + * + * sg_io_v4.din_xferp = empty buffer for door bell events + * sg_io_v4.dout_xferp = struct edif_read_dbell *buf + */ +struct edif_read_dbell { + struct app_id app_info; + uint8_t version; + uint8_t pad[VND_CMD_PAD_SIZE]; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; +};
/* Application interface data structure for rtn data */
From: Quinn Tran qutran@marvell.com
[ Upstream commit e0fb8ce2bb9e52c846e54ad2c58b5b7beb13eb09 ]
When a thread is in the process of reestablish a session, a flag is set to prevent multiple threads/triggers from doing the same task. This flag was left on, and any attempt to relogin was locked out. Clear this flag if the attempt has failed.
Link: https://lore.kernel.org/r/20220607044627.19563-6-njavali@marvell.com Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update") Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 0d84dad2612c..c7198f8635c7 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -2331,6 +2331,7 @@ edif_doorbell_show(struct device *dev, struct device_attribute *attr,
static void qla_noop_sp_done(srb_t *sp, int res) { + sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); /* ref: INIT */ kref_put(&sp->cmd_kref, qla2x00_sp_release); } @@ -2355,7 +2356,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e) if (!sa_ctl) { ql_dbg(ql_dbg_edif, vha, 0x70e6, "sa_ctl allocation failed\n"); - return -ENOMEM; + rval = -ENOMEM; + goto done; }
fcport = sa_ctl->fcport; @@ -2365,7 +2367,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e) if (!sp) { ql_dbg(ql_dbg_edif, vha, 0x70e6, "SRB allocation failed\n"); - return -ENOMEM; + rval = -ENOMEM; + goto done; }
fcport->flags |= FCF_ASYNC_SENT; @@ -2394,9 +2397,17 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
rval = qla2x00_start_sp(sp);
- if (rval != QLA_SUCCESS) + if (rval != QLA_SUCCESS) { rval = QLA_FUNCTION_FAILED; + goto done_free_sp; + }
+ return rval; +done_free_sp: + kref_put(&sp->cmd_kref, qla2x00_sp_release); + fcport->flags &= ~FCF_ASYNC_SENT; +done: + fcport->flags &= ~FCF_ASYNC_ACTIVE; return rval; }
From: Quinn Tran qutran@marvell.com
[ Upstream commit cf79716e6636400ae38c37bc8a652b1e522abbba ]
Notify authentication application of a NPIV deletion event is about to occur. This allows app to perform cleanup.
Link: https://lore.kernel.org/r/20220607044627.19563-7-njavali@marvell.com Fixes: 9efea843a906 ("scsi: qla2xxx: edif: Add detection of secure device") Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif_bsg.h | 2 ++ drivers/scsi/qla2xxx/qla_mid.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif_bsg.h b/drivers/scsi/qla2xxx/qla_edif_bsg.h index 110843b13767..0931f4e4e127 100644 --- a/drivers/scsi/qla2xxx/qla_edif_bsg.h +++ b/drivers/scsi/qla2xxx/qla_edif_bsg.h @@ -253,4 +253,6 @@ struct aen_complete_cmd {
#define RX_DELAY_DELETE_TIMEOUT 20
+#define FCH_EVT_VENDOR_UNIQUE_VPORT_DOWN 1 + #endif /* QLA_EDIF_BSG_H */ diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 346d47b61c07..16a9f22bb860 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -166,9 +166,13 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) int ret = QLA_SUCCESS; fc_port_t *fcport;
- if (vha->hw->flags.edif_enabled) + if (vha->hw->flags.edif_enabled) { + if (DBELL_ACTIVE(vha)) + qla2x00_post_aen_work(vha, FCH_EVT_VENDOR_UNIQUE, + FCH_EVT_VENDOR_UNIQUE_VPORT_DOWN); /* delete sessions and flush sa_indexes */ qla2x00_wait_for_sess_deletion(vha); + }
if (vha->hw->flags.fw_started) ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
From: Quinn Tran qutran@marvell.com
[ Upstream commit 0b3f3143d473b489a7aa0779c43bcdb344bd3014 ]
Relating to EDIF, when sending IKE message, updating key or deleting key, driver can encounter IOCB queue full. Add additional retries to reduce higher level recovery.
Link: https://lore.kernel.org/r/20220607044627.19563-8-njavali@marvell.com Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update") Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 52 +++++++++++++++++++++++---------- drivers/scsi/qla2xxx/qla_os.c | 2 +- 2 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index c7198f8635c7..06c1252019e1 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -1467,6 +1467,8 @@ qla24xx_check_sadb_avail_slot(struct bsg_job *bsg_job, fc_port_t *fcport,
#define QLA_SA_UPDATE_FLAGS_RX_KEY 0x0 #define QLA_SA_UPDATE_FLAGS_TX_KEY 0x2 +#define EDIF_MSLEEP_INTERVAL 100 +#define EDIF_RETRY_COUNT 50
int qla24xx_sadb_update(struct bsg_job *bsg_job) @@ -1479,7 +1481,7 @@ qla24xx_sadb_update(struct bsg_job *bsg_job) struct edif_list_entry *edif_entry = NULL; int found = 0; int rval = 0; - int result = 0; + int result = 0, cnt; struct qla_sa_update_frame sa_frame; struct srb_iocb *iocb_cmd; port_id_t portid; @@ -1720,11 +1722,23 @@ qla24xx_sadb_update(struct bsg_job *bsg_job) sp->done = qla2x00_bsg_job_done; iocb_cmd = &sp->u.iocb_cmd; iocb_cmd->u.sa_update.sa_frame = sa_frame; - + cnt = 0; +retry: rval = qla2x00_start_sp(sp); - if (rval != QLA_SUCCESS) { + switch (rval) { + case QLA_SUCCESS: + break; + case EAGAIN: + msleep(EDIF_MSLEEP_INTERVAL); + cnt++; + if (cnt < EDIF_RETRY_COUNT) + goto retry; + + fallthrough; + default: ql_log(ql_dbg_edif, vha, 0x70e3, - "qla2x00_start_sp failed=%d.\n", rval); + "%s qla2x00_start_sp failed=%d.\n", + __func__, rval);
qla2x00_rel_sp(sp); rval = -EIO; @@ -2398,7 +2412,6 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e) rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) { - rval = QLA_FUNCTION_FAILED; goto done_free_sp; }
@@ -3530,7 +3543,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job) fc_port_t *fcport = NULL; struct qla_hw_data *ha = vha->hw; srb_t *sp; - int rval = (DID_ERROR << 16); + int rval = (DID_ERROR << 16), cnt; port_id_t d_id; struct qla_bsg_auth_els_request *p = (struct qla_bsg_auth_els_request *)bsg_job->request; @@ -3625,17 +3638,26 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job) sp->free = qla2x00_bsg_sp_free; sp->done = qla2x00_bsg_job_done;
+ cnt = 0; +retry: rval = qla2x00_start_sp(sp); - - ql_dbg(ql_dbg_edif, vha, 0x700a, - "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n", - __func__, sc_to_str(p->e.sub_cmd), fcport->port_name, - p->e.extra_rx_xchg_address, p->e.extra_control_flags, - sp->handle, sp->remap.req.len, bsg_job); - - if (rval != QLA_SUCCESS) { + switch (rval) { + case QLA_SUCCESS: + ql_dbg(ql_dbg_edif, vha, 0x700a, + "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n", + __func__, sc_to_str(p->e.sub_cmd), fcport->port_name, + p->e.extra_rx_xchg_address, p->e.extra_control_flags, + sp->handle, sp->remap.req.len, bsg_job); + break; + case EAGAIN: + msleep(EDIF_MSLEEP_INTERVAL); + cnt++; + if (cnt < EDIF_RETRY_COUNT) + goto retry; + fallthrough; + default: ql_log(ql_log_warn, vha, 0x700e, - "qla2x00_start_sp failed = %d\n", rval); + "%s qla2x00_start_sp failed = %d\n", __func__, rval); SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY); rval = -EIO; goto done_free_remap_rsp; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 73073fb08369..4f3125b826c4 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -5472,7 +5472,7 @@ qla2x00_do_work(struct scsi_qla_host *vha) e->u.fcport.fcport, false); break; case QLA_EVT_SA_REPLACE: - qla24xx_issue_sa_replace_iocb(vha, e); + rc = qla24xx_issue_sa_replace_iocb(vha, e); break; }
From: Quinn Tran qutran@marvell.com
[ Upstream commit 789d54a4178634850e441f60c0326124138e7269 ]
User failed to see disk via n2n topology. Driver used up all login retries before authentication application started. When authentication application started, driver did not have enough login retries to connect securely. On app_start, driver will reset the login retry attempt count.
Link: https://lore.kernel.org/r/20220607044627.19563-10-njavali@marvell.com Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF") Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 06c1252019e1..bd5740f23e76 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -515,6 +515,9 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) }
if (N2N_TOPO(vha->hw)) { + list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) + fcport->n2n_link_reset_cnt = 0; + if (vha->hw->flags.n2n_fw_acc_sec) set_bit(N2N_LINK_RESET, &vha->dpc_flags); else
From: Quinn Tran qutran@marvell.com
[ Upstream commit aec55325ddec975216119da000092cb8664a3399 ]
After initiator has burned up all login retries, target authentication application begins to run. This triggers a link bounce on target side. Initiator will attempt another login. Due to N2N, the PRLI [nvme | fcp] can fail because of the mode mismatch with target. This patch add a few more login retries to revive the connection.
Link: https://lore.kernel.org/r/20220607044627.19563-11-njavali@marvell.com Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF") Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_init.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 5f077f9217e5..177ce45b76a6 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2123,6 +2123,13 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) }
if (N2N_TOPO(vha->hw)) { + if (ea->fcport->n2n_link_reset_cnt == + vha->hw->login_retry_count && + ea->fcport->flags & FCF_FCSP_DEVICE) { + /* remote authentication app just started */ + ea->fcport->n2n_link_reset_cnt = 0; + } + if (ea->fcport->n2n_link_reset_cnt < vha->hw->login_retry_count) { ea->fcport->n2n_link_reset_cnt++;
From: Sean Christopherson seanjc@google.com
[ Upstream commit cd9e6da8048c5b40315ee2d929b6230ce1252c3c ]
Unwind the RIP advancement done by svm_queue_exception() when injecting an INT3 ultimately "fails" due to the CPU encountering a VM-Exit while vectoring the injected event, even if the exception reported by the CPU isn't the same event that was injected. If vectoring INT3 encounters an exception, e.g. #NP, and vectoring the #NP encounters an intercepted exception, e.g. #PF when KVM is using shadow paging, then the #NP will be reported as the event that was in-progress.
Note, this is still imperfect, as it will get a false positive if the INT3 is cleanly injected, no VM-Exit occurs before the IRET from the INT3 handler in the guest, the instruction following the INT3 generates an exception (directly or indirectly), _and_ vectoring that exception encounters an exception that is intercepted by KVM. The false positives could theoretically be solved by further analyzing the vectoring event, e.g. by comparing the error code against the expected error code were an exception to occur when vectoring the original injected exception, but SVM without NRIPS is a complete disaster, trying to make it 100% correct is a waste of time.
Reviewed-by: Maxim Levitsky mlevitsk@redhat.com Fixes: 66b7138f9136 ("KVM: SVM: Emulate nRIP feature when reinjecting INT3") Signed-off-by: Sean Christopherson seanjc@google.com Signed-off-by: Maciej S. Szmigiero maciej.szmigiero@oracle.com Message-Id: 450133cf0a026cb9825a2ff55d02cb136a1cb111.1651440202.git.maciej.szmigiero@oracle.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kvm/svm/svm.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 40e560c875f1..fe8536c57fd7 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3699,6 +3699,18 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu) vector = exitintinfo & SVM_EXITINTINFO_VEC_MASK; type = exitintinfo & SVM_EXITINTINFO_TYPE_MASK;
+ /* + * If NextRIP isn't enabled, KVM must manually advance RIP prior to + * injecting the soft exception/interrupt. That advancement needs to + * be unwound if vectoring didn't complete. Note, the _new_ event may + * not be the injected event, e.g. if KVM injected an INTn, the INTn + * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will + * be the reported vectored event, but RIP still needs to be unwound. + */ + if (int3_injected && type == SVM_EXITINTINFO_TYPE_EXEPT && + kvm_is_linear_rip(vcpu, svm->int3_rip)) + kvm_rip_write(vcpu, kvm_rip_read(vcpu) - int3_injected); + switch (type) { case SVM_EXITINTINFO_TYPE_NMI: vcpu->arch.nmi_injected = true; @@ -3712,16 +3724,11 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu)
/* * In case of software exceptions, do not reinject the vector, - * but re-execute the instruction instead. Rewind RIP first - * if we emulated INT3 before. + * but re-execute the instruction instead. */ - if (kvm_exception_is_soft(vector)) { - if (vector == BP_VECTOR && int3_injected && - kvm_is_linear_rip(vcpu, svm->int3_rip)) - kvm_rip_write(vcpu, - kvm_rip_read(vcpu) - int3_injected); + if (kvm_exception_is_soft(vector)) break; - } + if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { u32 err = svm->vmcb->control.exit_int_info_err; kvm_requeue_exception_e(vcpu, vector, err);
From: Sean Christopherson seanjc@google.com
[ Upstream commit 3741aec4c38fa4123ab08ae552f05366d4fd05d8 ]
If NRIPS is supported in hardware but disabled in KVM, set next_rip to the next RIP when advancing RIP as part of emulating INT3 injection. There is no flag to tell the CPU that KVM isn't using next_rip, and so leaving next_rip is left as is will result in the CPU pushing garbage onto the stack when vectoring the injected event.
Reviewed-by: Maxim Levitsky mlevitsk@redhat.com Fixes: 66b7138f9136 ("KVM: SVM: Emulate nRIP feature when reinjecting INT3") Signed-off-by: Sean Christopherson seanjc@google.com Signed-off-by: Maciej S. Szmigiero maciej.szmigiero@oracle.com Message-Id: cd328309a3b88604daa2359ad56f36cb565ce2d4.1651440202.git.maciej.szmigiero@oracle.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kvm/svm/svm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index fe8536c57fd7..92b30b4937fc 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -392,6 +392,10 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu) */ (void)svm_skip_emulated_instruction(vcpu); rip = kvm_rip_read(vcpu); + + if (boot_cpu_has(X86_FEATURE_NRIPS)) + svm->vmcb->control.next_rip = rip; + svm->int3_rip = rip + svm->vmcb->save.cs.base; svm->int3_injected = rip - old_rip; } @@ -3702,7 +3706,7 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu) /* * If NextRIP isn't enabled, KVM must manually advance RIP prior to * injecting the soft exception/interrupt. That advancement needs to - * be unwound if vectoring didn't complete. Note, the _new_ event may + * be unwound if vectoring didn't complete. Note, the new event may * not be the injected event, e.g. if KVM injected an INTn, the INTn * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will * be the reported vectored event, but RIP still needs to be unwound.
From: Sean Christopherson seanjc@google.com
[ Upstream commit 9fb3565743d58352f00964bf47213b88aff4bb82 ]
All of sync_page()'s existing checks filter out only !PRESENT gPTE, because without execute-only, all upper levels are guaranteed to be at least READABLE. However, if EPT with execute-only support is in use by L1, KVM can create an SPTE that is shadow-present but guest-inaccessible (RWX=0) if the upper level combined permissions are R (or RW) and the leaf EPTE is changed from R (or RW) to X. Because the EPTE is considered present when viewed in isolation, and no reserved bits are set, FNAME(prefetch_invalid_gpte) will consider the GPTE valid, and cause a not-present SPTE to be created.
The SPTE is "correct": the guest translation is inaccessible because the combined protections of all levels yield RWX=0, and KVM will just redirect any vmexits to the guest. If EPT A/D bits are disabled, KVM can mistake the SPTE for an access-tracked SPTE, but again such confusion isn't fatal, as the "saved" protections are also RWX=0. However, creating a useless SPTE in general means that KVM messed up something, even if this particular goof didn't manifest as a functional bug. So, drop SPTEs whose new protections will yield a RWX=0 SPTE, and add a WARN in make_spte() to detect creation of SPTEs that will result in RWX=0 protections.
Fixes: d95c55687e11 ("kvm: mmu: track read permission explicitly for shadow EPT page tables") Cc: David Matlack dmatlack@google.com Cc: Ben Gardon bgardon@google.com Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220513195000.99371-2-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kvm/mmu/paging_tmpl.h | 9 ++++++++- arch/x86/kvm/mmu/spte.c | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index db80f7ccaa4e..1576e65b3b1f 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -1053,7 +1053,14 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) if (sync_mmio_spte(vcpu, &sp->spt[i], gfn, pte_access)) continue;
- if (gfn != sp->gfns[i]) { + /* + * Drop the SPTE if the new protections would result in a RWX=0 + * SPTE or if the gfn is changing. The RWX=0 case only affects + * EPT with execute-only support, i.e. EPT without an effective + * "present" bit, as all other paging modes will create a + * read-only SPTE if pte_access is zero. + */ + if ((!pte_access && !shadow_present_mask) || gfn != sp->gfns[i]) { drop_spte(vcpu->kvm, &sp->spt[i]); flush = true; continue; diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c index ba1be0159095..186fa97d4375 100644 --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -143,6 +143,8 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, u64 spte = SPTE_MMU_PRESENT_MASK; bool wrprot = false;
+ WARN_ON_ONCE(!pte_access && !shadow_present_mask); + if (sp->role.ad_disabled) spte |= SPTE_TDP_AD_DISABLED_MASK; else if (kvm_mmu_page_ad_need_write_protect(sp))
From: Chanho Park chanho61.park@samsung.com
[ Upstream commit f7fdc4db071f7ee7d408ea3f083222a060c76623 ]
For exynos auto v9's UFS MPHY, We should use 0x50 offset of TSRV register configurations. So, it must be
s/PHY_TRSV_REG_CFG/PHY_TRSV_REG_CFG_AUTOV9/g
Fixes: d64519249e1d ("phy: samsung-ufs: support exynosauto ufs phy driver") Signed-off-by: Chanho Park chanho61.park@samsung.com Acked-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220603050536.61957-1-chanho61.park@samsung.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/samsung/phy-exynosautov9-ufs.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/phy/samsung/phy-exynosautov9-ufs.c b/drivers/phy/samsung/phy-exynosautov9-ufs.c index 36398a15c2db..d043dfdb598a 100644 --- a/drivers/phy/samsung/phy-exynosautov9-ufs.c +++ b/drivers/phy/samsung/phy-exynosautov9-ufs.c @@ -31,22 +31,22 @@ static const struct samsung_ufs_phy_cfg exynosautov9_pre_init_cfg[] = { PHY_COMN_REG_CFG(0x023, 0xc0, PWR_MODE_ANY), PHY_COMN_REG_CFG(0x023, 0x00, PWR_MODE_ANY),
- PHY_TRSV_REG_CFG(0x042, 0x5d, PWR_MODE_ANY), - PHY_TRSV_REG_CFG(0x043, 0x80, PWR_MODE_ANY), + PHY_TRSV_REG_CFG_AUTOV9(0x042, 0x5d, PWR_MODE_ANY), + PHY_TRSV_REG_CFG_AUTOV9(0x043, 0x80, PWR_MODE_ANY),
END_UFS_PHY_CFG, };
/* Calibration for HS mode series A/B */ static const struct samsung_ufs_phy_cfg exynosautov9_pre_pwr_hs_cfg[] = { - PHY_TRSV_REG_CFG(0x032, 0xbc, PWR_MODE_HS_ANY), - PHY_TRSV_REG_CFG(0x03c, 0x7f, PWR_MODE_HS_ANY), - PHY_TRSV_REG_CFG(0x048, 0xc0, PWR_MODE_HS_ANY), + PHY_TRSV_REG_CFG_AUTOV9(0x032, 0xbc, PWR_MODE_HS_ANY), + PHY_TRSV_REG_CFG_AUTOV9(0x03c, 0x7f, PWR_MODE_HS_ANY), + PHY_TRSV_REG_CFG_AUTOV9(0x048, 0xc0, PWR_MODE_HS_ANY),
- PHY_TRSV_REG_CFG(0x04a, 0x00, PWR_MODE_HS_G3_SER_B), - PHY_TRSV_REG_CFG(0x04b, 0x10, PWR_MODE_HS_G1_SER_B | - PWR_MODE_HS_G3_SER_B), - PHY_TRSV_REG_CFG(0x04d, 0x63, PWR_MODE_HS_G3_SER_B), + PHY_TRSV_REG_CFG_AUTOV9(0x04a, 0x00, PWR_MODE_HS_G3_SER_B), + PHY_TRSV_REG_CFG_AUTOV9(0x04b, 0x10, PWR_MODE_HS_G1_SER_B | + PWR_MODE_HS_G3_SER_B), + PHY_TRSV_REG_CFG_AUTOV9(0x04d, 0x63, PWR_MODE_HS_G3_SER_B),
END_UFS_PHY_CFG, };
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit f030304fdeb87ec8f1b518c73703214aec6cc24a ]
of_get_next_child() returns a node pointer with refcount incremented, so we should use of_node_put() on it when we don't need it anymore.
mc_pcie_init_irq_domains() only calls of_node_put() in the normal path, missing it in some error paths. Add missing of_node_put() to avoid refcount leak.
Fixes: 6f15a9c9f941 ("PCI: microchip: Add Microchip PolarFire PCIe controller driver") Link: https://lore.kernel.org/r/20220605055123.59127-1-linmq006@gmail.com Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-microchip-host.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c index dd5dba419047..7263d175b5ad 100644 --- a/drivers/pci/controller/pcie-microchip-host.c +++ b/drivers/pci/controller/pcie-microchip-host.c @@ -904,6 +904,7 @@ static int mc_pcie_init_irq_domains(struct mc_pcie *port) &event_domain_ops, port); if (!port->event_domain) { dev_err(dev, "failed to get event domain\n"); + of_node_put(pcie_intc_node); return -ENOMEM; }
@@ -913,6 +914,7 @@ static int mc_pcie_init_irq_domains(struct mc_pcie *port) &intx_domain_ops, port); if (!port->intx_domain) { dev_err(dev, "failed to get an INTx IRQ domain\n"); + of_node_put(pcie_intc_node); return -ENOMEM; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit e8fbd344a5ea62663554b8546b6bf9f88b93785a ]
pm_runtime_enable() will increase power disable depth. If dw_pcie_ep_init() fails, we should use pm_runtime_disable() to balance it with pm_runtime_enable().
Add missing pm_runtime_disable() for tegra_pcie_config_ep().
Fixes: c57247f940e8 ("PCI: tegra: Add support for PCIe endpoint mode in Tegra194") Link: https://lore.kernel.org/r/20220602031910.55859-1-linmq006@gmail.com Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Vidya Sagar vidyas@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-tegra194.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index cc2678490162..d992371a36e6 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -1949,6 +1949,7 @@ static int tegra_pcie_config_ep(struct tegra194_pcie *pcie, if (ret) { dev_err(dev, "Failed to initialize DWC Endpoint subsystem: %d\n", ret); + pm_runtime_disable(dev); return ret; }
From: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
[ Upstream commit 381583845d19cb4bd21c8193449385f3fefa9caf ]
Smatch warnings: drivers/hid/hid-cp2112.c:793 cp2112_xfer() error: __memcpy() 'data->block[1]' too small (33 vs 255) drivers/hid/hid-cp2112.c:793 cp2112_xfer() error: __memcpy() 'buf' too small (64 vs 255)
The 'read_length' variable is provided by 'data->block[0]' which comes from user and it(read_length) can take a value between 0-255. Add an upper bound to 'read_length' variable to prevent a buffer overflow in memcpy().
Fixes: 542134c0375b ("HID: cp2112: Fix I2C_BLOCK_DATA transactions") Signed-off-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-cp2112.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c index ece147d1a278..1e16b0fa310d 100644 --- a/drivers/hid/hid-cp2112.c +++ b/drivers/hid/hid-cp2112.c @@ -790,6 +790,11 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, data->word = le16_to_cpup((__le16 *)buf); break; case I2C_SMBUS_I2C_BLOCK_DATA: + if (read_length > I2C_SMBUS_BLOCK_MAX) { + ret = -EINVAL; + goto power_normal; + } + memcpy(data->block + 1, buf, read_length); break; case I2C_SMBUS_BLOCK_DATA:
From: Duoming Zhou duoming@zju.edu.cn
[ Upstream commit a61528d997619a518ee8c51cf0ef0513021afaff ]
There is a deadlock between sm_release and sm_cache_flush_work which is a work item. The cancel_work_sync in sm_release will not return until sm_cache_flush_work is finished. If we hold mutex_lock and use cancel_work_sync to wait the work item to finish, the work item also requires mutex_lock. As a result, the sm_release will be blocked forever. The race condition is shown below:
(Thread 1) | (Thread 2) sm_release | mutex_lock(&ftl->mutex) | sm_cache_flush_work | mutex_lock(&ftl->mutex) cancel_work_sync | ...
This patch moves del_timer_sync and cancel_work_sync out of mutex_lock in order to mitigate deadlock.
Fixes: 7d17c02a01a1 ("mtd: Add new SmartMedia/xD FTL") Signed-off-by: Duoming Zhou duoming@zju.edu.cn Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220524044841.10517-1-duoming@zju.edu.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/sm_ftl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index 0cff2cda1b5a..7f955fade838 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c @@ -1111,9 +1111,9 @@ static void sm_release(struct mtd_blktrans_dev *dev) { struct sm_ftl *ftl = dev->priv;
- mutex_lock(&ftl->mutex); del_timer_sync(&ftl->timer); cancel_work_sync(&ftl->flush_work); + mutex_lock(&ftl->mutex); sm_cache_flush(ftl); mutex_unlock(&ftl->mutex); }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 9f7e62815cf3cbbcb1b8cb21649fb4dfdb3aa016 ]
of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: 237960880960 ("mtd: partitions: redboot: seek fis-index-block in the right node") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220526110652.64849-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/parsers/redboot.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/parsers/redboot.c b/drivers/mtd/parsers/redboot.c index feb44a573d44..a16b42a88581 100644 --- a/drivers/mtd/parsers/redboot.c +++ b/drivers/mtd/parsers/redboot.c @@ -58,6 +58,7 @@ static void parse_redboot_of(struct mtd_info *master) return;
ret = of_property_read_u32(npart, "fis-index-block", &dirblock); + of_node_put(npart); if (ret) return;
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit e607879b0da18c451de5e91daf239cc2f2f8ff2d ]
of_find_node_by_path() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: bb17230c61a6 ("mtd: parsers: ofpart: support BCM4908 fixed partitions") Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220605070726.5979-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/parsers/ofpart_bcm4908.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/mtd/parsers/ofpart_bcm4908.c b/drivers/mtd/parsers/ofpart_bcm4908.c index 0eddef4c198e..bb072a0940e4 100644 --- a/drivers/mtd/parsers/ofpart_bcm4908.c +++ b/drivers/mtd/parsers/ofpart_bcm4908.c @@ -35,12 +35,15 @@ static long long bcm4908_partitions_fw_offset(void) err = kstrtoul(s + len + 1, 0, &offset); if (err) { pr_err("failed to parse %s\n", s + len + 1); + of_node_put(root); return err; }
+ of_node_put(root); return offset << 10; }
+ of_node_put(root); return -ENOENT; }
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 0057568b391488a5940635cbda562ea397bf4bdd ]
If mtd_device_unregister() fails (which it doesn't when used correctly), the resources bound by the nand chip should be freed anyhow as returning an error value doesn't prevent the device getting unbound.
Instead use WARN_ON on the return value similar to how other drivers do it.
This is a preparation for making platform remove callbacks return void.
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220603210758.148493-7-u.kleine-koenig@pe... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/devices/spear_smi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 24073518587f..f6febe6662db 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -1045,7 +1045,7 @@ static int spear_smi_remove(struct platform_device *pdev) { struct spear_smi *dev; struct spear_snor_flash *flash; - int ret, i; + int i;
dev = platform_get_drvdata(pdev); if (!dev) { @@ -1060,9 +1060,7 @@ static int spear_smi_remove(struct platform_device *pdev) continue;
/* clean up mtd stuff */ - ret = mtd_device_unregister(&flash->mtd); - if (ret) - dev_err(&pdev->dev, "error removing mtd\n"); + WARN_ON(mtd_device_unregister(&flash->mtd)); }
clk_disable_unprepare(dev->clk);
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 28607b426c3d050714f250d0faeb99d2e9106e90 ]
For all but one error path clk_disable_unprepare() is already there. Add it to the one location where it's missing.
Fixes: 481815a6193b ("mtd: st_spi_fsm: Handle clk_prepare_enable/clk_disable_unprepare.") Fixes: 69d5af8d016c ("mtd: st_spi_fsm: Obtain and use EMI clock") Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220607152458.232847-2-u.kleine-koenig@pe... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/devices/st_spi_fsm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c index d3377b10fc0f..52a799cae402 100644 --- a/drivers/mtd/devices/st_spi_fsm.c +++ b/drivers/mtd/devices/st_spi_fsm.c @@ -2115,10 +2115,12 @@ static int stfsm_probe(struct platform_device *pdev) (long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20), fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10));
- return mtd_device_register(&fsm->mtd, NULL, 0); - + ret = mtd_device_register(&fsm->mtd, NULL, 0); + if (ret) { err_clk_unprepare: - clk_disable_unprepare(fsm->clk); + clk_disable_unprepare(fsm->clk); + } + return ret; }
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 279d719be39d8edb37c9178c15e167a94c7bc0a0 ]
The remove callback is only called after probe completed successfully. In this case platform_set_drvdata() was called with a non-NULL argument and so dev is never NULL.
This is a preparation for making platform remove callbacks return void.
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220603210758.148493-8-u.kleine-koenig@pe... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/devices/spear_smi.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index f6febe6662db..f58742486d3d 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -1048,10 +1048,6 @@ static int spear_smi_remove(struct platform_device *pdev) int i;
dev = platform_get_drvdata(pdev); - if (!dev) { - dev_err(&pdev->dev, "dev is null\n"); - return -ENODEV; - }
/* clean up for all nor flash */ for (i = 0; i < dev->num_flashes; i++) {
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit cfa7847f150c4343903d8ff2cd219418c1768205 ]
mtd_device_unregister() shouldn't fail. Wail loudly if it does anyhow.
This matches how other drivers (e.g. nand/raw/nandsim.c) use mtd_device_unregister().
By returning 0 in the platform remove callback a generic error message by the device core is suppressed, nothing else changes.
This is a preparation for making platform remove callbacks return void.
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220607152458.232847-3-u.kleine-koenig@pe... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/devices/st_spi_fsm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c index 52a799cae402..a5a4b612480c 100644 --- a/drivers/mtd/devices/st_spi_fsm.c +++ b/drivers/mtd/devices/st_spi_fsm.c @@ -2130,7 +2130,9 @@ static int stfsm_remove(struct platform_device *pdev)
clk_disable_unprepare(fsm->clk);
- return mtd_device_unregister(&fsm->mtd); + WARN_ON(mtd_device_unregister(&fsm->mtd)); + + return 0; }
#ifdef CONFIG_PM_SLEEP
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit cd043c613e21bb6f039057043da759471706adf5 ]
Until mtd_device_unregister() returns the device is expected to be operational. So only disable the clock after the mtd is unregistered.
Fixes: 1fefc8ecb834 ("mtd: st_spi_fsm: add missing clk_disable_unprepare() in stfsm_remove()") Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220607152458.232847-4-u.kleine-koenig@pe... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/devices/st_spi_fsm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c index a5a4b612480c..9f6d4dd8bade 100644 --- a/drivers/mtd/devices/st_spi_fsm.c +++ b/drivers/mtd/devices/st_spi_fsm.c @@ -2128,10 +2128,10 @@ static int stfsm_remove(struct platform_device *pdev) { struct stfsm *fsm = platform_get_drvdata(pdev);
- clk_disable_unprepare(fsm->clk); - WARN_ON(mtd_device_unregister(&fsm->mtd));
+ clk_disable_unprepare(fsm->clk); + return 0; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit bf038503d5fe90189743124233fe7aeb0984e961 ]
of_get_child_by_name() returns a node pointer with refcount incremented, so we should use of_node_put() on it when we don't need it anymore.
Add missing of_node_put() to avoid refcount leak.
Fixes: 814cceebba9b ("PCI: mediatek-gen3: Add INTx support") Link: https://lore.kernel.org/r/20220601041259.56185-1-linmq006@gmail.com Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Miles Chen miles.chen@mediatek.com Acked-by: Jianjun Wang jianjun.wang@mediatek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mediatek-gen3.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 5d9fd36b02d1..a02c466a597c 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -600,7 +600,8 @@ static int mtk_pcie_init_irq_domains(struct mtk_gen3_pcie *pcie) &intx_domain_ops, pcie); if (!pcie->intx_domain) { dev_err(dev, "failed to create INTx IRQ domain\n"); - return -ENODEV; + ret = -ENODEV; + goto out_put_node; }
/* Setup MSI */ @@ -623,13 +624,15 @@ static int mtk_pcie_init_irq_domains(struct mtk_gen3_pcie *pcie) goto err_msi_domain; }
+ of_node_put(intc_node); return 0;
err_msi_domain: irq_domain_remove(pcie->msi_bottom_domain); err_msi_bottom_domain: irq_domain_remove(pcie->intx_domain); - +out_put_node: + of_node_put(intc_node); return ret; }
From: Marco Pagani marpagan@redhat.com
[ Upstream commit 2df84a757d87fd62869fc401119d429735377ec5 ]
Fix the "comparison with less than zero" warning reported by cppcheck for the unsigned (size_t) parameter count of the alt_pr_fpga_write() function.
Fixes: d201cc17a8a3 ("fpga pr ip: Core driver support for Altera Partial Reconfiguration IP") Reviewed-by: Tom Rix trix@redhat.com Acked-by: Xu Yilun yilun.xu@intel.com Signed-off-by: Marco Pagani marpagan@redhat.com Link: https://lore.kernel.org/r/20220609140520.42662-1-marpagan@redhat.com Signed-off-by: Xu Yilun yilun.xu@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/fpga/altera-pr-ip-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/fpga/altera-pr-ip-core.c b/drivers/fpga/altera-pr-ip-core.c index be0667968d33..df8671af4a92 100644 --- a/drivers/fpga/altera-pr-ip-core.c +++ b/drivers/fpga/altera-pr-ip-core.c @@ -108,7 +108,7 @@ static int alt_pr_fpga_write(struct fpga_manager *mgr, const char *buf, u32 *buffer_32 = (u32 *)buf; size_t i = 0;
- if (count <= 0) + if (!count) return -EINVAL;
/* Write out the complete 32-bit chunks */
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit b5c5b13cb45e2c88181308186b0001992cb41954 ]
of_find_compatible_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. Add missing of_node_put() to avoid refcount leak.
Fixes: 796bcae7361c ("USB: powerpc: Workaround for the PPC440EPX USBH_23 errata [take 3]") Acked-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220602110849.58549-1-linmq006@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/ehci-ppc-of.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 6bbaee74f7e7..28a19693c19f 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -148,6 +148,7 @@ static int ehci_hcd_ppc_of_probe(struct platform_device *op) } else { ehci->has_amcc_usb23 = 1; } + of_node_put(np); }
if (of_get_property(dn, "big-endian", NULL)) {
From: Frank Li Frank.Li@nxp.com
[ Upstream commit 8659ab3d936fcf0084676f98b75b317017aa8f82 ]
Warning log: [ 4.141392] Unexpected gfp: 0x4 (GFP_DMA32). Fixing up to gfp: 0xa20 (GFP_ATOMIC). Fix your code! [ 4.150340] CPU: 1 PID: 175 Comm: 1-0050 Not tainted 5.15.5-00039-g2fd9ae1b568c #20 [ 4.158010] Hardware name: Freescale i.MX8QXP MEK (DT) [ 4.163155] Call trace: [ 4.165600] dump_backtrace+0x0/0x1b0 [ 4.169286] show_stack+0x18/0x68 [ 4.172611] dump_stack_lvl+0x68/0x84 [ 4.176286] dump_stack+0x18/0x34 [ 4.179613] kmalloc_fix_flags+0x60/0x88 [ 4.183550] new_slab+0x334/0x370 [ 4.186878] ___slab_alloc.part.108+0x4d4/0x748 [ 4.191419] __slab_alloc.isra.109+0x30/0x78 [ 4.195702] kmem_cache_alloc+0x40c/0x420 [ 4.199725] dma_pool_alloc+0xac/0x1f8 [ 4.203486] cdns3_allocate_trb_pool+0xb4/0xd0
pool_alloc_page(struct dma_pool *pool, gfp_t mem_flags) { ... page = kmalloc(sizeof(*page), mem_flags); page->vaddr = dma_alloc_coherent(pool->dev, pool->allocation, &page->dma, mem_flags); ... }
kmalloc was called with mem_flags, which is passed down in cdns3_allocate_trb_pool() and have GFP_DMA32 flags. kmall_fix_flags() report warning.
GFP_DMA32 is not useful at all. dma_alloc_coherent() will handle DMA memory region correctly by pool->dev. GFP_DMA32 can be removed safely.
Signed-off-by: Frank Li Frank.Li@nxp.com Link: https://lore.kernel.org/r/20220609154456.2871672-1-Frank.Li@nxp.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/cdns3/cdns3-gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c index 5c15c48952a6..f5f5fbbefec0 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -220,7 +220,7 @@ int cdns3_allocate_trb_pool(struct cdns3_endpoint *priv_ep)
if (!priv_ep->trb_pool) { priv_ep->trb_pool = dma_pool_alloc(priv_dev->eps_dma_pool, - GFP_DMA32 | GFP_ATOMIC, + GFP_ATOMIC, &priv_ep->trb_pool_dma);
if (!priv_ep->trb_pool)
From: Laurent Pinchart laurent.pinchart@ideasonboard.com
[ Upstream commit c5d337a358b3e41bb4f7abd99a79b68a28eafaa2 ]
The UVC gadget driver historically uses the
/* Comment * style */
for multi-line block comments, which is frowned upon. Patches for the driver are required to use the more standard
/* * Comment * style */
style. This result in inconsistencies. Fix it by converting all remaining instances of the old style.
Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Link: https://lore.kernel.org/r/20220608174918.14656-1-laurent.pinchart@ideasonboa... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_uvc.c | 30 ++++++++++++++++--------- drivers/usb/gadget/function/uvc_queue.c | 6 +++-- drivers/usb/gadget/function/uvc_video.c | 12 ++++++---- 3 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index d3feeeb50841..71669e0e4d00 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -141,7 +141,8 @@ static struct usb_endpoint_descriptor uvc_fs_streaming_ep = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_XFER_ISOC, - /* The wMaxPacketSize and bInterval values will be initialized from + /* + * The wMaxPacketSize and bInterval values will be initialized from * module parameters. */ }; @@ -152,7 +153,8 @@ static struct usb_endpoint_descriptor uvc_hs_streaming_ep = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_XFER_ISOC, - /* The wMaxPacketSize and bInterval values will be initialized from + /* + * The wMaxPacketSize and bInterval values will be initialized from * module parameters. */ }; @@ -164,7 +166,8 @@ static struct usb_endpoint_descriptor uvc_ss_streaming_ep = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_XFER_ISOC, - /* The wMaxPacketSize and bInterval values will be initialized from + /* + * The wMaxPacketSize and bInterval values will be initialized from * module parameters. */ }; @@ -172,7 +175,8 @@ static struct usb_endpoint_descriptor uvc_ss_streaming_ep = { static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = { .bLength = sizeof(uvc_ss_streaming_comp), .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - /* The bMaxBurst, bmAttributes and wBytesPerInterval values will be + /* + * The bMaxBurst, bmAttributes and wBytesPerInterval values will be * initialized from module parameters. */ }; @@ -234,7 +238,8 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) if (le16_to_cpu(ctrl->wLength) > UVC_MAX_REQUEST_SIZE) return -EINVAL;
- /* Tell the complete callback to generate an event for the next request + /* + * Tell the complete callback to generate an event for the next request * that will be enqueued by UVCIOC_SEND_RESPONSE. */ uvc->event_setup_out = !(ctrl->bRequestType & USB_DIR_IN); @@ -500,7 +505,8 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) if (!uvc_control_desc || !uvc_streaming_cls) return ERR_PTR(-ENODEV);
- /* Descriptors layout + /* + * Descriptors layout * * uvc_iad * uvc_control_intf @@ -597,8 +603,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) uvcg_info(f, "%s()\n", __func__);
opts = fi_to_f_uvc_opts(f->fi); - /* Sanity check the streaming endpoint module parameters. - */ + /* Sanity check the streaming endpoint module parameters. */ opts->streaming_interval = clamp(opts->streaming_interval, 1U, 16U); opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U); opts->streaming_maxburst = min(opts->streaming_maxburst, 15U); @@ -611,7 +616,8 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) opts->streaming_maxpacket); }
- /* Fill in the FS/HS/SS Video Streaming specific descriptors from the + /* + * Fill in the FS/HS/SS Video Streaming specific descriptors from the * module parameters. * * NOTE: We assume that the user knows what they are doing and won't @@ -895,7 +901,8 @@ static void uvc_function_unbind(struct usb_configuration *c,
uvcg_info(f, "%s()\n", __func__);
- /* If we know we're connected via v4l2, then there should be a cleanup + /* + * If we know we're connected via v4l2, then there should be a cleanup * of the device from userspace either via UVC_EVENT_DISCONNECT or * though the video device removal uevent. Allow some time for the * application to close out before things get deleted. @@ -912,7 +919,8 @@ static void uvc_function_unbind(struct usb_configuration *c, v4l2_device_unregister(&uvc->v4l2_dev);
if (uvc->func_connected) { - /* Wait for the release to occur to ensure there are no longer any + /* + * Wait for the release to occur to ensure there are no longer any * pending operations that may cause panics when resources are cleaned * up. */ diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index d25edc3d2174..951934aa4454 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -104,7 +104,8 @@ static void uvc_buffer_queue(struct vb2_buffer *vb) if (likely(!(queue->flags & UVC_QUEUE_DISCONNECTED))) { list_add_tail(&buf->queue, &queue->irqqueue); } else { - /* If the device is disconnected return the buffer to userspace + /* + * If the device is disconnected return the buffer to userspace * directly. The next QBUF call will fail with -ENODEV. */ buf->state = UVC_BUF_STATE_ERROR; @@ -255,7 +256,8 @@ void uvcg_queue_cancel(struct uvc_video_queue *queue, int disconnect) } queue->buf_used = 0;
- /* This must be protected by the irqlock spinlock to avoid race + /* + * This must be protected by the irqlock spinlock to avoid race * conditions between uvc_queue_buffer and the disconnection event that * could result in an interruptible wait in uvc_dequeue_buffer. Do not * blindly replace this logic by checking for the UVC_DEV_DISCONNECTED diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index d42bb3346745..ce421d9cc241 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -378,7 +378,8 @@ static void uvcg_video_pump(struct work_struct *work) int ret;
while (video->ep->enabled) { - /* Retrieve the first available USB request, protected by the + /* + * Retrieve the first available USB request, protected by the * request lock. */ spin_lock_irqsave(&video->req_lock, flags); @@ -391,7 +392,8 @@ static void uvcg_video_pump(struct work_struct *work) list_del(&req->list); spin_unlock_irqrestore(&video->req_lock, flags);
- /* Retrieve the first available video buffer and fill the + /* + * Retrieve the first available video buffer and fill the * request, protected by the video queue irqlock. */ spin_lock_irqsave(&queue->irqlock, flags); @@ -403,9 +405,11 @@ static void uvcg_video_pump(struct work_struct *work)
video->encode(req, video, buf);
- /* With usb3 we have more requests. This will decrease the + /* + * With usb3 we have more requests. This will decrease the * interrupt load to a quarter but also catches the corner - * cases, which needs to be handled */ + * cases, which needs to be handled. + */ if (list_empty(&video->req_free) || buf->state == UVC_BUF_STATE_DONE || !(video->req_int_count %
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 302970b4cad3ebfda2c05ce06c322ccdc447d17e ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: 73108aa90cbf ("USB: ohci-nxp: Use isp1301 driver") Acked-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220603141231.979-1-linmq006@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/ohci-nxp.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index 85878e8ad331..106a6bcefb08 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c @@ -164,6 +164,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev) }
isp1301_i2c_client = isp1301_get_client(isp1301_node); + of_node_put(isp1301_node); if (!isp1301_i2c_client) return -EPROBE_DEFER;
From: Tang Bin tangbin@cmss.chinamobile.com
[ Upstream commit f08aa7c80dac27ee00fa6827f447597d2fba5465 ]
dev_pm_domain_attach_by_name() may return NULL in some cases, so IS_ERR() doesn't meet the requirements. Thus fix it.
Fixes: 49db427232fe ("usb: gadget: Add UDC driver for tegra XUSB device mode controller") Signed-off-by: Tang Bin tangbin@cmss.chinamobile.com Link: https://lore.kernel.org/r/20220525135332.23144-1-tangbin@cmss.chinamobile.co... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/udc/tegra-xudc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c index 6d31ccf6aee5..3c37effdfa64 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -3691,15 +3691,15 @@ static int tegra_xudc_powerdomain_init(struct tegra_xudc *xudc) int err;
xudc->genpd_dev_device = dev_pm_domain_attach_by_name(dev, "dev"); - if (IS_ERR(xudc->genpd_dev_device)) { - err = PTR_ERR(xudc->genpd_dev_device); + if (IS_ERR_OR_NULL(xudc->genpd_dev_device)) { + err = PTR_ERR(xudc->genpd_dev_device) ? : -ENODATA; dev_err(dev, "failed to get device power domain: %d\n", err); return err; }
xudc->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "ss"); - if (IS_ERR(xudc->genpd_dev_ss)) { - err = PTR_ERR(xudc->genpd_dev_ss); + if (IS_ERR_OR_NULL(xudc->genpd_dev_ss)) { + err = PTR_ERR(xudc->genpd_dev_ss) ? : -ENODATA; dev_err(dev, "failed to get SuperSpeed power domain: %d\n", err); return err; }
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 62e4efe3375eb30292dabaec4481dc04550d3644 ]
This code does:
spin_unlock_irq(&udc->ud.lock); spin_unlock_irqrestore(&udc->lock, flags);
which does not make sense. In theory, the first unlock could enable IRQs and then the second _irqrestore could disable them again. There would be a brief momemt where IRQs were enabled improperly.
In real life, however, this function is always called with IRQs enabled and the bug does not affect runtime.
Reviewed-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/Yo4hVWcZNYzKEkIQ@kili Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/usbip/vudc_sysfs.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/usbip/vudc_sysfs.c b/drivers/usb/usbip/vudc_sysfs.c index d1cf6b51bf85..c95e6b2bfd32 100644 --- a/drivers/usb/usbip/vudc_sysfs.c +++ b/drivers/usb/usbip/vudc_sysfs.c @@ -128,7 +128,7 @@ static ssize_t usbip_sockfd_store(struct device *dev, goto unlock; }
- spin_lock_irq(&udc->ud.lock); + spin_lock(&udc->ud.lock);
if (udc->ud.status != SDEV_ST_AVAILABLE) { ret = -EINVAL; @@ -150,7 +150,7 @@ static ssize_t usbip_sockfd_store(struct device *dev, }
/* unlock and create threads and get tasks */ - spin_unlock_irq(&udc->ud.lock); + spin_unlock(&udc->ud.lock); spin_unlock_irqrestore(&udc->lock, flags);
tcp_rx = kthread_create(&v_rx_loop, &udc->ud, "vudc_rx"); @@ -173,14 +173,14 @@ static ssize_t usbip_sockfd_store(struct device *dev,
/* lock and update udc->ud state */ spin_lock_irqsave(&udc->lock, flags); - spin_lock_irq(&udc->ud.lock); + spin_lock(&udc->ud.lock);
udc->ud.tcp_socket = socket; udc->ud.tcp_rx = tcp_rx; udc->ud.tcp_tx = tcp_tx; udc->ud.status = SDEV_ST_USED;
- spin_unlock_irq(&udc->ud.lock); + spin_unlock(&udc->ud.lock);
ktime_get_ts64(&udc->start_time); v_start_timer(udc); @@ -201,12 +201,12 @@ static ssize_t usbip_sockfd_store(struct device *dev, goto unlock; }
- spin_lock_irq(&udc->ud.lock); + spin_lock(&udc->ud.lock); if (udc->ud.status != SDEV_ST_USED) { ret = -EINVAL; goto unlock_ud; } - spin_unlock_irq(&udc->ud.lock); + spin_unlock(&udc->ud.lock);
usbip_event_add(&udc->ud, VUDC_EVENT_DOWN); } @@ -219,7 +219,7 @@ static ssize_t usbip_sockfd_store(struct device *dev, sock_err: sockfd_put(socket); unlock_ud: - spin_unlock_irq(&udc->ud.lock); + spin_unlock(&udc->ud.lock); unlock: spin_unlock_irqrestore(&udc->lock, flags); mutex_unlock(&udc->ud.sysfs_lock);
From: Clément Léger clement.leger@bootlin.com
[ Upstream commit 1e073e3ed9ff9ec14e7e360ed89a81256d895588 ]
When Linux is running under OP-TEE, the SFR is set as secured and thus the AT91_OHCIICR_USB_SUSPEND register isn't accessible. Add a SMC to do the appropriate call to suspend the controller. The SMC id is fetched from the device-tree property "microchip,suspend-smc-id". if present, then the syscon regmap is not used to enter suspend and a SMC is issued.
Reviewed-by: Claudiu Beznea claudiu.beznea@microchip.com Acked-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: Clément Léger clement.leger@bootlin.com Link: https://lore.kernel.org/r/20220607133454.727063-1-clement.leger@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/ohci-at91.c | 69 ++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 23 deletions(-)
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index a24aea3d2759..98326465e2dc 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -13,6 +13,7 @@ * This file is licenced under the GPL. */
+#include <linux/arm-smccc.h> #include <linux/clk.h> #include <linux/dma-mapping.h> #include <linux/gpio/consumer.h> @@ -55,6 +56,7 @@ struct ohci_at91_priv { bool clocked; bool wakeup; /* Saved wake-up state for resume */ struct regmap *sfr_regmap; + u32 suspend_smc_id; }; /* interface and function clocks; sometimes also an AHB clock */
@@ -135,6 +137,19 @@ static void at91_stop_hc(struct platform_device *pdev)
static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
+static u32 at91_dt_suspend_smc(struct device *dev) +{ + u32 suspend_smc_id; + + if (!dev->of_node) + return 0; + + if (of_property_read_u32(dev->of_node, "microchip,suspend-smc-id", &suspend_smc_id)) + return 0; + + return suspend_smc_id; +} + static struct regmap *at91_dt_syscon_sfr(void) { struct regmap *regmap; @@ -215,9 +230,13 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, goto err; }
- ohci_at91->sfr_regmap = at91_dt_syscon_sfr(); - if (!ohci_at91->sfr_regmap) - dev_dbg(dev, "failed to find sfr node\n"); + ohci_at91->suspend_smc_id = at91_dt_suspend_smc(dev); + if (!ohci_at91->suspend_smc_id) { + dev_dbg(dev, "failed to find sfr suspend smc id, using regmap\n"); + ohci_at91->sfr_regmap = at91_dt_syscon_sfr(); + if (!ohci_at91->sfr_regmap) + dev_dbg(dev, "failed to find sfr node\n"); + }
board = hcd->self.controller->platform_data; ohci = hcd_to_ohci(hcd); @@ -303,24 +322,30 @@ static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf) return length; }
-static int ohci_at91_port_suspend(struct regmap *regmap, u8 set) +static int ohci_at91_port_suspend(struct ohci_at91_priv *ohci_at91, u8 set) { + struct regmap *regmap = ohci_at91->sfr_regmap; u32 regval; int ret;
- if (!regmap) - return 0; + if (ohci_at91->suspend_smc_id) { + struct arm_smccc_res res;
- ret = regmap_read(regmap, AT91_SFR_OHCIICR, ®val); - if (ret) - return ret; + arm_smccc_smc(ohci_at91->suspend_smc_id, set, 0, 0, 0, 0, 0, 0, &res); + if (res.a0) + return -EINVAL; + } else if (regmap) { + ret = regmap_read(regmap, AT91_SFR_OHCIICR, ®val); + if (ret) + return ret;
- if (set) - regval |= AT91_OHCIICR_USB_SUSPEND; - else - regval &= ~AT91_OHCIICR_USB_SUSPEND; + if (set) + regval |= AT91_OHCIICR_USB_SUSPEND; + else + regval &= ~AT91_OHCIICR_USB_SUSPEND;
- regmap_write(regmap, AT91_SFR_OHCIICR, regval); + regmap_write(regmap, AT91_SFR_OHCIICR, regval); + }
return 0; } @@ -357,9 +382,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
case USB_PORT_FEAT_SUSPEND: dev_dbg(hcd->self.controller, "SetPortFeat: SUSPEND\n"); - if (valid_port(wIndex) && ohci_at91->sfr_regmap) { - ohci_at91_port_suspend(ohci_at91->sfr_regmap, - 1); + if (valid_port(wIndex)) { + ohci_at91_port_suspend(ohci_at91, 1); return 0; } break; @@ -400,9 +424,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
case USB_PORT_FEAT_SUSPEND: dev_dbg(hcd->self.controller, "ClearPortFeature: SUSPEND\n"); - if (valid_port(wIndex) && ohci_at91->sfr_regmap) { - ohci_at91_port_suspend(ohci_at91->sfr_regmap, - 0); + if (valid_port(wIndex)) { + ohci_at91_port_suspend(ohci_at91, 0); return 0; } break; @@ -630,10 +653,10 @@ ohci_hcd_at91_drv_suspend(struct device *dev) /* flush the writes */ (void) ohci_readl (ohci, &ohci->regs->control); msleep(1); - ohci_at91_port_suspend(ohci_at91->sfr_regmap, 1); + ohci_at91_port_suspend(ohci_at91, 1); at91_stop_clock(ohci_at91); } else { - ohci_at91_port_suspend(ohci_at91->sfr_regmap, 1); + ohci_at91_port_suspend(ohci_at91, 1); }
return ret; @@ -645,7 +668,7 @@ ohci_hcd_at91_drv_resume(struct device *dev) struct usb_hcd *hcd = dev_get_drvdata(dev); struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd);
- ohci_at91_port_suspend(ohci_at91->sfr_regmap, 0); + ohci_at91_port_suspend(ohci_at91, 0);
if (ohci_at91->wakeup) disable_irq_wake(hcd->irq);
From: Tang Bin tangbin@cmss.chinamobile.com
[ Upstream commit 18fc7c435be3f17ea26a21b2e2312fcb9088e01f ]
In the function tegra_xusb_powerdomain_init(), dev_pm_domain_attach_by_name() may return NULL in some cases, so IS_ERR() doesn't meet the requirements. Thus fix it.
Fixes: 6494a9ad86de ("usb: xhci: tegra: Add genpd support") Signed-off-by: Tang Bin tangbin@cmss.chinamobile.com Link: https://lore.kernel.org/r/20220524121404.18376-1-tangbin@cmss.chinamobile.co... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-tegra.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 996958a6565c..bdb776553826 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -1010,15 +1010,15 @@ static int tegra_xusb_powerdomain_init(struct device *dev, int err;
tegra->genpd_dev_host = dev_pm_domain_attach_by_name(dev, "xusb_host"); - if (IS_ERR(tegra->genpd_dev_host)) { - err = PTR_ERR(tegra->genpd_dev_host); + if (IS_ERR_OR_NULL(tegra->genpd_dev_host)) { + err = PTR_ERR(tegra->genpd_dev_host) ? : -ENODATA; dev_err(dev, "failed to get host pm-domain: %d\n", err); return err; }
tegra->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "xusb_ss"); - if (IS_ERR(tegra->genpd_dev_ss)) { - err = PTR_ERR(tegra->genpd_dev_ss); + if (IS_ERR_OR_NULL(tegra->genpd_dev_ss)) { + err = PTR_ERR(tegra->genpd_dev_ss) ? : -ENODATA; dev_err(dev, "failed to get superspeed pm-domain: %d\n", err); return err; }
From: Miquel Raynal miquel.raynal@bootlin.com
[ Upstream commit 2717d33841957a0f5fb65fd8b37f9c2321593864 ]
This is a tristate driver that can be built as a module, as a result, the OF match table should be exported with MODULE_DEVICE_TABLE().
Fixes: 134d9c52fca2 ("dmaengine: dw: dmamux: Introduce RZN1 DMA router support") Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20220609141455.300879-1-miquel.raynal@bootlin.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/dw/rzn1-dmamux.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/dma/dw/rzn1-dmamux.c b/drivers/dma/dw/rzn1-dmamux.c index 11d254e450b0..0ce4fb58185e 100644 --- a/drivers/dma/dw/rzn1-dmamux.c +++ b/drivers/dma/dw/rzn1-dmamux.c @@ -140,6 +140,7 @@ static const struct of_device_id rzn1_dmamux_match[] = { { .compatible = "renesas,rzn1-dmamux" }, {} }; +MODULE_DEVICE_TABLE(of, rzn1_dmamux_match);
static struct platform_driver rzn1_dmamux_driver = { .driver = {
From: Miquel Raynal miquel.raynal@bootlin.com
[ Upstream commit 7811f2e7fd6a30d96eaa1fccf57b07694a8cad27 ]
When built without OF support, of_match_node() expands to NULL, which produces the following output:
drivers/dma/dw/rzn1-dmamux.c:105:34: warning: unused variable 'rzn1_dmac_match' [-Wunused-const-variable]
static const struct of_device_id rzn1_dmac_match[] = {
One way to silence the warning is to enclose the structure definition with an #ifdef CONFIG_OF/#endif block.
Fixes: 134d9c52fca2 ("dmaengine: dw: dmamux: Introduce RZN1 DMA router support") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20220609141455.300879-2-miquel.raynal@bootlin.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/dw/rzn1-dmamux.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/dma/dw/rzn1-dmamux.c b/drivers/dma/dw/rzn1-dmamux.c index 0ce4fb58185e..f9912c3dd4d7 100644 --- a/drivers/dma/dw/rzn1-dmamux.c +++ b/drivers/dma/dw/rzn1-dmamux.c @@ -102,10 +102,12 @@ static void *rzn1_dmamux_route_allocate(struct of_phandle_args *dma_spec, return ERR_PTR(ret); }
+#ifdef CONFIG_OF static const struct of_device_id rzn1_dmac_match[] = { { .compatible = "renesas,rzn1-dma" }, {} }; +#endif
static int rzn1_dmamux_probe(struct platform_device *pdev) {
From: Thomas Gleixner tglx@linutronix.de
[ Upstream commit 20646f5b1e798bcc20044ae90ac3702f177bf254 ]
Commit e2be04c7f995 ("License cleanup: add SPDX license identifier to uapi header files with a license") added the correct SPDX identifier to include/uapi/linux/netfilter/xt_IDLETIMER.h.
A subsequent commit removed it for no reason and reintroduced the UAPI license incorrectness as the file is now missing the UAPI exception again.
Add it back and remove the GPLv2 boilerplate while at it.
Fixes: 68983a354a65 ("netfilter: xtables: Add snapshot of hardidletimer target") Cc: Manoj Basapathi manojbm@codeaurora.org Cc: Subash Abhinov Kasiviswanathan subashab@codeaurora.org Cc: Pablo Neira Ayuso pablo@netfilter.org Cc: netfilter-devel@vger.kernel.org Signed-off-by: Thomas Gleixner tglx@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/uapi/linux/netfilter/xt_IDLETIMER.h | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_IDLETIMER.h b/include/uapi/linux/netfilter/xt_IDLETIMER.h index 49ddcdc61c09..7bfb31a66fc9 100644 --- a/include/uapi/linux/netfilter/xt_IDLETIMER.h +++ b/include/uapi/linux/netfilter/xt_IDLETIMER.h @@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* - * linux/include/linux/netfilter/xt_IDLETIMER.h - * * Header file for Xtables timer target module. * * Copyright (C) 2004, 2010 Nokia Corporation @@ -10,20 +9,6 @@ * by Luciano Coelho luciano.coelho@nokia.com * * Contact: Luciano Coelho luciano.coelho@nokia.com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA */
#ifndef _XT_IDLETIMER_H
From: Quinn Tran qutran@marvell.com
[ Upstream commit 2b659ed67a12f39f56d8dcad9b5d5a74d67c01b3 ]
If the session is down and the local port continues to receive AUTH ELS messages, the driver needs to send back LOGO so that the remote device knows to tear down its session. Terminate and clean up the AUTH ELS exchange followed by a passthrough LOGO.
Link: https://lore.kernel.org/r/20220608115849.16693-3-njavali@marvell.com Fixes: 225479296c4f ("scsi: qla2xxx: edif: Reject AUTH ELS on session down") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 19 +++++++++++++++++-- drivers/scsi/qla2xxx/qla_fw.h | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index bd5740f23e76..f9f4c4a6afcc 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -2643,8 +2643,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
fcport = qla2x00_find_fcport_by_pid(host, &purex->pur_info.pur_sid);
- if (DBELL_INACTIVE(vha) || - (fcport && EDIF_SESSION_DOWN(fcport))) { + if (DBELL_INACTIVE(vha)) { ql_dbg(ql_dbg_edif, host, 0x0910c, "%s e_dbell.db_flags =%x %06x\n", __func__, host->e_dbell.db_flags, fcport ? fcport->d_id.b24 : 0); @@ -2654,6 +2653,22 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp) return; }
+ if (fcport && EDIF_SESSION_DOWN(fcport)) { + ql_dbg(ql_dbg_edif, host, 0x13b6, + "%s terminate exchange. Send logo to 0x%x\n", + __func__, a.did.b24); + + a.tx_byte_count = a.tx_len = 0; + a.tx_addr = 0; + a.control_flags = EPD_RX_XCHG; /* EPD_RX_XCHG = terminate cmd */ + qla_els_reject_iocb(host, (*rsp)->qpair, &a); + qla_enode_free(host, ptr); + /* send logo to let remote port knows to tear down session */ + fcport->send_els_logo = 1; + qlt_schedule_sess_for_deletion(fcport); + return; + } + /* add the local enode to the list */ qla_enode_add(host, ptr);
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 0bb1d562f0bf..361015b5763e 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -807,7 +807,7 @@ struct els_entry_24xx { #define EPD_ELS_COMMAND (0 << 13) #define EPD_ELS_ACC (1 << 13) #define EPD_ELS_RJT (2 << 13) -#define EPD_RX_XCHG (3 << 13) +#define EPD_RX_XCHG (3 << 13) /* terminate exchange */ #define ECF_CLR_PASSTHRU_PEND BIT_12 #define ECF_INCL_FRAME_HDR BIT_11 #define ECF_SEC_LOGIN BIT_3
From: Quinn Tran qutran@marvell.com
[ Upstream commit 0dbfce5255fe8d069a1a3b712a25b263264cfa58 ]
Multiple app start can trigger a session bounce. Make driver skip over session teardown if app start is seen more than once.
Link: https://lore.kernel.org/r/20220608115849.16693-4-njavali@marvell.com Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index f9f4c4a6afcc..4523ae745e55 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -510,8 +510,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) /* mark doorbell as active since an app is now present */ vha->e_dbell.db_flags |= EDB_ACTIVE; } else { - ql_dbg(ql_dbg_edif, vha, 0x911e, "%s doorbell already active\n", - __func__); + goto out; }
if (N2N_TOPO(vha->hw)) { @@ -578,6 +577,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) __func__); }
+out: appreply.host_support_edif = vha->hw->flags.edif_enabled; appreply.edif_enode_active = vha->pur_cinfo.enode_flags; appreply.edif_edb_active = vha->e_dbell.db_flags;
From: Quinn Tran qutran@marvell.com
[ Upstream commit 24c796098f5395477f7f7ebf8e24f3f08a139f71 ]
The scenario is this: User loaded driver but has not started authentication app. All sessions to secure device will exhaust all login attempts, fail, and in stay in deleted state. Then some time later the app is started. The driver will replenish the login retry count, trigger delete to prepare for secure login. After deletion, relogin is triggered.
For the session that is already deleted, the delete trigger is a no-op. If none of the sessions trigger a relogin, no progress is made.
Add a relogin trigger.
Link: https://lore.kernel.org/r/20220608115849.16693-5-njavali@marvell.com Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 4523ae745e55..c4bebbb17e92 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -567,6 +567,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) qlt_schedule_sess_for_deletion(fcport); qla_edif_sa_ctl_init(vha, fcport); } + set_bit(RELOGIN_NEEDED, &vha->dpc_flags); }
if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
From: Quinn Tran qutran@marvell.com
[ Upstream commit d7e2e4a68fc047a025afcd200e6b7e1fbc8b1999 ]
If all keys for a session have been deleted, trigger a session teardown.
Link: https://lore.kernel.org/r/20220608115849.16693-6-njavali@marvell.com Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_def.h | 5 +++++ drivers/scsi/qla2xxx/qla_isr.c | 1 + 2 files changed, 6 insertions(+)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index c2b92a6fef90..4062d46f33a6 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2158,6 +2158,11 @@ typedef struct { #define CS_IOCB_ERROR 0x31 /* Generic error for IOCB request failure */ #define CS_REJECT_RECEIVED 0x4E /* Reject received */ +#define CS_EDIF_AUTH_ERROR 0x63 /* decrypt error */ +#define CS_EDIF_PAD_LEN_ERROR 0x65 /* pad > frame size, not 4byte align */ +#define CS_EDIF_INV_REQ 0x66 /* invalid request */ +#define CS_EDIF_SPI_ERROR 0x67 /* rx frame unable to locate sa */ +#define CS_EDIF_HDR_ERROR 0x69 /* data frame != expected len */ #define CS_BAD_PAYLOAD 0x80 /* Driver defined */ #define CS_UNKNOWN 0x81 /* Driver defined */ #define CS_RETRY 0x82 /* Driver defined */ diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 5deea6bff09f..ad55eace66aa 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3424,6 +3424,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) case CS_PORT_UNAVAILABLE: case CS_TIMEOUT: case CS_RESET: + case CS_EDIF_INV_REQ:
/* * We are going to have the fc class block the rport
From: Quinn Tran qutran@marvell.com
[ Upstream commit a8fdfb0b39c2b31722c70bdf2272b949d5af4b7b ]
Current code prematurely sends out PRLI before authentication application has given the OK to do so. This causes PRLI failure and session teardown.
Prevents PRLI from going out before authentication app gives the OK.
Link: https://lore.kernel.org/r/20220608115849.16693-7-njavali@marvell.com Fixes: 91f6f5fbe87b ("scsi: qla2xxx: edif: Reduce connection thrash") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 2 +- drivers/scsi/qla2xxx/qla_edif.h | 4 ++++ drivers/scsi/qla2xxx/qla_init.c | 10 +++++++++- 3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index c4bebbb17e92..7239439120c0 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -3588,7 +3588,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job) if (qla_bsg_check(vha, bsg_job, fcport)) return 0;
- if (fcport->loop_id == FC_NO_LOOP_ID) { + if (EDIF_SESS_DELETE(fcport)) { ql_dbg(ql_dbg_edif, vha, 0x910d, "%s ELS code %x, no loop id.\n", __func__, bsg_request->rqst_data.r_els.els_code); diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h index 3561e22b8f0f..7cdb89ccdc6e 100644 --- a/drivers/scsi/qla2xxx/qla_edif.h +++ b/drivers/scsi/qla2xxx/qla_edif.h @@ -141,4 +141,8 @@ struct enode { (DBELL_ACTIVE(_fcport->vha) && \ (_fcport->disc_state == DSC_LOGIN_AUTH_PEND))
+#define EDIF_SESS_DELETE(_s) \ + (qla_ini_mode_enabled(_s->vha) && (_s->disc_state == DSC_DELETE_PEND || \ + _s->disc_state == DSC_DELETED)) + #endif /* __QLA_EDIF_H */ diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 177ce45b76a6..7bd10b4ed9ed 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1762,8 +1762,16 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) break;
case DSC_LOGIN_PEND: - if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) + if (vha->hw->flags.edif_enabled) + break; + + if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) { + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC post %s PRLI\n", + __func__, __LINE__, fcport->port_name, + NVME_TARGET(vha->hw, fcport) ? "NVME" : "FC"); qla24xx_post_prli_work(vha, fcport); + } break;
case DSC_UPD_FCPORT:
From: Quinn Tran qutran@marvell.com
[ Upstream commit ec538eb838f334453b10e7e9b260f0c358018a37 ]
The driver failed to send implicit logout on session delete. For edif, this failed to flush any lingering SA index in FW.
Set a flag to turn on implicit logout early in the session recovery to make sure the logout will go out in case of error.
Link: https://lore.kernel.org/r/20220608115849.16693-8-njavali@marvell.com Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_iocb.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 46c879923da1..42ce4e1fe744 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2882,6 +2882,9 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) sp->name, res, sp->handle, fcport->d_id.b24, fcport->port_name);
fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE); + /* For edif, set logout on delete to ensure any residual key from FW is flushed.*/ + fcport->logout_on_delete = 1; + fcport->chip_reset = vha->hw->base_qpair->chip_reset;
if (sp->flags & SRB_WAKEUP_ON_COMP) complete(&lio->u.els_plogi.comp);
From: Quinn Tran qutran@marvell.com
[ Upstream commit 37be3f9d6993a721bc019f03c97ea0fe66319997 ]
For N2N + remote WWPN is bigger than local adapter, remote adapter will login to local adapter while authentication application is not running. When authentication application starts, the current session in FW needs to to be invalidated.
Make sure the old session is torn down before triggering a relogin.
Link: https://lore.kernel.org/r/20220608115849.16693-9-njavali@marvell.com Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 47 ++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 13 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 7239439120c0..ee8931392ce2 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -517,11 +517,28 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) fcport->n2n_link_reset_cnt = 0;
- if (vha->hw->flags.n2n_fw_acc_sec) - set_bit(N2N_LINK_RESET, &vha->dpc_flags); - else + if (vha->hw->flags.n2n_fw_acc_sec) { + list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) + qla_edif_sa_ctl_init(vha, fcport); + + /* + * While authentication app was not running, remote device + * could still try to login with this local port. Let's + * clear the state and try again. + */ + qla2x00_wait_for_sess_deletion(vha); + + /* bounce the link to get the other guy to relogin */ + if (!vha->hw->flags.n2n_bigger) { + set_bit(N2N_LINK_RESET, &vha->dpc_flags); + qla2xxx_wake_dpc(vha); + } + } else { + qla2x00_wait_for_hba_online(vha); set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); - qla2xxx_wake_dpc(vha); + qla2xxx_wake_dpc(vha); + qla2x00_wait_for_hba_online(vha); + } } else { list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { ql_dbg(ql_dbg_edif, vha, 0x2058, @@ -920,17 +937,21 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24) continue;
- if (fcport->scan_state != QLA_FCPORT_FOUND) - continue; + if (!N2N_TOPO(vha->hw)) { + if (fcport->scan_state != QLA_FCPORT_FOUND) + continue;
- if (fcport->port_type == FCT_UNKNOWN && !fcport->fc4_features) - rval = qla24xx_async_gffid(vha, fcport, true); + if (fcport->port_type == FCT_UNKNOWN && + !fcport->fc4_features) + rval = qla24xx_async_gffid(vha, fcport, + true);
- if (!rval && - !(fcport->fc4_features & FC4_FF_TARGET || - fcport->port_type & - (FCT_TARGET | FCT_NVME_TARGET))) - continue; + if (!rval && + !(fcport->fc4_features & FC4_FF_TARGET || + fcport->port_type & + (FCT_TARGET | FCT_NVME_TARGET))) + continue; + }
rval = 0;
From: Jagath Jog J jagathjog1996@gmail.com
[ Upstream commit 747c7cf1592e226d40543231b26502b332d0ea2f ]
Changing the scale macro values to match the bma400 sensitivity for 1 LSB of all the available ranges.
Fixes: 465c811f1f20 ("iio: accel: Add driver for the BMA400") Signed-off-by: Jagath Jog J jagathjog1996@gmail.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Link: https://lore.kernel.org/r/20220505133021.22362-2-jagathjog1996@gmail.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/bma400.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h index c4c8d74155c2..80330c7ce17f 100644 --- a/drivers/iio/accel/bma400.h +++ b/drivers/iio/accel/bma400.h @@ -83,8 +83,27 @@ #define BMA400_ACC_ODR_MIN_WHOLE_HZ 25 #define BMA400_ACC_ODR_MIN_HZ 12
-#define BMA400_SCALE_MIN 38357 -#define BMA400_SCALE_MAX 306864 +/* + * BMA400_SCALE_MIN macro value represents m/s^2 for 1 LSB before + * converting to micro values for +-2g range. + * + * For +-2g - 1 LSB = 0.976562 milli g = 0.009576 m/s^2 + * For +-4g - 1 LSB = 1.953125 milli g = 0.019153 m/s^2 + * For +-16g - 1 LSB = 7.8125 milli g = 0.076614 m/s^2 + * + * The raw value which is used to select the different ranges is determined + * by the first bit set position from the scale value, so BMA400_SCALE_MIN + * should be odd. + * + * Scale values for +-2g, +-4g, +-8g and +-16g are populated into bma400_scales + * array by left shifting BMA400_SCALE_MIN. + * e.g.: + * To select +-2g = 9577 << 0 = raw value to write is 0. + * To select +-8g = 9577 << 2 = raw value to write is 2. + * To select +-16g = 9577 << 3 = raw value to write is 3. + */ +#define BMA400_SCALE_MIN 9577 +#define BMA400_SCALE_MAX 76617
#define BMA400_NUM_REGULATORS 2 #define BMA400_VDD_REGULATOR 0
From: Stephen Boyd swboyd@chromium.org
[ Upstream commit 74bb746407bf0d7c7d126c7731dbcd66d467619b ]
The last resume result exposing logic in cros_ec_sleep_event() incorrectly requires S0ix support, which doesn't work on ARM based systems where S0ix doesn't exist. That's because cros_ec_sleep_event() only reports the last resume result when the EC indicates the last sleep event was an S0ix resume. On ARM systems, the last sleep event is always S3 resume, but the EC can still detect sleep hang events in case some other part of the AP is blocking sleep.
Always expose the last resume result if the EC supports it so that this works on all devices regardless of S0ix support. This fixes sleep hang detection on ARM based chromebooks like Trogdor.
Cc: Rajat Jain rajatja@chromium.org Cc: Matthias Kaehlcke mka@chromium.org Cc: Hsin-Yi Wang hsinyi@chromium.org Cc: Tzung-Bi Shih tzungbi@kernel.org Reviewed-by: Guenter Roeck groeck@chromium.org Reviewed-by: Evan Green evgreen@chromium.org Fixes: 7235560ac77a ("platform/chrome: Add support for v1 of host sleep event") Signed-off-by: Stephen Boyd swboyd@chromium.org Signed-off-by: Tzung-Bi Shih tzungbi@kernel.org Link: https://lore.kernel.org/r/20220614075726.2729987-1-swboyd@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/chrome/cros_ec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c index b3e94cdf7d1a..00381490dd3e 100644 --- a/drivers/platform/chrome/cros_ec.c +++ b/drivers/platform/chrome/cros_ec.c @@ -135,16 +135,16 @@ static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event) buf.msg.command = EC_CMD_HOST_SLEEP_EVENT;
ret = cros_ec_cmd_xfer_status(ec_dev, &buf.msg); - - /* For now, report failure to transition to S0ix with a warning. */ + /* Report failure to transition to system wide suspend with a warning. */ if (ret >= 0 && ec_dev->host_sleep_v1 && - (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME)) { + (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME || + sleep_event == HOST_SLEEP_EVENT_S3_RESUME)) { ec_dev->last_resume_result = buf.u.resp1.resume_response.sleep_transitions;
WARN_ONCE(buf.u.resp1.resume_response.sleep_transitions & EC_HOST_RESUME_SLEEP_TIMEOUT, - "EC detected sleep transition timeout. Total slp_s0 transitions: %d", + "EC detected sleep transition timeout. Total sleep transitions: %d", buf.u.resp1.resume_response.sleep_transitions & EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK); }
From: Gwendal Grignou gwendal@chromium.org
[ Upstream commit 0b24034c7ffa20bcfb4fdfece1df770ec5b0a634 ]
Field for PROX_CTRL4 should contain PROX_CTRL4.
Fixes: 4c18a890dff8d ("iio:proximity:sx9324: Add SX9324 support") Signed-off-by: Gwendal Grignou gwendal@chromium.org Reviewed-by: Stephen Boyd swboyd@chromium.org Link: https://lore.kernel.org/r/20220429220144.1476049-3-gwendal@chromium.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/proximity/sx9324.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/proximity/sx9324.c b/drivers/iio/proximity/sx9324.c index 63fbcaa4cac8..a30ac8007a3d 100644 --- a/drivers/iio/proximity/sx9324.c +++ b/drivers/iio/proximity/sx9324.c @@ -93,7 +93,7 @@ #define SX9324_REG_PROX_CTRL4_AVGNEGFILT_MASK GENMASK(5, 3) #define SX9324_REG_PROX_CTRL4_AVGNEG_FILT_2 0x08 #define SX9324_REG_PROX_CTRL4_AVGPOSFILT_MASK GENMASK(2, 0) -#define SX9324_REG_PROX_CTRL3_AVGPOS_FILT_256 0x04 +#define SX9324_REG_PROX_CTRL4_AVGPOS_FILT_256 0x04 #define SX9324_REG_PROX_CTRL5 0x35 #define SX9324_REG_PROX_CTRL5_HYST_MASK GENMASK(5, 4) #define SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK GENMASK(3, 2) @@ -810,7 +810,7 @@ static const struct sx_common_reg_default sx9324_default_regs[] = { { SX9324_REG_PROX_CTRL3, SX9324_REG_PROX_CTRL3_AVGDEB_2SAMPLES | SX9324_REG_PROX_CTRL3_AVGPOS_THRESH_16K }, { SX9324_REG_PROX_CTRL4, SX9324_REG_PROX_CTRL4_AVGNEG_FILT_2 | - SX9324_REG_PROX_CTRL3_AVGPOS_FILT_256 }, + SX9324_REG_PROX_CTRL4_AVGPOS_FILT_256 }, { SX9324_REG_PROX_CTRL5, 0x00 }, { SX9324_REG_PROX_CTRL6, SX9324_REG_PROX_CTRL6_PROXTHRESH_32 }, { SX9324_REG_PROX_CTRL7, SX9324_REG_PROX_CTRL6_PROXTHRESH_32 },
From: Jagath Jog J jagathjog1996@gmail.com
[ Upstream commit 1bd2dc6ea863690aee5c45ebf09c9194c7a42c0d ]
Reordering of header files and removing the iio/sysfs.h since custom attributes are not being used in the driver.
Signed-off-by: Jagath Jog J jagathjog1996@gmail.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Link: https://lore.kernel.org/r/20220505133021.22362-3-jagathjog1996@gmail.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/bma400_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 043002fe6f63..25ad1f7339bc 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -13,14 +13,14 @@
#include <linux/bitops.h> #include <linux/device.h> -#include <linux/iio/iio.h> -#include <linux/iio/sysfs.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h>
+#include <linux/iio/iio.h> + #include "bma400.h"
/*
From: Jagath Jog J jagathjog1996@gmail.com
[ Upstream commit 12c99f859fd3da5fc8f8491826e7023001f54821 ]
This is a conversion to device-managed by using devm_iio_device_register() inside probe function. Previously the bma400 was not put into power down mode in some error paths in probe where it now is, but that should cause no harm.
The dev_set_drvdata() call, bma400_remove() function and hooks in the I2C and SPI driver struct is removed as devm_iio_device_register() function is used to automatically unregister on driver detach.
Signed-off-by: Jagath Jog J jagathjog1996@gmail.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Link: https://lore.kernel.org/r/20220505133021.22362-4-jagathjog1996@gmail.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/bma400.h | 2 - drivers/iio/accel/bma400_core.c | 77 ++++++++++++++++----------------- drivers/iio/accel/bma400_i2c.c | 8 ---- drivers/iio/accel/bma400_spi.c | 6 --- 4 files changed, 38 insertions(+), 55 deletions(-)
diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h index 80330c7ce17f..1c8c47a9a317 100644 --- a/drivers/iio/accel/bma400.h +++ b/drivers/iio/accel/bma400.h @@ -113,6 +113,4 @@ extern const struct regmap_config bma400_regmap_config;
int bma400_probe(struct device *dev, struct regmap *regmap, const char *name);
-void bma400_remove(struct device *dev); - #endif diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 25ad1f7339bc..07674d89d978 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -560,6 +560,26 @@ static void bma400_init_tables(void) } }
+static void bma400_regulators_disable(void *data_ptr) +{ + struct bma400_data *data = data_ptr; + + regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); +} + +static void bma400_power_disable(void *data_ptr) +{ + struct bma400_data *data = data_ptr; + int ret; + + mutex_lock(&data->mutex); + ret = bma400_set_power_mode(data, POWER_MODE_SLEEP); + mutex_unlock(&data->mutex); + if (ret) + dev_warn(data->dev, "Failed to put device into sleep mode (%pe)\n", + ERR_PTR(ret)); +} + static int bma400_init(struct bma400_data *data) { unsigned int val; @@ -569,13 +589,12 @@ static int bma400_init(struct bma400_data *data) ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val); if (ret) { dev_err(data->dev, "Failed to read chip id register\n"); - goto out; + return ret; }
if (val != BMA400_ID_REG_VAL) { dev_err(data->dev, "Chip ID mismatch\n"); - ret = -ENODEV; - goto out; + return -ENODEV; }
data->regulators[BMA400_VDD_REGULATOR].supply = "vdd"; @@ -589,27 +608,31 @@ static int bma400_init(struct bma400_data *data) "Failed to get regulators: %d\n", ret);
- goto out; + return ret; } ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators), data->regulators); if (ret) { dev_err(data->dev, "Failed to enable regulators: %d\n", ret); - goto out; + return ret; }
+ ret = devm_add_action_or_reset(data->dev, bma400_regulators_disable, data); + if (ret) + return ret; + ret = bma400_get_power_mode(data); if (ret) { dev_err(data->dev, "Failed to get the initial power-mode\n"); - goto err_reg_disable; + return ret; }
if (data->power_mode != POWER_MODE_NORMAL) { ret = bma400_set_power_mode(data, POWER_MODE_NORMAL); if (ret) { dev_err(data->dev, "Failed to wake up the device\n"); - goto err_reg_disable; + return ret; } /* * TODO: The datasheet waits 1500us here in the example, but @@ -618,19 +641,23 @@ static int bma400_init(struct bma400_data *data) usleep_range(1500, 2000); }
+ ret = devm_add_action_or_reset(data->dev, bma400_power_disable, data); + if (ret) + return ret; + bma400_init_tables();
ret = bma400_get_accel_output_data_rate(data); if (ret) - goto err_reg_disable; + return ret;
ret = bma400_get_accel_oversampling_ratio(data); if (ret) - goto err_reg_disable; + return ret;
ret = bma400_get_accel_scale(data); if (ret) - goto err_reg_disable; + return ret;
/* * Once the interrupt engine is supported we might use the @@ -639,12 +666,6 @@ static int bma400_init(struct bma400_data *data) * channel. */ return regmap_write(data->regmap, BMA400_ACC_CONFIG2_REG, 0x00); - -err_reg_disable: - regulator_bulk_disable(ARRAY_SIZE(data->regulators), - data->regulators); -out: - return ret; }
static int bma400_read_raw(struct iio_dev *indio_dev, @@ -822,32 +843,10 @@ int bma400_probe(struct device *dev, struct regmap *regmap, const char *name) indio_dev->num_channels = ARRAY_SIZE(bma400_channels); indio_dev->modes = INDIO_DIRECT_MODE;
- dev_set_drvdata(dev, indio_dev); - - return iio_device_register(indio_dev); + return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_NS(bma400_probe, IIO_BMA400);
-void bma400_remove(struct device *dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct bma400_data *data = iio_priv(indio_dev); - int ret; - - mutex_lock(&data->mutex); - ret = bma400_set_power_mode(data, POWER_MODE_SLEEP); - mutex_unlock(&data->mutex); - - if (ret) - dev_warn(dev, "Failed to put device into sleep mode (%pe)\n", ERR_PTR(ret)); - - regulator_bulk_disable(ARRAY_SIZE(data->regulators), - data->regulators); - - iio_device_unregister(indio_dev); -} -EXPORT_SYMBOL_NS(bma400_remove, IIO_BMA400); - MODULE_AUTHOR("Dan Robertson dan@dlrobertson.com"); MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor core"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c index da104ffd3fe0..4f6e01a3b3a1 100644 --- a/drivers/iio/accel/bma400_i2c.c +++ b/drivers/iio/accel/bma400_i2c.c @@ -27,13 +27,6 @@ static int bma400_i2c_probe(struct i2c_client *client, return bma400_probe(&client->dev, regmap, id->name); }
-static int bma400_i2c_remove(struct i2c_client *client) -{ - bma400_remove(&client->dev); - - return 0; -} - static const struct i2c_device_id bma400_i2c_ids[] = { { "bma400", 0 }, { } @@ -52,7 +45,6 @@ static struct i2c_driver bma400_i2c_driver = { .of_match_table = bma400_of_i2c_match, }, .probe = bma400_i2c_probe, - .remove = bma400_i2c_remove, .id_table = bma400_i2c_ids, };
diff --git a/drivers/iio/accel/bma400_spi.c b/drivers/iio/accel/bma400_spi.c index 51f23bdc0ea5..28e240400a3f 100644 --- a/drivers/iio/accel/bma400_spi.c +++ b/drivers/iio/accel/bma400_spi.c @@ -87,11 +87,6 @@ static int bma400_spi_probe(struct spi_device *spi) return bma400_probe(&spi->dev, regmap, id->name); }
-static void bma400_spi_remove(struct spi_device *spi) -{ - bma400_remove(&spi->dev); -} - static const struct spi_device_id bma400_spi_ids[] = { { "bma400", 0 }, { } @@ -110,7 +105,6 @@ static struct spi_driver bma400_spi_driver = { .of_match_table = bma400_of_spi_match, }, .probe = bma400_spi_probe, - .remove = bma400_spi_remove, .id_table = bma400_spi_ids, };
From: Jagath Jog J jagathjog1996@gmail.com
[ Upstream commit ffe0ab6a96988daa8b316290c15e1c7bbb9d4211 ]
Added trigger buffer support to read continuous acceleration and temperature data from device with data ready interrupt which is mapped to INT1 pin.
Signed-off-by: Jagath Jog J jagathjog1996@gmail.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Link: https://lore.kernel.org/r/20220505133021.22362-5-jagathjog1996@gmail.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/Kconfig | 2 + drivers/iio/accel/bma400.h | 10 +- drivers/iio/accel/bma400_core.c | 177 +++++++++++++++++++++++++++++++- drivers/iio/accel/bma400_i2c.c | 2 +- drivers/iio/accel/bma400_spi.c | 2 +- 5 files changed, 185 insertions(+), 8 deletions(-)
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index b53f010f3e40..35798712f811 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -204,6 +204,8 @@ config BMA220 config BMA400 tristate "Bosch BMA400 3-Axis Accelerometer Driver" select REGMAP + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER select BMA400_I2C if I2C select BMA400_SPI if SPI help diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h index 1c8c47a9a317..907e1a6c0a38 100644 --- a/drivers/iio/accel/bma400.h +++ b/drivers/iio/accel/bma400.h @@ -62,6 +62,13 @@ #define BMA400_ACC_CONFIG2_REG 0x1b #define BMA400_CMD_REG 0x7e
+/* Interrupt registers */ +#define BMA400_INT_CONFIG0_REG 0x1f +#define BMA400_INT_CONFIG1_REG 0x20 +#define BMA400_INT1_MAP_REG 0x21 +#define BMA400_INT_IO_CTRL_REG 0x24 +#define BMA400_INT_DRDY_MSK BIT(7) + /* Chip ID of BMA 400 devices found in the chip ID register. */ #define BMA400_ID_REG_VAL 0x90
@@ -111,6 +118,7 @@
extern const struct regmap_config bma400_regmap_config;
-int bma400_probe(struct device *dev, struct regmap *regmap, const char *name); +int bma400_probe(struct device *dev, struct regmap *regmap, int irq, + const char *name);
#endif diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 07674d89d978..67e102c097bc 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -11,6 +11,7 @@ * - Create channel for sensor time */
+#include <linux/bitfield.h> #include <linux/bitops.h> #include <linux/device.h> #include <linux/kernel.h> @@ -20,6 +21,10 @@ #include <linux/regulator/consumer.h>
#include <linux/iio/iio.h> +#include <linux/iio/buffer.h> +#include <linux/iio/trigger.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h>
#include "bma400.h"
@@ -46,6 +51,13 @@ enum bma400_power_mode { POWER_MODE_INVALID = 0x03, };
+enum bma400_scan { + BMA400_ACCL_X, + BMA400_ACCL_Y, + BMA400_ACCL_Z, + BMA400_TEMP, +}; + struct bma400_sample_freq { int hz; int uhz; @@ -61,6 +73,14 @@ struct bma400_data { struct bma400_sample_freq sample_freq; int oversampling_ratio; int scale; + struct iio_trigger *trig; + /* Correct time stamp alignment */ + struct { + __le16 buff[3]; + u8 temperature; + s64 ts __aligned(8); + } buffer __aligned(IIO_ALIGN); + __le16 status; };
static bool bma400_is_writable_reg(struct device *dev, unsigned int reg) @@ -152,7 +172,7 @@ static const struct iio_chan_spec_ext_info bma400_ext_info[] = { { } };
-#define BMA400_ACC_CHANNEL(_axis) { \ +#define BMA400_ACC_CHANNEL(_index, _axis) { \ .type = IIO_ACCEL, \ .modified = 1, \ .channel2 = IIO_MOD_##_axis, \ @@ -164,17 +184,32 @@ static const struct iio_chan_spec_ext_info bma400_ext_info[] = { BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ .ext_info = bma400_ext_info, \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 12, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ }
static const struct iio_chan_spec bma400_channels[] = { - BMA400_ACC_CHANNEL(X), - BMA400_ACC_CHANNEL(Y), - BMA400_ACC_CHANNEL(Z), + BMA400_ACC_CHANNEL(0, X), + BMA400_ACC_CHANNEL(1, Y), + BMA400_ACC_CHANNEL(2, Z), { .type = IIO_TEMP, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .scan_index = 3, + .scan_type = { + .sign = 's', + .realbits = 8, + .storagebits = 8, + .endianness = IIO_LE, + }, }, + IIO_CHAN_SOFT_TIMESTAMP(4), };
static int bma400_get_temp_reg(struct bma400_data *data, int *val, int *val2) @@ -659,6 +694,10 @@ static int bma400_init(struct bma400_data *data) if (ret) return ret;
+ /* Configure INT1 pin to open drain */ + ret = regmap_write(data->regmap, BMA400_INT_IO_CTRL_REG, 0x06); + if (ret) + return ret; /* * Once the interrupt engine is supported we might use the * data_src_reg, but for now ensure this is set to the @@ -807,6 +846,31 @@ static int bma400_write_raw_get_fmt(struct iio_dev *indio_dev, } }
+static int bma400_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + struct bma400_data *data = iio_priv(indio_dev); + int ret; + + ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG, + BMA400_INT_DRDY_MSK, + FIELD_PREP(BMA400_INT_DRDY_MSK, state)); + if (ret) + return ret; + + return regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG, + BMA400_INT_DRDY_MSK, + FIELD_PREP(BMA400_INT_DRDY_MSK, state)); +} + +static const unsigned long bma400_avail_scan_masks[] = { + BIT(BMA400_ACCL_X) | BIT(BMA400_ACCL_Y) | BIT(BMA400_ACCL_Z), + BIT(BMA400_ACCL_X) | BIT(BMA400_ACCL_Y) | BIT(BMA400_ACCL_Z) + | BIT(BMA400_TEMP), + 0 +}; + static const struct iio_info bma400_info = { .read_raw = bma400_read_raw, .read_avail = bma400_read_avail, @@ -814,7 +878,78 @@ static const struct iio_info bma400_info = { .write_raw_get_fmt = bma400_write_raw_get_fmt, };
-int bma400_probe(struct device *dev, struct regmap *regmap, const char *name) +static const struct iio_trigger_ops bma400_trigger_ops = { + .set_trigger_state = &bma400_data_rdy_trigger_set_state, + .validate_device = &iio_trigger_validate_own_device, +}; + +static irqreturn_t bma400_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct bma400_data *data = iio_priv(indio_dev); + int ret, temp; + + /* Lock to protect the data->buffer */ + mutex_lock(&data->mutex); + + /* bulk read six registers, with the base being the LSB register */ + ret = regmap_bulk_read(data->regmap, BMA400_X_AXIS_LSB_REG, + &data->buffer.buff, sizeof(data->buffer.buff)); + if (ret) + goto unlock_err; + + if (test_bit(BMA400_TEMP, indio_dev->active_scan_mask)) { + ret = regmap_read(data->regmap, BMA400_TEMP_DATA_REG, &temp); + if (ret) + goto unlock_err; + + data->buffer.temperature = temp; + } + + iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer, + iio_get_time_ns(indio_dev)); + + mutex_unlock(&data->mutex); + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; + +unlock_err: + mutex_unlock(&data->mutex); + return IRQ_NONE; +} + +static irqreturn_t bma400_interrupt(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct bma400_data *data = iio_priv(indio_dev); + int ret; + + /* Lock to protect the data->status */ + mutex_lock(&data->mutex); + ret = regmap_bulk_read(data->regmap, BMA400_INT_STAT0_REG, + &data->status, + sizeof(data->status)); + /* + * if none of the bit is set in the status register then it is + * spurious interrupt. + */ + if (ret || !data->status) + goto unlock_err; + + if (FIELD_GET(BMA400_INT_DRDY_MSK, le16_to_cpu(data->status))) { + mutex_unlock(&data->mutex); + iio_trigger_poll_chained(data->trig); + return IRQ_HANDLED; + } + +unlock_err: + mutex_unlock(&data->mutex); + return IRQ_NONE; +} + +int bma400_probe(struct device *dev, struct regmap *regmap, int irq, + const char *name) { struct iio_dev *indio_dev; struct bma400_data *data; @@ -841,8 +976,40 @@ int bma400_probe(struct device *dev, struct regmap *regmap, const char *name) indio_dev->info = &bma400_info; indio_dev->channels = bma400_channels; indio_dev->num_channels = ARRAY_SIZE(bma400_channels); + indio_dev->available_scan_masks = bma400_avail_scan_masks; indio_dev->modes = INDIO_DIRECT_MODE;
+ if (irq > 0) { + data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", + indio_dev->name, + iio_device_id(indio_dev)); + if (!data->trig) + return -ENOMEM; + + data->trig->ops = &bma400_trigger_ops; + iio_trigger_set_drvdata(data->trig, indio_dev); + + ret = devm_iio_trigger_register(data->dev, data->trig); + if (ret) + return dev_err_probe(data->dev, ret, + "iio trigger register fail\n"); + + indio_dev->trig = iio_trigger_get(data->trig); + ret = devm_request_threaded_irq(dev, irq, NULL, + &bma400_interrupt, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret) + return dev_err_probe(data->dev, ret, + "request irq %d failed\n", irq); + } + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + &bma400_trigger_handler, NULL); + if (ret) + return dev_err_probe(data->dev, ret, + "iio triggered buffer setup failed\n"); + return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_NS(bma400_probe, IIO_BMA400); diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c index 4f6e01a3b3a1..1ba2a982ea73 100644 --- a/drivers/iio/accel/bma400_i2c.c +++ b/drivers/iio/accel/bma400_i2c.c @@ -24,7 +24,7 @@ static int bma400_i2c_probe(struct i2c_client *client, return PTR_ERR(regmap); }
- return bma400_probe(&client->dev, regmap, id->name); + return bma400_probe(&client->dev, regmap, client->irq, id->name); }
static const struct i2c_device_id bma400_i2c_ids[] = { diff --git a/drivers/iio/accel/bma400_spi.c b/drivers/iio/accel/bma400_spi.c index 28e240400a3f..ec13c044b304 100644 --- a/drivers/iio/accel/bma400_spi.c +++ b/drivers/iio/accel/bma400_spi.c @@ -84,7 +84,7 @@ static int bma400_spi_probe(struct spi_device *spi) if (ret) dev_err(&spi->dev, "Failed to read chip id register\n");
- return bma400_probe(&spi->dev, regmap, id->name); + return bma400_probe(&spi->dev, regmap, spi->irq, id->name); }
static const struct spi_device_id bma400_spi_ids[] = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 12c4efe3509b8018e76ea3ebda8227cb53bf5887 ]
Discussion of the series: https://lore.kernel.org/all/20220405135758.774016-1-catalin.marinas@arm.com/ mm, arm64: Reduce ARCH_KMALLOC_MINALIGN brought to my attention that our current IIO usage of L1CACHE_ALIGN is insufficient as their are Arm platforms out their with non coherent DMA and larger cache lines at at higher levels of their cache hierarchy.
Rename the define to make it's purpose more explicit. It will be used much more widely going forwards (to replace incorrect ____cacheline_aligned markings.
Note this patch will greatly reduce the padding on some architectures that have smaller requirements for DMA safe buffers.
The history of changing values of ARCH_KMALLOC_MINALIGN via ARCH_DMA_MINALIGN on arm64 is rather complex. I'm not tagging this as fixing a particular patch from that route as it's not clear what to tag.
Most recently a change to bring them back inline was reverted because of some Qualcomm Kryo cores with an L2 cache with 128-byte lines sitting above the point of coherency.
c1132702c71f Revert "arm64: cache: Lower ARCH_DMA_MINALIGN to 64 (L1_CACHE_BYTES)" That reverts: 65688d2a05de arm64: cache: Lower ARCH_DMA_MINALIGN to 64 (L1_CACHE_BYTES) which refers to the change originally being motivated by Thunder x1 performance rather than correctness.
Fixes: 6f7c8ee585e9d ("staging:iio: Add ability to allocate private data space to iio_allocate_device") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-2-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/bma400_core.c | 2 +- drivers/iio/adc/adi-axi-adc.c | 7 ++++--- drivers/iio/industrialio-core.c | 4 ++-- include/linux/iio/iio.h | 10 ++++++++-- 4 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 67e102c097bc..837f8671e00d 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -79,7 +79,7 @@ struct bma400_data { __le16 buff[3]; u8 temperature; s64 ts __aligned(8); - } buffer __aligned(IIO_ALIGN); + } buffer __aligned(IIO_DMA_MINALIGN); __le16 status; };
diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index a9e655e69eaa..8ffabdaf841e 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -84,7 +84,8 @@ void *adi_axi_adc_conv_priv(struct adi_axi_adc_conv *conv) { struct adi_axi_adc_client *cl = conv_to_client(conv);
- return (char *)cl + ALIGN(sizeof(struct adi_axi_adc_client), IIO_ALIGN); + return (char *)cl + ALIGN(sizeof(struct adi_axi_adc_client), + IIO_DMA_MINALIGN); } EXPORT_SYMBOL_GPL(adi_axi_adc_conv_priv);
@@ -169,9 +170,9 @@ static struct adi_axi_adc_conv *adi_axi_adc_conv_register(struct device *dev, struct adi_axi_adc_client *cl; size_t alloc_size;
- alloc_size = ALIGN(sizeof(struct adi_axi_adc_client), IIO_ALIGN); + alloc_size = ALIGN(sizeof(struct adi_axi_adc_client), IIO_DMA_MINALIGN); if (sizeof_priv) - alloc_size += ALIGN(sizeof_priv, IIO_ALIGN); + alloc_size += ALIGN(sizeof_priv, IIO_DMA_MINALIGN);
cl = kzalloc(alloc_size, GFP_KERNEL); if (!cl) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 299ae3ad2fe5..ed36851d646b 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1669,7 +1669,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
alloc_size = sizeof(struct iio_dev_opaque); if (sizeof_priv) { - alloc_size = ALIGN(alloc_size, IIO_ALIGN); + alloc_size = ALIGN(alloc_size, IIO_DMA_MINALIGN); alloc_size += sizeof_priv; }
@@ -1679,7 +1679,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
indio_dev = &iio_dev_opaque->indio_dev; indio_dev->priv = (char *)iio_dev_opaque + - ALIGN(sizeof(struct iio_dev_opaque), IIO_ALIGN); + ALIGN(sizeof(struct iio_dev_opaque), IIO_DMA_MINALIGN);
indio_dev->dev.parent = parent; indio_dev->dev.type = &iio_device_type; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 233d2e6b7721..a0db62297ea1 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -9,6 +9,7 @@
#include <linux/device.h> #include <linux/cdev.h> +#include <linux/slab.h> #include <linux/iio/types.h> #include <linux/of.h> /* IIO TODO LIST */ @@ -709,8 +710,13 @@ static inline void *iio_device_get_drvdata(const struct iio_dev *indio_dev) return dev_get_drvdata(&indio_dev->dev); }
-/* Can we make this smaller? */ -#define IIO_ALIGN L1_CACHE_BYTES +/* + * Used to ensure the iio_priv() structure is aligned to allow that structure + * to in turn include IIO_DMA_MINALIGN'd elements such as buffers which + * must not share cachelines with the rest of the structure, thus making + * them safe for use with non-coherent DMA. + */ +#define IIO_DMA_MINALIGN ARCH_KMALLOC_MINALIGN struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv);
/* The information at the returned address is guaranteed to be cacheline aligned */
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit f68a0445ee86e48dafbfdea50163ad6fc6dba268 ]
____cacheline_aligned is insufficient guarantee for non-coherent DMA. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 636d44633039 ("iio: accel: Add driver support for ADXL313") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-3-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/adxl313_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_core.c index 9e4193e64765..afeef779e1d0 100644 --- a/drivers/iio/accel/adxl313_core.c +++ b/drivers/iio/accel/adxl313_core.c @@ -46,7 +46,7 @@ EXPORT_SYMBOL_NS_GPL(adxl313_writable_regs_table, IIO_ADXL313); struct adxl313_data { struct regmap *regmap; struct mutex lock; /* lock to protect transf_buf */ - __le16 transf_buf ____cacheline_aligned; + __le16 transf_buf __aligned(IIO_DMA_MINALIGN); };
static const int adxl313_odr_freqs[][2] = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 46403dcf3a7cbd24b86f809fd79962f4d6b137c5 ]
____cacheline_aligned is insufficient guarantee for non-coherent DMA. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 327a0eaf19d53 ("iio: accel: adxl355: Add triggered buffer support") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Puranjay Mohan puranjay12@gmail.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-4-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/adxl355_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c index 7561399daef3..4bc648eac8b2 100644 --- a/drivers/iio/accel/adxl355_core.c +++ b/drivers/iio/accel/adxl355_core.c @@ -177,7 +177,7 @@ struct adxl355_data { u8 buf[14]; s64 ts; } buffer; - } ____cacheline_aligned; + } __aligned(IIO_DMA_MINALIGN); };
static int adxl355_set_op_mode(struct adxl355_data *data,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit e1f956a804df9074fb5de557563d153ae25252e7 ]
____cacheline_aligned is insufficient guarantee for non-coherent DMA. Switch to the updated IIO_DMA_MINALIGN definition.
Update comment to reflect that DMA safety may require separate cachelines.
Fixes: cbab791c5e2a5 ("iio: accel: add ADXL367 driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Cosmin Tanislav demonsingur@gmail.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-5-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/adxl367.c | 2 +- drivers/iio/accel/adxl367_spi.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c index 0289ed8cf2c6..0168329ec505 100644 --- a/drivers/iio/accel/adxl367.c +++ b/drivers/iio/accel/adxl367.c @@ -179,7 +179,7 @@ struct adxl367_state { unsigned int fifo_set_size; unsigned int fifo_watermark;
- __be16 fifo_buf[ADXL367_FIFO_SIZE] ____cacheline_aligned; + __be16 fifo_buf[ADXL367_FIFO_SIZE] __aligned(IIO_DMA_MINALIGN); __be16 sample_buf; u8 act_threshold_buf[2]; u8 inact_time_buf[2]; diff --git a/drivers/iio/accel/adxl367_spi.c b/drivers/iio/accel/adxl367_spi.c index 26dfc821ebbe..118c894015a5 100644 --- a/drivers/iio/accel/adxl367_spi.c +++ b/drivers/iio/accel/adxl367_spi.c @@ -9,6 +9,8 @@ #include <linux/regmap.h> #include <linux/spi/spi.h>
+#include <linux/iio/iio.h> + #include "adxl367.h"
#define ADXL367_SPI_WRITE_COMMAND 0x0A @@ -28,10 +30,10 @@ struct adxl367_spi_state { struct spi_transfer fifo_xfer[2];
/* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. + * DMA (thus cache coherency maintenance) may require the + * transfer buffers live in their own cache lines. */ - u8 reg_write_tx_buf[1] ____cacheline_aligned; + u8 reg_write_tx_buf[1] __aligned(IIO_DMA_MINALIGN); u8 reg_read_tx_buf[2]; u8 fifo_tx_buf[1]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 38e71240e2ff97184cdcdaf877cf62d3f16678e2 ]
____cacheline_aligned is insufficient guarantee for non-coherent DMA. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: bf2a5600a3ebc ("iio: accel: Add support for Bosch BMA220") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-6-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/bma220_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/accel/bma220_spi.c b/drivers/iio/accel/bma220_spi.c index 74024d7ce5ac..b6d9ab8e2054 100644 --- a/drivers/iio/accel/bma220_spi.c +++ b/drivers/iio/accel/bma220_spi.c @@ -67,7 +67,7 @@ struct bma220_data { /* Ensure timestamp is naturally aligned. */ s64 timestamp __aligned(8); } scan; - u8 tx_buf[2] ____cacheline_aligned; + u8 tx_buf[2] __aligned(IIO_DMA_MINALIGN); };
static const struct iio_chan_spec bma220_channels[] = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit a263456f0e27ec2f00d25119757f4d4bd656b2e9 ]
____cacheline_aligned is insufficient guarantee for non-coherent DMA. Switch to the updated IIO_DMA_MINALIGN definition.
The second alignment marking is left in place to avoid doing more than the simple fix in this patch.
Fixes: ced5c03d360ae ("staging:iio:accel:sca3000 merge files into one.") Fixes: 152a6a884ae13 ("staging:iio:accel:sca3000 move to hybrid hard / soft buffer design.") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-8-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/sca3000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/accel/sca3000.c b/drivers/iio/accel/sca3000.c index 29a68a7d34cd..cc0aa1dda611 100644 --- a/drivers/iio/accel/sca3000.c +++ b/drivers/iio/accel/sca3000.c @@ -167,8 +167,8 @@ struct sca3000_state { int mo_det_use_count; struct mutex lock; /* Can these share a cacheline ? */ - u8 rx[384] ____cacheline_aligned; - u8 tx[6] ____cacheline_aligned; + u8 rx[384] __aligned(IIO_DMA_MINALIGN); + u8 tx[6] __aligned(IIO_DMA_MINALIGN); };
/**
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit b1d3a806630dbbf3b4d75a2e850adccf4f4439e7 ]
____cacheline_aligned is insufficient guarantee for non-coherent DMA. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 9cc9806e22178 ("iio: accel: Add driver for Murata SCA3300 accelerometer") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reviewed-by: Tomas Melin tomas.melin@vaisala.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-9-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/sca3300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/accel/sca3300.c b/drivers/iio/accel/sca3300.c index f7ef8ecfd34a..39e0c24364ae 100644 --- a/drivers/iio/accel/sca3300.c +++ b/drivers/iio/accel/sca3300.c @@ -115,7 +115,7 @@ struct sca3300_data { s16 channels[4]; s64 ts __aligned(sizeof(s64)); } scan; - u8 txbuf[4] ____cacheline_aligned; + u8 txbuf[4] __aligned(IIO_DMA_MINALIGN); u8 rxbuf[4]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit b990cdfe7536a8da7e134d516350402981300016 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to reflect that DMA safety 'may' require separate cachelines.
Fixes: 54e018da3141 ("iio:ad7266: Mark transfer buffer as __be16") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-10-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7266.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c index f20d39f0bc01..468c2656d2be 100644 --- a/drivers/iio/adc/ad7266.c +++ b/drivers/iio/adc/ad7266.c @@ -37,7 +37,7 @@ struct ad7266_state { struct gpio_desc *gpios[3];
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. * The buffer needs to be large enough to hold two samples (4 bytes) and * the naturally aligned timestamp (8 bytes). @@ -45,7 +45,7 @@ struct ad7266_state { struct { __be16 sample[2]; s64 timestamp; - } data ____cacheline_aligned; + } data __aligned(IIO_DMA_MINALIGN); };
static int ad7266_wakeup(struct ad7266_state *st)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 4e2008429588b857bbc13d048b67b931a8d84816 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 003f1d48de52 ("staging:iio:adc:ad7280a: Split buff[2] into tx and rx parts") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-11-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7280a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ad7280a.c b/drivers/iio/adc/ad7280a.c index 3bdf3d9422f2..d4a4e15c8244 100644 --- a/drivers/iio/adc/ad7280a.c +++ b/drivers/iio/adc/ad7280a.c @@ -183,7 +183,7 @@ struct ad7280_state { unsigned char cb_mask[AD7280A_MAX_CHAIN]; struct mutex lock; /* protect sensor state */
- __be32 tx ____cacheline_aligned; + __be32 tx __aligned(IIO_DMA_MINALIGN); __be32 rx; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 98295a206d04633bae31f279de11ff7d04724bce ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 506d2e317a0a ("iio: adc: Add driver support for AD7292") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Marcelo Schmitt marcelo.schmitt1@gmail.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-12-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7292.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ad7292.c b/drivers/iio/adc/ad7292.c index 3271a31afde1..92c68d467c50 100644 --- a/drivers/iio/adc/ad7292.c +++ b/drivers/iio/adc/ad7292.c @@ -80,7 +80,7 @@ struct ad7292_state { struct regulator *reg; unsigned short vref_mv;
- __be16 d16 ____cacheline_aligned; + __be16 d16 __aligned(IIO_DMA_MINALIGN); u8 d8[2]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 585c9772f883da3ac425e2e8277b2aaceb201f38 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: be7fd3b86ad2 ("iio:adc:ad7298 make the tx and rx buffers __be16") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-13-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7298.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c index 3f4e73f7d35a..c0430f71f592 100644 --- a/drivers/iio/adc/ad7298.c +++ b/drivers/iio/adc/ad7298.c @@ -49,7 +49,7 @@ struct ad7298_state { * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. */ - __be16 rx_buf[12] ____cacheline_aligned; + __be16 rx_buf[12] __aligned(IIO_DMA_MINALIGN); __be16 tx_buf[2]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 58b74555afc8affe4ae4f57d396349158433fc80 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to reflect that DMA safety 'may' require separate cachelines.
Fixes tag is unlikely to be the actual introdution of the problem but is far enough back to cover any likely backporting.
Fixes: 7a28fe3c93d6 ("staging:iio:ad7476: Squash driver into a single file.") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-14-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7476.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index a1e8b32671cf..94776f696290 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -44,13 +44,12 @@ struct ad7476_state { struct spi_transfer xfer; struct spi_message msg; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. * Make the buffer large enough for one 16 bit sample and one 64 bit * aligned 64 bit timestamp. */ - unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)] - ____cacheline_aligned; + unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)] __aligned(IIO_DMA_MINALIGN); };
enum ad7476_supported_device_ids {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 6268c6eebb13f228d418f9adaca848b3ed5b3cf9 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_ALIGN definition.
Update the comment to reflect the fact DMA safety 'may' require separate cachelines.
Fixes: 7989b4bb23fe ("iio: adc: ad7616: Add support for AD7616 ADC") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-15-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7606.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h index 4f82d7c9acfd..2dc4f599f9df 100644 --- a/drivers/iio/adc/ad7606.h +++ b/drivers/iio/adc/ad7606.h @@ -116,11 +116,11 @@ struct ad7606_state { struct completion completion;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. * 16 * 16-bit samples + 64-bit timestamp */ - unsigned short data[20] ____cacheline_aligned; + unsigned short data[20] __aligned(IIO_DMA_MINALIGN); __be16 d16[2]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 009ae227a1dace2d4d27c804e5bd65907e1d0557 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to reflect the fact DMA safety 'may' require separate cachelines.
Fixes: aa16c6bd0e09 ("iio:adc: Add support for AD7766/AD7767") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Lars-Peter Clausen lars@metafoo.de Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-16-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7766.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/adc/ad7766.c b/drivers/iio/adc/ad7766.c index 51ee9482e0df..3079a0872947 100644 --- a/drivers/iio/adc/ad7766.c +++ b/drivers/iio/adc/ad7766.c @@ -45,13 +45,12 @@ struct ad7766 { struct spi_message msg;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. * Make the buffer large enough for one 24 bit sample and one 64 bit * aligned 64 bit timestamp. */ - unsigned char data[ALIGN(3, sizeof(s64)) + sizeof(s64)] - ____cacheline_aligned; + unsigned char data[ALIGN(3, sizeof(s64)) + sizeof(s64)] __aligned(IIO_DMA_MINALIGN); };
/*
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 211f810f8fae05c1f78e531b2b113ea1ab3d1ce7 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to reflect that separate cachelines 'may' be required.
Fixes: a5f8c7da3dbe ("iio: adc: Add AD7768-1 ADC basic support") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-17-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7768-1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c index aa42ba759fa1..60f394da4640 100644 --- a/drivers/iio/adc/ad7768-1.c +++ b/drivers/iio/adc/ad7768-1.c @@ -163,7 +163,7 @@ struct ad7768_state { struct gpio_desc *gpio_sync_in; const char *labels[ARRAY_SIZE(ad7768_channels)]; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ union { @@ -173,7 +173,7 @@ struct ad7768_state { } scan; __be32 d32; u8 d8[2]; - } data ____cacheline_aligned; + } data __aligned(IIO_DMA_MINALIGN); };
static int ad7768_spi_reg_read(struct ad7768_state *st, unsigned int addr,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit b330ea6bc52468e183ced79189ff064f36c64aa7 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes tag is clearly not where this was introduced but it is very unlikely anyone will back port it past that point.
Fixes: 65dd3d3d7a9b ("staging:iio:ad7887: Squash everything into one file") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Lars-Peter Clausen lars@metafoo.de Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-18-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7887.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c index f64999714a4d..965bdc8aa696 100644 --- a/drivers/iio/adc/ad7887.c +++ b/drivers/iio/adc/ad7887.c @@ -66,13 +66,12 @@ struct ad7887_state { unsigned char tx_cmd_buf[4];
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. * Buffer needs to be large enough to hold two 16 bit samples and a * 64 bit aligned 64 bit timestamp. */ - unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)] - ____cacheline_aligned; + unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)] __aligned(IIO_DMA_MINALIGN); };
enum ad7887_supported_device_ids {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 908af45d7057345bc910940a9340f7a1d8935875 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Note that some other fixes have applied to this line of code that may complicate automated backporting.
Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Fixes: 0eac259db28f ("IIO ADC support for AD7923") Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-19-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7923.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c index 069b561ee768..edad1f30121d 100644 --- a/drivers/iio/adc/ad7923.c +++ b/drivers/iio/adc/ad7923.c @@ -57,12 +57,12 @@ struct ad7923_state { unsigned int settings;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. * Ensure rx_buf can be directly used in iio_push_to_buffers_with_timetamp * Length = 8 channels + 4 extra for 8 byte timestamp */ - __be16 rx_buf[12] ____cacheline_aligned; + __be16 rx_buf[12] __aligned(IIO_DMA_MINALIGN); __be16 tx_buf[4]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 9c6c7eff7d4a53efd4d0818f8664259a1862665a ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Note the fixes tag predates some changes to this line of code so automated application of this fix may fail.
Fixes: 7f40e0614317 ("iio:adc:ad7949: Add AD7949 ADC driver family") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Charles-Antoine Couret charles-antoine.couret@essensium.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-20-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7949.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c index 44bb5fde83de..ed4c1656ca75 100644 --- a/drivers/iio/adc/ad7949.c +++ b/drivers/iio/adc/ad7949.c @@ -86,7 +86,7 @@ struct ad7949_adc_chip { u8 resolution; u16 cfg; unsigned int current_channel; - u16 buffer ____cacheline_aligned; + u16 buffer __aligned(IIO_DMA_MINALIGN); __be16 buf8b; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 48e4ae96b0b10f93de23b86fd34e573c44e95ab3 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 72aa29ce0a59 ("iio: adc: hi8435: Holt HI-8435 threshold detector") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-21-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/hi8435.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c index 8eb0140df133..771fa12bdc02 100644 --- a/drivers/iio/adc/hi8435.c +++ b/drivers/iio/adc/hi8435.c @@ -49,7 +49,7 @@ struct hi8435_priv {
unsigned threshold_lo[2]; /* GND-Open and Supply-Open thresholds */ unsigned threshold_hi[2]; /* GND-Open and Supply-Open thresholds */ - u8 reg_buffer[3] ____cacheline_aligned; + u8 reg_buffer[3] __aligned(IIO_DMA_MINALIGN); };
static int hi8435_readb(struct hi8435_priv *priv, u8 reg, u8 *val)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 1673b7ca2dc1fb3b8d7c94a112496c02d34ae449 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: e4c5c4dfaa88 ("iio: adc: new driver to support Linear technology's ltc2496") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Uwe Kleine-König u.kleine-koenig@pengutronix.de Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-22-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ltc2496.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ltc2496.c b/drivers/iio/adc/ltc2496.c index 5a55f79f2574..dfb3bb5997e5 100644 --- a/drivers/iio/adc/ltc2496.c +++ b/drivers/iio/adc/ltc2496.c @@ -24,10 +24,10 @@ struct ltc2496_driverdata { struct spi_device *spi;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ - unsigned char rxbuf[3] ____cacheline_aligned; + unsigned char rxbuf[3] __aligned(IIO_DMA_MINALIGN); unsigned char txbuf[3]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 6ebf401d555ee1e75e779b865d38e171db0aa1f2 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: bc82222fcca1 ("iio:adc: Driver for Linear Technology LTC2497 ADC") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Michael Hennerich michael.hennerich@analog.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-23-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ltc2497.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c index 1adddf5a88a9..f7c786f37ceb 100644 --- a/drivers/iio/adc/ltc2497.c +++ b/drivers/iio/adc/ltc2497.c @@ -20,10 +20,10 @@ struct ltc2497_driverdata { struct ltc2497core_driverdata common_ddata; struct i2c_client *client; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ - __be32 buf ____cacheline_aligned; + __be32 buf __aligned(IIO_DMA_MINALIGN); };
static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit e754fb7e7a05e3838c9aa044b4114869dd0d1e17 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: fc167f624833 ("iio: add support of the max1027") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-24-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/max1027.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c index 4daf1d576c4e..b725d012625c 100644 --- a/drivers/iio/adc/max1027.c +++ b/drivers/iio/adc/max1027.c @@ -272,7 +272,7 @@ struct max1027_state { struct mutex lock; struct completion complete;
- u8 reg ____cacheline_aligned; + u8 reg __aligned(IIO_DMA_MINALIGN); };
static int max1027_wait_eoc(struct iio_dev *indio_dev)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 51f30d63145cc84cb8a8e0ec96f9a8b73e6b5448 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: a8e7e88df9ec ("iio: adc: Add Maxim MAX11100 driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Jacopo Mondi jacopo@jmondi.org Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-25-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/max11100.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/max11100.c b/drivers/iio/adc/max11100.c index eb1ce6a0315c..49e38dca8fe2 100644 --- a/drivers/iio/adc/max11100.c +++ b/drivers/iio/adc/max11100.c @@ -33,10 +33,10 @@ struct max11100_state { struct spi_device *spi;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ - u8 buffer[3] ____cacheline_aligned; + u8 buffer[3] __aligned(IIO_DMA_MINALIGN); };
static const struct iio_chan_spec max11100_channels[] = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit f746ab0bac5b335b09143dcd01db6f9f26d0c9ec ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: a9e9c7153e96 ("iio: adc: add max1117/max1118/max1119 ADC driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Akinobu Mita akinobu.mita@gmail.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-26-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/max1118.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/max1118.c b/drivers/iio/adc/max1118.c index a41bc570be21..75ab57d9aef7 100644 --- a/drivers/iio/adc/max1118.c +++ b/drivers/iio/adc/max1118.c @@ -42,7 +42,7 @@ struct max1118 { s64 ts __aligned(8); } scan;
- u8 data ____cacheline_aligned; + u8 data __aligned(IIO_DMA_MINALIGN); };
#define MAX1118_CHANNEL(ch) \
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 9d7019e43ee67a48cef63f8f23f002233064d390 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 8a80a71d9020 ("iio: adc: Add MAX1241 driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Alexandru Lazar alazar@startmail.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-27-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/max1241.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/max1241.c b/drivers/iio/adc/max1241.c index a5afd84af58b..a815ad1f6913 100644 --- a/drivers/iio/adc/max1241.c +++ b/drivers/iio/adc/max1241.c @@ -26,7 +26,7 @@ struct max1241 { struct regulator *vref; struct gpio_desc *shutdown;
- __be16 data ____cacheline_aligned; + __be16 data __aligned(IIO_DMA_MINALIGN); };
static const struct iio_chan_spec max1241_channels[] = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit e770f78036ce4327caf285873f4b20564a8b4f0f ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Worth noting the fixes tag refers to the same issue being observed on a platform that probably had only 64 byte cachelines.
Fixes: 0e81bc99a082 ("iio: mcp320x: Fix occasional incorrect readings") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Michael Welling mwelling@ieee.org Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-28-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/mcp320x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index b4c69acb33e3..f3b81798b3c9 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -92,7 +92,7 @@ struct mcp320x { struct mutex lock; const struct mcp320x_chip_info *chip_info;
- u8 tx_buf ____cacheline_aligned; + u8 tx_buf __aligned(IIO_DMA_MINALIGN); u8 rx_buf[4]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 1e6bb81c23a84a078736a0f2a52bd765863e94ed ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: efc945fb729c ("iio: adc: add support for ADC0831/ADC0832/ADC0834/ADC0838 chips") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Akinobu Mita akinobu.mita@gmail.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-29-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-adc0832.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ti-adc0832.c b/drivers/iio/adc/ti-adc0832.c index fb5e72600b96..b11ce555ba3b 100644 --- a/drivers/iio/adc/ti-adc0832.c +++ b/drivers/iio/adc/ti-adc0832.c @@ -36,7 +36,7 @@ struct adc0832 { */ u8 data[24] __aligned(8);
- u8 tx_buf[2] ____cacheline_aligned; + u8 tx_buf[2] __aligned(IIO_DMA_MINALIGN); u8 rx_buf[2]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit bb102fd600d1d6c0020a4514197c0604c4a218d9 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: 3691e5a69449 ("iio: adc: add driver for the ti-adc084s021 chip") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Acked-by: Mårten Lindahl marten.lindahl@axis.com Link: https://lore.kernel.org/r/20220508175712.647246-30-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-adc084s021.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ti-adc084s021.c b/drivers/iio/adc/ti-adc084s021.c index c9b5d9aec3dc..1f6e53832e06 100644 --- a/drivers/iio/adc/ti-adc084s021.c +++ b/drivers/iio/adc/ti-adc084s021.c @@ -32,10 +32,10 @@ struct adc084s021 { s64 ts __aligned(8); } scan; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache line. */ - u16 tx_buf[4] ____cacheline_aligned; + u16 tx_buf[4] __aligned(IIO_DMA_MINALIGN); __be16 rx_buf[5]; /* First 16-bits are trash */ };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 6909fe17888b66ea53ebb15640f82b97daa587a0 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Dual fixes tags as two cases that were introduced in different patches. One of those patches is a fix however and likely to have been backported to stable kernels.
Note the second alignment marking is likely to be unnecessary, but is left for now to keep this fix simple.
Fixes: 3691e5a69449 ("iio: adc: add driver for the ti-adc084s021 chip") Fixes: cbe5c6977604 ("iio: adc: ti-adc108s102: Fix alignment of buffer pushed to iio buffers.") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-31-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-adc108s102.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ti-adc108s102.c b/drivers/iio/adc/ti-adc108s102.c index c8e48881c37f..c82a161630e1 100644 --- a/drivers/iio/adc/ti-adc108s102.c +++ b/drivers/iio/adc/ti-adc108s102.c @@ -77,8 +77,8 @@ struct adc108s102_state { * tx_buf: 8 channel read commands, plus 1 dummy command * rx_buf: 1 dummy response, 8 channel responses */ - __be16 rx_buf[9] ____cacheline_aligned; - __be16 tx_buf[9] ____cacheline_aligned; + __be16 rx_buf[9] __aligned(IIO_DMA_MINALIGN); + __be16 tx_buf[9] __aligned(IIO_DMA_MINALIGN); };
#define ADC108S102_V_CHAN(index) \
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 76890c3bce6003caf53b283c49a210280cb8ea33 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 50a6edb1b6e0 ("iio: adc: add ADC12130/ADC12132/ADC12138 ADC driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Akinobu Mita akinobu.mita@gmail.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-32-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-adc12138.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ti-adc12138.c b/drivers/iio/adc/ti-adc12138.c index 59d75d09604f..c0a72d72f3a9 100644 --- a/drivers/iio/adc/ti-adc12138.c +++ b/drivers/iio/adc/ti-adc12138.c @@ -55,7 +55,7 @@ struct adc12138 { */ __be16 data[20] __aligned(8);
- u8 tx_buf[2] ____cacheline_aligned; + u8 tx_buf[2] __aligned(IIO_DMA_MINALIGN); u8 rx_buf[2]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 23c81e7a7e5204a08b553d07362d3082926663b8 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 913b86468674 ("iio: adc: Add TI ADC128S052") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-33-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-adc128s052.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c index 8e7adec87755..622fd384983c 100644 --- a/drivers/iio/adc/ti-adc128s052.c +++ b/drivers/iio/adc/ti-adc128s052.c @@ -29,7 +29,7 @@ struct adc128 { struct regulator *reg; struct mutex lock;
- u8 buffer[2] ____cacheline_aligned; + u8 buffer[2] __aligned(IIO_DMA_MINALIGN); };
static int adc128_adc_conversion(struct adc128 *adc, u8 channel)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 3a828f204a110dc9f253c4cf3c1103d00a0681da ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 4d671b71beef ("iio: adc: ti-adc161s626: add support for TI 1-channel differential ADCs") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Matt Ranostay mranostay@gmail.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-34-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-adc161s626.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ti-adc161s626.c b/drivers/iio/adc/ti-adc161s626.c index 75ca7f1c8726..b789891dcf49 100644 --- a/drivers/iio/adc/ti-adc161s626.c +++ b/drivers/iio/adc/ti-adc161s626.c @@ -71,7 +71,7 @@ struct ti_adc_data { u8 read_size; u8 shift;
- u8 buffer[16] ____cacheline_aligned; + u8 buffer[16] __aligned(IIO_DMA_MINALIGN); };
static int ti_adc_read_measurement(struct ti_adc_data *data,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 7df19bd26cc0b85ff997cc9e2aaea712836b5460 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: e717f8c6dfec ("iio: adc: Add the TI ads124s08 ADC code") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-35-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-ads124s08.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c index 767b3b634809..64833156c199 100644 --- a/drivers/iio/adc/ti-ads124s08.c +++ b/drivers/iio/adc/ti-ads124s08.c @@ -106,7 +106,7 @@ struct ads124s_private { * timestamp is maintained. */ u32 buffer[ADS124S08_MAX_CHANNELS + sizeof(s64)/sizeof(u32)] __aligned(8); - u8 data[5] ____cacheline_aligned; + u8 data[5] __aligned(IIO_DMA_MINALIGN); };
#define ADS124S08_CHAN(index) \
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 55afdd050c063ae4b8dbd566107a030c00d005fd ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: d935eddd2799 ("iio: adc: Add driver for Texas Instruments ADS131E0x ADC family") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Tomislav Denis tomislav.denis@avl.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-36-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-ads131e08.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ti-ads131e08.c b/drivers/iio/adc/ti-ads131e08.c index 80a09817c119..32237cacc9a3 100644 --- a/drivers/iio/adc/ti-ads131e08.c +++ b/drivers/iio/adc/ti-ads131e08.c @@ -105,7 +105,7 @@ struct ads131e08_state { s64 ts __aligned(8); } tmp_buf;
- u8 tx_buf[3] ____cacheline_aligned; + u8 tx_buf[3] __aligned(IIO_DMA_MINALIGN); /* * Add extra one padding byte to be able to access the last channel * value using u32 pointer
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit dd54ba8b2469f6ae665c529623a9454ce5293ca8 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: 902c4b2446d4 ("iio: adc: New driver for TI ADS7950 chips") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: David Lechner david@lechnology.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-37-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-ads7950.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c index e3658b969c5b..2cc9a9bd9db6 100644 --- a/drivers/iio/adc/ti-ads7950.c +++ b/drivers/iio/adc/ti-ads7950.c @@ -102,11 +102,11 @@ struct ti_ads7950_state { unsigned int gpio_cmd_settings_bitmask;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ u16 rx_buf[TI_ADS7950_MAX_CHAN + 2 + TI_ADS7950_TIMESTAMP_SIZE] - ____cacheline_aligned; + __aligned(IIO_DMA_MINALIGN); u16 tx_buf[TI_ADS7950_MAX_CHAN + 2]; u16 single_tx; u16 single_rx;
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 8966b11e5a14aaabc747ee97a7942fd50a681402 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 8dd2d7c0fed7 ("iio: adc: Add driver for the TI ADS8344 A/DC chips") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-38-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-ads8344.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ti-ads8344.c b/drivers/iio/adc/ti-ads8344.c index c96d2a9ba924..bbd85cb47f81 100644 --- a/drivers/iio/adc/ti-ads8344.c +++ b/drivers/iio/adc/ti-ads8344.c @@ -28,7 +28,7 @@ struct ads8344 { */ struct mutex lock;
- u8 tx_buf ____cacheline_aligned; + u8 tx_buf __aligned(IIO_DMA_MINALIGN); u8 rx_buf[3]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit a2105d87eb8eb03591515df10102e04a1c9e0e46 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 3e87e7838328 ("iio: adc: Add TI ADS8688") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-39-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-ads8688.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c index 708cca0a63be..ef06a897421a 100644 --- a/drivers/iio/adc/ti-ads8688.c +++ b/drivers/iio/adc/ti-ads8688.c @@ -71,7 +71,7 @@ struct ads8688_state { union { __be32 d32; u8 d8[4]; - } data[2] ____cacheline_aligned; + } data[2] __aligned(IIO_DMA_MINALIGN); };
enum ads8688_id {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 62fa19bf484bfeb52c56b7c6d6a6b1222c597f9c ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: ac2bec9d587c ("iio: adc: tlc4541: add support for TI tlc4541 adc") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-40-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ti-tlc4541.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ti-tlc4541.c b/drivers/iio/adc/ti-tlc4541.c index 2406eda9dfc6..30f629a553a1 100644 --- a/drivers/iio/adc/ti-tlc4541.c +++ b/drivers/iio/adc/ti-tlc4541.c @@ -37,12 +37,12 @@ struct tlc4541_state { struct spi_message scan_single_msg;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. * 2 bytes data + 6 bytes padding + 8 bytes timestamp when * call iio_push_to_buffers_with_timestamp. */ - __be16 rx_buf[8] ____cacheline_aligned; + __be16 rx_buf[8] __aligned(IIO_DMA_MINALIGN); };
struct tlc4541_chip_info {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 00eb2b8a077062557772234019ecd6045b8b6298 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: fea251b6a5db ("iio: addac: add AD74413R driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Cosmin Tanislav cosmin.tanislav@analog.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-41-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/addac/ad74413r.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index acd230a6af35..6a66d7a65db7 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -77,13 +77,13 @@ struct ad74413r_state { struct spi_transfer adc_samples_xfer[AD74413R_CHANNEL_MAX + 1];
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ struct { u8 rx_buf[AD74413R_FRAME_SIZE * AD74413R_CHANNEL_MAX]; s64 timestamp; - } adc_samples_buf ____cacheline_aligned; + } adc_samples_buf __aligned(IIO_DMA_MINALIGN);
u8 adc_samples_tx_buf[AD74413R_FRAME_SIZE * AD74413R_CHANNEL_MAX]; u8 reg_tx_buf[AD74413R_FRAME_SIZE];
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 026bffa458d029a5f15ac3f82a9bb0f64aca403d ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: e71d42e03c60 ("iio: amplifiers: New driver for AD8366 Dual-Digital Variable Gain Amplifier") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-42-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/amplifiers/ad8366.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c index 1134ae12e531..f2c2ea79a07f 100644 --- a/drivers/iio/amplifiers/ad8366.c +++ b/drivers/iio/amplifiers/ad8366.c @@ -45,10 +45,10 @@ struct ad8366_state { enum ad8366_type type; struct ad8366_info *info; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ - unsigned char data[2] ____cacheline_aligned; + unsigned char data[2] __aligned(IIO_DMA_MINALIGN); };
static struct ad8366_info ad8366_infos[] = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 314d2b1978bb3d20b1ec239f4e28c394da493f36 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 50dd64d57eee ("iio: common: ssp_sensors: Add sensorhub driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-43-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/common/ssp_sensors/ssp.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/iio/common/ssp_sensors/ssp.h b/drivers/iio/common/ssp_sensors/ssp.h index abb832795619..f649cdecc277 100644 --- a/drivers/iio/common/ssp_sensors/ssp.h +++ b/drivers/iio/common/ssp_sensors/ssp.h @@ -221,8 +221,7 @@ struct ssp_data { struct iio_dev *sensor_devs[SSP_SENSOR_MAX]; atomic_t enable_refcount;
- __le16 header_buffer[SSP_HEADER_BUFFER_SIZE / sizeof(__le16)] - ____cacheline_aligned; + __le16 header_buffer[SSP_HEADER_BUFFER_SIZE / sizeof(__le16)] __aligned(IIO_DMA_MINALIGN); };
void ssp_clean_pending_list(struct ssp_data *data);
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 8779b88c214fa0f8fdfb9c54a124f468884d356a ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: 6a17a0768f77 ("iio:dac:ad5064: Add support for the ad5629r and ad5669r") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Lars-Peter Clausen lars@metafoo.de Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-44-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5064.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index d87cf14daabe..4447b8811827 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -115,13 +115,13 @@ struct ad5064_state { struct mutex lock;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ union { u8 i2c[3]; __be32 spi; - } data ____cacheline_aligned; + } data __aligned(IIO_DMA_MINALIGN); };
enum ad5064_type {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 94ec314e1bd686b669c24385ce2dbc967eb74147 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: a3e2940c24d3 ("staging:iio:dac: Add AD5360 driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Lars-Peter Clausen lars@metafoo.de Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-45-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5360.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c index 22b000a40828..e0b7f658d611 100644 --- a/drivers/iio/dac/ad5360.c +++ b/drivers/iio/dac/ad5360.c @@ -79,13 +79,13 @@ struct ad5360_state { struct mutex lock;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ union { __be32 d32; u8 d8[4]; - } data[2] ____cacheline_aligned; + } data[2] __aligned(IIO_DMA_MINALIGN); };
enum ad5360_type {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit d2b240d3d31c66df4d2da54c75ff8e27a0e006c3 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: 5691b23489db ("staging:iio:dac: Add AD5421 driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Lars-Peter Clausen lars@metafoo.de Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-46-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5421.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c index eedf661d32b2..7644acfd879e 100644 --- a/drivers/iio/dac/ad5421.c +++ b/drivers/iio/dac/ad5421.c @@ -72,13 +72,13 @@ struct ad5421_state { struct mutex lock;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ union { __be32 d32; u8 d8[4]; - } data[2] ____cacheline_aligned; + } data[2] __aligned(IIO_DMA_MINALIGN); };
static const struct iio_event_spec ad5421_current_event[] = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 678d536bb454e3bbedcaa68208550ac9dc1cc066 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: 8341dc04dfb3 ("iio:dac: Add support for the ad5449") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Lars-Peter Clausen lars@metafoo.de Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-47-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5449.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c index bad9bdaafa94..4572d6f49275 100644 --- a/drivers/iio/dac/ad5449.c +++ b/drivers/iio/dac/ad5449.c @@ -68,10 +68,10 @@ struct ad5449 { uint16_t dac_cache[AD5449_MAX_CHANNELS];
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ - __be16 data[2] ____cacheline_aligned; + __be16 data[2] __aligned(IIO_DMA_MINALIGN); };
enum ad5449_type {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 00b9737caa5aaed5cf45a7c7498edf5957efa3b2 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 0dbe59c7a788 ("iio:ad5504: Do not store transfer buffers on the stack") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Lars-Peter Clausen lars@metafoo.de Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-48-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5504.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c index a0817e799cc0..e6c5be728bb2 100644 --- a/drivers/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c @@ -54,7 +54,7 @@ struct ad5504_state { unsigned pwr_down_mask; unsigned pwr_down_mode;
- __be16 data[2] ____cacheline_aligned; + __be16 data[2] __aligned(IIO_DMA_MINALIGN); };
/*
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 4a4a79c06caeec47003bcbee1cf3094479f26e24 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 56ca9db862bf ("iio: dac: Add support for the AD5592R/AD5593R ADCs/DACs") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Paul Cercueil paul@crapouillou.net Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-49-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5592r-base.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/dac/ad5592r-base.h b/drivers/iio/dac/ad5592r-base.h index 2a22ef691996..cc7be426cbc8 100644 --- a/drivers/iio/dac/ad5592r-base.h +++ b/drivers/iio/dac/ad5592r-base.h @@ -14,6 +14,8 @@ #include <linux/mutex.h> #include <linux/gpio/driver.h>
+#include <linux/iio/iio.h> + struct device; struct ad5592r_state;
@@ -65,7 +67,7 @@ struct ad5592r_state { u8 gpio_in; u8 gpio_val;
- __be16 spi_msg ____cacheline_aligned; + __be16 spi_msg __aligned(IIO_DMA_MINALIGN); __be16 spi_msg_nop; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 444e38927d9af093de7cdc6afbb7afdc3485da2d ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: 0357e488b825 ("iio:dac:ad5686: Refactor the driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-50-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5686.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h index cd5fff9e9d53..b7ade3a6b9b6 100644 --- a/drivers/iio/dac/ad5686.h +++ b/drivers/iio/dac/ad5686.h @@ -13,6 +13,8 @@ #include <linux/mutex.h> #include <linux/kernel.h>
+#include <linux/iio/iio.h> + #define AD5310_CMD(x) ((x) << 12)
#define AD5683_DATA(x) ((x) << 4) @@ -137,7 +139,7 @@ struct ad5686_state { struct mutex lock;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */
@@ -145,7 +147,7 @@ struct ad5686_state { __be32 d32; __be16 d16; u8 d8[4]; - } data[3] ____cacheline_aligned; + } data[3] __aligned(IIO_DMA_MINALIGN); };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit d0c167ceff2d833ee493dd58164dc87bd36e48aa ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: c499d029d805 ("iio:dac: Add ad5755 driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-51-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5755.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c index 1a63b8456725..beadfa938d2d 100644 --- a/drivers/iio/dac/ad5755.c +++ b/drivers/iio/dac/ad5755.c @@ -189,14 +189,14 @@ struct ad5755_state { struct mutex lock;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */
union { __be32 d32; u8 d8[4]; - } data[2] ____cacheline_aligned; + } data[2] __aligned(IIO_DMA_MINALIGN); };
enum ad5755_type {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 7d12a61187aed57863c41032acbc1fae516d6e49 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: 131497acd88a ("iio: add ad5761 DAC driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-52-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5761.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/ad5761.c b/drivers/iio/dac/ad5761.c index 4cb8471db81e..6aa1a068adb0 100644 --- a/drivers/iio/dac/ad5761.c +++ b/drivers/iio/dac/ad5761.c @@ -70,13 +70,13 @@ struct ad5761_state { enum ad5761_voltage_range range;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ union { __be32 d32; u8 d8[4]; - } data[3] ____cacheline_aligned; + } data[3] __aligned(IIO_DMA_MINALIGN); };
static const struct ad5761_range_params ad5761_range_params[] = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit b378722a3e9bb51318c0de7eeb4d71f2fcd6987f ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: 68b14d7ea956 ("staging:iio:dac: Add AD5764 driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-53-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5764.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c index d235a8047ba0..26c049d5b73a 100644 --- a/drivers/iio/dac/ad5764.c +++ b/drivers/iio/dac/ad5764.c @@ -56,13 +56,13 @@ struct ad5764_state { struct mutex lock;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ union { __be32 d32; u8 d8[4]; - } data[2] ____cacheline_aligned; + } data[2] __aligned(IIO_DMA_MINALIGN); };
enum ad5764_type {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit c32be7f035ae430ba9c142b03ceb9f935b09ed6b ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: fd9373e41b9b ("iio: dac: ad5766: add driver support for AD5766") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-54-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5766.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/dac/ad5766.c b/drivers/iio/dac/ad5766.c index 43189af2fb1f..899894523752 100644 --- a/drivers/iio/dac/ad5766.c +++ b/drivers/iio/dac/ad5766.c @@ -123,7 +123,7 @@ struct ad5766_state { u32 d32; u16 w16[2]; u8 b8[4]; - } data[3] ____cacheline_aligned; + } data[3] __aligned(IIO_DMA_MINALIGN); };
struct ad5766_span_tbl {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 27f2261d16d01858b8e5baca5a1a515b040429c4 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: cbbb819837f6 ("iio: dac: ad5770r: Add AD5770R support") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Alexandru Tachici alexandru.tachici@analog.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-55-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5770r.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/dac/ad5770r.c b/drivers/iio/dac/ad5770r.c index 7e2fd32e993a..f66d67402e43 100644 --- a/drivers/iio/dac/ad5770r.c +++ b/drivers/iio/dac/ad5770r.c @@ -140,7 +140,7 @@ struct ad5770r_state { bool ch_pwr_down[AD5770R_MAX_CHANNELS]; bool internal_ref; bool external_res; - u8 transf_buf[2] ____cacheline_aligned; + u8 transf_buf[2] __aligned(IIO_DMA_MINALIGN); };
static const struct regmap_config ad5770r_spi_regmap_config = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit b2d5e9de77c8774a5a6cff59d928f2fa38cbc642 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 791bb52a0cd2 ("iio:ad5791: Do not store transfer buffers on the stack") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-56-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad5791.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c index 339564fe47d1..a4167454da81 100644 --- a/drivers/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c @@ -95,7 +95,7 @@ struct ad5791_state { union { __be32 d32; u8 d8[4]; - } data[3] ____cacheline_aligned; + } data[3] __aligned(IIO_DMA_MINALIGN); };
enum ad5791_supported_device_ids {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 8482468b30bdb16d4a764f995d7a63d94fa0cf40 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 0bb12606c05f ("iio:dac:ad7293: add support for AD7293") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Antoniu Miclaus antoniu.miclaus@analog.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-57-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad7293.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/dac/ad7293.c b/drivers/iio/dac/ad7293.c index 59a38ca4c3c7..06f05750d921 100644 --- a/drivers/iio/dac/ad7293.c +++ b/drivers/iio/dac/ad7293.c @@ -144,7 +144,7 @@ struct ad7293_state { struct regulator *reg_avdd; struct regulator *reg_vdrive; u8 page_select; - u8 data[3] ____cacheline_aligned; + u8 data[3] __aligned(IIO_DMA_MINALIGN); };
static int ad7293_page_select(struct ad7293_state *st, unsigned int reg)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 69e51448ddfb9062efdf83e2d3179498e0aeb293 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: f83478240e74 ("iio:dac: Add support for the AD7303") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-58-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad7303.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/ad7303.c b/drivers/iio/dac/ad7303.c index 03edf046dec6..bff6bf697d9c 100644 --- a/drivers/iio/dac/ad7303.c +++ b/drivers/iio/dac/ad7303.c @@ -44,10 +44,10 @@ struct ad7303_state {
struct mutex lock; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ - __be16 data ____cacheline_aligned; + __be16 data __aligned(IIO_DMA_MINALIGN); };
static int ad7303_write(struct ad7303_state *st, unsigned int chan,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 1c20292c6b60cfc60a5e652174b8063e5cc03fec ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 7f270bc9a2d9 ("iio: dac: AD8801: add Analog Devices AD8801/AD8803 support") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-59-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ad8801.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/dac/ad8801.c b/drivers/iio/dac/ad8801.c index 6be35c92d435..919e8c880697 100644 --- a/drivers/iio/dac/ad8801.c +++ b/drivers/iio/dac/ad8801.c @@ -26,7 +26,7 @@ struct ad8801_state { struct regulator *vrefh_reg; struct regulator *vrefl_reg;
- __be16 data ____cacheline_aligned; + __be16 data __aligned(IIO_DMA_MINALIGN); };
static int ad8801_spi_write(struct ad8801_state *state,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 2030708377a219b548a9a36da57d3852382baf1d ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Update the comment to include 'may'.
Fixes: 832cb9eeb931 ("iio: dac: add support for ltc2688") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-60-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ltc2688.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/ltc2688.c b/drivers/iio/dac/ltc2688.c index 937b0d25a11c..28bdde2d3088 100644 --- a/drivers/iio/dac/ltc2688.c +++ b/drivers/iio/dac/ltc2688.c @@ -91,10 +91,10 @@ struct ltc2688_state { struct mutex lock; int vref; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ - u8 tx_data[6] ____cacheline_aligned; + u8 tx_data[6] __aligned(IIO_DMA_MINALIGN); u8 rx_data[3]; };
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit e66bf04797f1f95a2402414c00e64d00f63d31ec ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 1b791fadf3a1 ("iio: dac: mcp4902/mcp4912/mcp4922 dac driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Acked-by: Michael Welling mwelling@ieee.org Link: https://lore.kernel.org/r/20220508175712.647246-61-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/mcp4922.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/dac/mcp4922.c b/drivers/iio/dac/mcp4922.c index cb9e60e71b91..6c0e31032c57 100644 --- a/drivers/iio/dac/mcp4922.c +++ b/drivers/iio/dac/mcp4922.c @@ -29,7 +29,7 @@ struct mcp4922_state { unsigned int value[MCP4922_NUM_CHANNELS]; unsigned int vref_mv; struct regulator *vref_reg; - u8 mosi[2] ____cacheline_aligned; + u8 mosi[2] __aligned(IIO_DMA_MINALIGN); };
#define MCP4922_CHAN(chan, bits) { \
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 03a0cc77f164e4e59b970d50c6e9a6caf06dae80 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 61011264c1af ("iio: dac: Add Texas Instruments 8/10/12-bit 2/4-channel DAC driver") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-62-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ti-dac082s085.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/dac/ti-dac082s085.c b/drivers/iio/dac/ti-dac082s085.c index 106ce3546419..8e1590e3cc8b 100644 --- a/drivers/iio/dac/ti-dac082s085.c +++ b/drivers/iio/dac/ti-dac082s085.c @@ -55,7 +55,7 @@ struct ti_dac_chip { bool powerdown; u8 powerdown_mode; u8 resolution; - u8 buf[2] ____cacheline_aligned; + u8 buf[2] __aligned(IIO_DMA_MINALIGN); };
#define WRITE_NOT_UPDATE(chan) (0x00 | (chan) << 6)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 58e22371539e01c742be5c30295f591a6a17e348 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: df38a4a72a3b ("iio: dac: add TI DAC5571 family support") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Sean Nyekjaer sean.nyekjaer@prevas.dk Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-63-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ti-dac5571.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/dac/ti-dac5571.c b/drivers/iio/dac/ti-dac5571.c index 4b6b04038e94..c8fbacb27515 100644 --- a/drivers/iio/dac/ti-dac5571.c +++ b/drivers/iio/dac/ti-dac5571.c @@ -52,7 +52,7 @@ struct dac5571_data { struct dac5571_spec const *spec; int (*dac5571_cmd)(struct dac5571_data *data, int channel, u16 val); int (*dac5571_pwrdwn)(struct dac5571_data *data, int channel, u8 pwrdwn); - u8 buf[3] ____cacheline_aligned; + u8 buf[3] __aligned(IIO_DMA_MINALIGN); };
#define DAC5571_POWERDOWN(mode) ((mode) + 1)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 3637c49ed54632d7c221af718d2d7b1d381d4b6e ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 7a02ef7907d8 ("iio:dac:ti-dac7311 Add driver for Texas Instrument DAC7311") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Charles-Antoine Couret charles-antoine.couret@essensium.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-64-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ti-dac7311.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/dac/ti-dac7311.c b/drivers/iio/dac/ti-dac7311.c index 4afc411725d9..7f89d2a52f49 100644 --- a/drivers/iio/dac/ti-dac7311.c +++ b/drivers/iio/dac/ti-dac7311.c @@ -52,7 +52,7 @@ struct ti_dac_chip { bool powerdown; u8 powerdown_mode; u8 resolution; - u8 buf[2] ____cacheline_aligned; + u8 buf[2] __aligned(IIO_DMA_MINALIGN); };
static u8 ti_dac_get_power(struct ti_dac_chip *ti_dac, bool powerdown)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit b9ac08b3282a95fcefb057c2886028a6807725d8 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Updated help text to 'may' require buffers to be in their own cacheline.
Fixes: 977724d20584 ("iio:dac:ti-dac7612: Add driver for Texas Instruments DAC7612") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Ricardo Ribalda ribalda@kernel.org Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-65-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/ti-dac7612.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/ti-dac7612.c b/drivers/iio/dac/ti-dac7612.c index 4c0f4b5e9ff4..8195815de26f 100644 --- a/drivers/iio/dac/ti-dac7612.c +++ b/drivers/iio/dac/ti-dac7612.c @@ -31,10 +31,10 @@ struct dac7612 { struct mutex lock;
/* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ - uint8_t data[2] ____cacheline_aligned; + uint8_t data[2] __aligned(IIO_DMA_MINALIGN); };
static int dac7612_cmd_single(struct dac7612 *priv, int channel, u16 val)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 8ff2eb625c353b1491d9f89f1dfd52e7aef5734c ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Updated help text to 'may' require buffers to be in their own cacheline.
Fixes: cd1678f96329 ("iio: frequency: New driver for AD9523 SPI Low Jitter Clock Generator") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-66-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/frequency/ad9523.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index 942870539268..97662ca1ca96 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -287,13 +287,13 @@ struct ad9523_state { struct mutex lock;
/* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. + * DMA (thus cache coherency maintenance) may require that + * transfer buffers live in their own cache lines. */ union { __be32 d32; u8 d8[4]; - } data[2] ____cacheline_aligned; + } data[2] __aligned(IIO_DMA_MINALIGN); };
static int ad9523_read(struct iio_dev *indio_dev, unsigned int addr)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 389b8972eb2a614cb3189e5fa55b1b7f66142c71 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Updated help text to 'may' require buffers to be in their own cacheline.
Fixes: e31166f0fd48 ("iio: frequency: New driver for Analog Devices ADF4350/ADF4351 Wideband Synthesizers") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-67-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/frequency/adf4350.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index be1218d86291..85e289700c3c 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -56,10 +56,10 @@ struct adf4350_state { */ struct mutex lock; /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. + * DMA (thus cache coherency maintenance) may require that + * transfer buffers live in their own cache lines. */ - __be32 val ____cacheline_aligned; + __be32 val __aligned(IIO_DMA_MINALIGN); };
static struct adf4350_platform_data default_pdata = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 0bb5675befe666eeed71ad808426cf2ec1c9a714 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 7f699bd14913 ("iio: frequency: adf4371: Add support for ADF4371 PLL") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-68-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/frequency/adf4371.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/frequency/adf4371.c b/drivers/iio/frequency/adf4371.c index ecd5e18995ad..135c8cedc33d 100644 --- a/drivers/iio/frequency/adf4371.c +++ b/drivers/iio/frequency/adf4371.c @@ -175,7 +175,7 @@ struct adf4371_state { unsigned int mod2; unsigned int rf_div_sel; unsigned int ref_div_factor; - u8 buf[10] ____cacheline_aligned; + u8 buf[10] __aligned(IIO_DMA_MINALIGN); };
static unsigned long long adf4371_pll_fract_n_get_rate(struct adf4371_state *st,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit b3f3f8d264b9be0cb3e50e89e3f8789a948a43bb ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: da35a7b526d9 ("iio: frequency: admv1013: add support for ADMV1013") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Antoniu Miclaus antoniu.miclaus@analog.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-69-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/frequency/admv1013.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c index b0e1f6571afb..ed8167271358 100644 --- a/drivers/iio/frequency/admv1013.c +++ b/drivers/iio/frequency/admv1013.c @@ -100,7 +100,7 @@ struct admv1013_state { unsigned int input_mode; unsigned int quad_se_mode; bool det_en; - u8 data[3] ____cacheline_aligned; + u8 data[3] __aligned(IIO_DMA_MINALIGN); };
static int __admv1013_spi_read(struct admv1013_state *st, unsigned int reg,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit a3e38a557a54df0edea791d7eb623515bb86e39a ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: f4eb9ac7842f ("iio: frequency: admv1014: add support for ADMV1014") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Antoniu Miclaus antoniu.miclaus@analog.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-70-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/frequency/admv1014.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/frequency/admv1014.c b/drivers/iio/frequency/admv1014.c index 1aac5665b5de..865addd10db4 100644 --- a/drivers/iio/frequency/admv1014.c +++ b/drivers/iio/frequency/admv1014.c @@ -127,7 +127,7 @@ struct admv1014_state { unsigned int quad_se_mode; unsigned int p1db_comp; bool det_en; - u8 data[3] ____cacheline_aligned; + u8 data[3] __aligned(IIO_DMA_MINALIGN); };
static const int mixer_vgate_table[] = {106, 107, 108, 110, 111, 112, 113, 114,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit f890aaac771bd015c348eddb967b4027e88344c0 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: b59c04155901 ("iio: frequency: admv4420.c: Add support for ADMV4420") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-71-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/frequency/admv4420.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/frequency/admv4420.c b/drivers/iio/frequency/admv4420.c index 51134aee8510..863ba8e98c95 100644 --- a/drivers/iio/frequency/admv4420.c +++ b/drivers/iio/frequency/admv4420.c @@ -113,7 +113,7 @@ struct admv4420_state { struct admv4420_n_counter n_counter; enum admv4420_mux_sel mux_sel; struct mutex lock; - u8 transf_buf[4] ____cacheline_aligned; + u8 transf_buf[4] __aligned(IIO_DMA_MINALIGN); };
static const struct regmap_config admv4420_regmap_config = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 9a5b11884cb72780cb824cac8aab47094654a84f ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 63aaf6d06d87 ("iio: frequency: adrf6780: add support for ADRF6780") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Antoniu Miclaus antoniu.miclaus@analog.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-72-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/frequency/adrf6780.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/frequency/adrf6780.c b/drivers/iio/frequency/adrf6780.c index 8255ffd174f6..21878bad0909 100644 --- a/drivers/iio/frequency/adrf6780.c +++ b/drivers/iio/frequency/adrf6780.c @@ -86,7 +86,7 @@ struct adrf6780_state { bool uc_bias_en; bool lo_sideband; bool vdet_out_en; - u8 data[3] ____cacheline_aligned; + u8 data[3] __aligned(IIO_DMA_MINALIGN); };
static int __adrf6780_spi_read(struct adrf6780_state *st, unsigned int reg,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit ae6eeb534924ecc2afd5a394964fd6de0ca54d39 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes tag is inaccurate but unlikely anyone will backport this beyond that point so I haven't chased the history futher than 2013.
Fixes: 3c80372dae17 ("staging:iio:adis16080: be16 cleanups") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-73-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/gyro/adis16080.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/gyro/adis16080.c b/drivers/iio/gyro/adis16080.c index acef59d822b1..14b3abf6dce9 100644 --- a/drivers/iio/gyro/adis16080.c +++ b/drivers/iio/gyro/adis16080.c @@ -45,7 +45,7 @@ struct adis16080_state { const struct adis16080_chip_info *info; struct mutex lock;
- __be16 buf ____cacheline_aligned; + __be16 buf __aligned(IIO_DMA_MINALIGN); };
static int adis16080_read_sample(struct iio_dev *indio_dev,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit ff3211b2ba9afac80ceb795d148831dd879b30b7 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 8e67875141b2 ("staging:iio:gyro: adis16130 cleanup, move to abi and bug fixes.") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-74-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/gyro/adis16130.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/gyro/adis16130.c b/drivers/iio/gyro/adis16130.c index b9c952e65b55..33cde9e6fca5 100644 --- a/drivers/iio/gyro/adis16130.c +++ b/drivers/iio/gyro/adis16130.c @@ -41,7 +41,7 @@ struct adis16130_state { struct spi_device *us; struct mutex buf_lock; - u8 buf[4] ____cacheline_aligned; + u8 buf[4] __aligned(IIO_DMA_MINALIGN); };
static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val)
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 966d2f4ee7f6e189df47abf67223266ad31e201f ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes tag is inaccurate but unlikely anyone will be interested in backporting beyond that point.
Fixes: 53ac8500ba9b ("staging:iio:adxrs450: Move header file contents to main file") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-75-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/gyro/adxrs450.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/gyro/adxrs450.c b/drivers/iio/gyro/adxrs450.c index 04f350025215..f84438e0c42c 100644 --- a/drivers/iio/gyro/adxrs450.c +++ b/drivers/iio/gyro/adxrs450.c @@ -73,7 +73,7 @@ enum { struct adxrs450_state { struct spi_device *us; struct mutex buf_lock; - __be32 tx ____cacheline_aligned; + __be32 tx __aligned(IIO_DMA_MINALIGN); __be32 rx;
};
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 3aafe923987cb4a15e16f03c6185ed4b6a78ca00 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Updated the comment to 'may' require.
Fixes: a0701b6263ae ("iio: gyro: add core driver for fxas21002c") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reviewed-by: Rui Miguel Silva rui.silva@linaro.org Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-76-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/gyro/fxas21002c_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c index 0923fd793492..a36d71d9e3ea 100644 --- a/drivers/iio/gyro/fxas21002c_core.c +++ b/drivers/iio/gyro/fxas21002c_core.c @@ -150,10 +150,10 @@ struct fxas21002c_data { struct regulator *vddio;
/* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. + * DMA (thus cache coherency maintenance) may require the + * transfer buffers live in their own cache lines. */ - s16 buffer[8] ____cacheline_aligned; + s16 buffer[8] __aligned(IIO_DMA_MINALIGN); };
enum fxas21002c_channel_index {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit c9a8417a13ed9c81383662fca8a4b89f84d31e78 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Robert Jones rjones@gateworks.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-77-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/imu/fxos8700_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/imu/fxos8700_core.c b/drivers/iio/imu/fxos8700_core.c index ab288186f36e..423cfe526f2a 100644 --- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -167,7 +167,7 @@ struct fxos8700_data { struct regmap *regmap; struct iio_trigger *trig; - __be16 buf[FXOS8700_DATA_BUF_SIZE] ____cacheline_aligned; + __be16 buf[FXOS8700_DATA_BUF_SIZE] __aligned(IIO_DMA_MINALIGN); };
/* Regmap info */
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 848847702bd10bf0bf547e38adc44c14e9742784 ]
Partial fix for this driver as a second instance was introduced in a later patch.
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: a095fadb443b ("iio: imu: inv_icm42600: add gyroscope IIO device") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Jean-Baptiste Maneyrol jean-baptiste.maneyrol@tdk.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-78-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h index 995a9dc06521..3d91469beccb 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h @@ -141,7 +141,7 @@ struct inv_icm42600_state { struct inv_icm42600_suspended suspended; struct iio_dev *indio_gyro; struct iio_dev *indio_accel; - uint8_t buffer[2] ____cacheline_aligned; + uint8_t buffer[2] __aligned(IIO_DMA_MINALIGN); struct inv_icm42600_fifo fifo; struct { int64_t gyro;
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit b0aa05065a0c1d1bffa10923dbc36f7193babbb7 ]
Second fix for this driver due to different introducing patches.
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 7f85e42a6c54 ("iio: imu: inv_icm42600: add buffer support in iio devices") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Jean-Baptiste Maneyrol jmaneyrol@invensense.com Acked-by: Jean-Baptiste Maneyrol jean-baptiste.maneyrol@tdk.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-79-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h index de2a3949dcc7..8b85ee333bf8 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h @@ -39,7 +39,7 @@ struct inv_icm42600_fifo { size_t accel; size_t total; } nb; - uint8_t data[2080] ____cacheline_aligned; + uint8_t data[2080] __aligned(IIO_DMA_MINALIGN); };
/* FIFO data packet */
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 54e03562bb960e78af050d2e550c28d77642ee44 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 6b0cc5dce072 ("iio:imu:inv_mpu6050 Fix dma and ts alignment and data leak issues.") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Jean-Baptiste Maneyrol jean-baptiste.maneyrol@tdk.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-80-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index 8e14f20b1314..94b54c501ec0 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -204,7 +204,7 @@ struct inv_mpu6050_state { s32 magn_raw_to_gauss[3]; struct iio_mount_matrix magn_orient; unsigned int suspended_sensors; - u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] ____cacheline_aligned; + u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] __aligned(IIO_DMA_MINALIGN); };
/*register and associated bit definition*/
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit b5841c38cb2f7e54b0787b3e0326a6b21b89ea3e ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: d03a74bfacce ("iio: potentiometer: Add driver support for AD5110") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Mugilraj Dhavachelvan dmugil2000@gmail.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-81-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/potentiometer/ad5110.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/potentiometer/ad5110.c b/drivers/iio/potentiometer/ad5110.c index d4eeedae56e5..8fbcce482989 100644 --- a/drivers/iio/potentiometer/ad5110.c +++ b/drivers/iio/potentiometer/ad5110.c @@ -63,10 +63,10 @@ struct ad5110_data { struct mutex lock; const struct ad5110_cfg *cfg; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ - u8 buf[2] ____cacheline_aligned; + u8 buf[2] __aligned(IIO_DMA_MINALIGN); };
static const struct iio_chan_spec ad5110_channels[] = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit da803652534271dbb4af0802bd678c759e27e6de ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 79e8a32d2aa9 ("iio: ad5272: Add support for Analog Devices digital potentiometers") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reviewed-by: Phil Reid preid@electromag.com.au Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-82-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/potentiometer/ad5272.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/potentiometer/ad5272.c b/drivers/iio/potentiometer/ad5272.c index d8cbd170262f..ed5fc0b50fe9 100644 --- a/drivers/iio/potentiometer/ad5272.c +++ b/drivers/iio/potentiometer/ad5272.c @@ -50,7 +50,7 @@ struct ad5272_data { struct i2c_client *client; struct mutex lock; const struct ad5272_cfg *cfg; - u8 buf[2] ____cacheline_aligned; + u8 buf[2] __aligned(IIO_DMA_MINALIGN); };
static const struct iio_chan_spec ad5272_channel = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit ec1ac1c0e7a14657d729159ccfbea72f434bdaf1 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: df1fd2de118e ("iio: max5481: Add support for Maxim digital potentiometers") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-83-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/potentiometer/max5481.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/potentiometer/max5481.c b/drivers/iio/potentiometer/max5481.c index 098d144a8fdd..b40e5ac218d7 100644 --- a/drivers/iio/potentiometer/max5481.c +++ b/drivers/iio/potentiometer/max5481.c @@ -44,7 +44,7 @@ static const struct max5481_cfg max5481_cfg[] = { struct max5481_data { struct spi_device *spi; const struct max5481_cfg *cfg; - u8 msg[3] ____cacheline_aligned; + u8 msg[3] __aligned(IIO_DMA_MINALIGN); };
#define MAX5481_CHANNEL { \
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit c5f78f4d2168ba21324095b0d46d4353c2eace4d ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 092cb71a604e ("iio: potentiometer: Add driver for Microchip MCP41xxx/42xxx") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-84-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/potentiometer/mcp41010.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/potentiometer/mcp41010.c b/drivers/iio/potentiometer/mcp41010.c index 30a4594d4e11..2b73c7540209 100644 --- a/drivers/iio/potentiometer/mcp41010.c +++ b/drivers/iio/potentiometer/mcp41010.c @@ -60,7 +60,7 @@ struct mcp41010_data { const struct mcp41010_cfg *cfg; struct mutex lock; /* Protect write sequences */ unsigned int value[MCP41010_MAX_WIPERS]; /* Cache wiper values */ - u8 buf[2] ____cacheline_aligned; + u8 buf[2] __aligned(IIO_DMA_MINALIGN); };
#define MCP41010_CHANNEL(ch) { \
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 4842e5de6f39ebf2c0f6da9e6a0cb751c7108507 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 22d199a53910 ("iio: potentiometer: add driver for Microchip MCP413X/414X/415X/416X/423X/424X/425X/426X") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-85-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/potentiometer/mcp4131.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/potentiometer/mcp4131.c b/drivers/iio/potentiometer/mcp4131.c index 7c8c18ab8764..7890c0993ec4 100644 --- a/drivers/iio/potentiometer/mcp4131.c +++ b/drivers/iio/potentiometer/mcp4131.c @@ -129,7 +129,7 @@ struct mcp4131_data { struct spi_device *spi; const struct mcp4131_cfg *cfg; struct mutex lock; - u8 buf[2] ____cacheline_aligned; + u8 buf[2] __aligned(IIO_DMA_MINALIGN); };
#define MCP4131_CHANNEL(ch) { \
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 2386c0f8c5b740873a4b9126c3706601b127fe22 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: 24ddb0e4bba4 ("iio: Add AS3935 lightning sensor support") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Matt Ranostay mranostay@gmail.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-87-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/proximity/as3935.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index 67891ce2bd09..ebc95cf8f5f4 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c @@ -65,7 +65,7 @@ struct as3935_state { u8 chan; s64 timestamp __aligned(8); } scan; - u8 buf[2] ____cacheline_aligned; + u8 buf[2] __aligned(IIO_DMA_MINALIGN); };
static const struct iio_chan_spec as3935_channels[] = {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 37882314d3bdc2ae775ebb9fa8ed7a94cd1aad61 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes tag is probably not where the issue was first introduced, but is likely to be as far as anyone considers backporting this fix.
Fixes: 0bd3d338f61b ("staging: iio: ad2s1200: Improve readability with be16_to_cpup") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-89-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/resolver/ad2s1200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/resolver/ad2s1200.c b/drivers/iio/resolver/ad2s1200.c index 9746bd935628..9d95241bdf8f 100644 --- a/drivers/iio/resolver/ad2s1200.c +++ b/drivers/iio/resolver/ad2s1200.c @@ -41,7 +41,7 @@ struct ad2s1200_state { struct spi_device *sdev; struct gpio_desc *sample; struct gpio_desc *rdvel; - __be16 rx ____cacheline_aligned; + __be16 rx __aligned(IIO_DMA_MINALIGN); };
static int ad2s1200_read_raw(struct iio_dev *indio_dev,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit faa05ecb1349070d874810e161b653c2220e0006 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes tag is probably not where the issue was first introduced, but is likely to be far beyond the point where anyone considers backporting this fix.
Fixes: 58f08b0af857 ("staging:iio:resolver:ad2s90 general cleanup") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-90-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/resolver/ad2s90.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/resolver/ad2s90.c b/drivers/iio/resolver/ad2s90.c index d6a91f137e13..be6836e55376 100644 --- a/drivers/iio/resolver/ad2s90.c +++ b/drivers/iio/resolver/ad2s90.c @@ -24,7 +24,7 @@ struct ad2s90_state { struct mutex lock; /* lock to protect rx buffer */ struct spi_device *sdev; - u8 rx[2] ____cacheline_aligned; + u8 rx[2] __aligned(IIO_DMA_MINALIGN); };
static int ad2s90_read_raw(struct iio_dev *indio_dev,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 732f2cb2fbb51bd5bc03a114bd102ab3b2f537fe ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition.
Fixes: f110f3188e56 ("iio: temperature: Add support for LTC2983") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-91-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/temperature/ltc2983.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c index 4fc654275155..4b7f2b8a9758 100644 --- a/drivers/iio/temperature/ltc2983.c +++ b/drivers/iio/temperature/ltc2983.c @@ -204,11 +204,11 @@ struct ltc2983_data { u8 num_channels; u8 iio_channels; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. * Holds the converted temperature */ - __be32 temp ____cacheline_aligned; + __be32 temp __aligned(IIO_DMA_MINALIGN); };
struct ltc2983_sensor {
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit ecdef5b8317cdf18acb46223e087f04a226fa619 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition
Fixes: e112dc4e18ea ("iio: temperature: Add MAX31865 RTD Support") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Navin Sankar Velliangiri navin@linumiz.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-92-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/temperature/max31865.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/temperature/max31865.c b/drivers/iio/temperature/max31865.c index e3bb78184c6e..29e23652ba5a 100644 --- a/drivers/iio/temperature/max31865.c +++ b/drivers/iio/temperature/max31865.c @@ -55,7 +55,7 @@ struct max31865_data { struct mutex lock; bool filter_50hz; bool three_wire; - u8 buf[2] ____cacheline_aligned; + u8 buf[2] __aligned(IIO_DMA_MINALIGN); };
static int max31865_read(struct max31865_data *data, u8 reg,
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 10897f34309b3c7bc14698407436c82d11c07f47 ]
____cacheline_aligned is an insufficient guarantee for non-coherent DMA on platforms with 128 byte cachelines above L1. Switch to the updated IIO_DMA_MINALIGN definition
Fixes: 1f25ca11d84a ("iio: temperature: add support for Maxim thermocouple chips") Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Cc: Matt Ranostay mranostay@gmail.com Acked-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20220508175712.647246-93-jic23@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/temperature/maxim_thermocouple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/temperature/maxim_thermocouple.c b/drivers/iio/temperature/maxim_thermocouple.c index 98c41cddc6f0..c28a7a6dea5f 100644 --- a/drivers/iio/temperature/maxim_thermocouple.c +++ b/drivers/iio/temperature/maxim_thermocouple.c @@ -122,7 +122,7 @@ struct maxim_thermocouple_data { struct spi_device *spi; const struct maxim_thermocouple_chip *chip;
- u8 buffer[16] ____cacheline_aligned; + u8 buffer[16] __aligned(IIO_DMA_MINALIGN); char tc_type; };
From: Rex-BC Chen rex-bc.chen@mediatek.com
[ Upstream commit edabcf71d100fd433a0fc2d0c97057c446c33b2a ]
Original assert/deassert bit is BIT(0), but it's more resonable to modify them to BIT(id % 32) which is based on id.
This patch will not influence any previous driver because the reset is only used for thermal. The id (MT8183_INFRACFG_AO_THERM_SW_RST) is 0.
Fixes: 64ebb57a3df6 ("clk: reset: Modify reset-controller driver") Signed-off-by: Rex-BC Chen rex-bc.chen@mediatek.com Reviewed-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Nícolas F. R. A. Prado nfraprado@collabora.com Tested-by: Nícolas F. R. A. Prado nfraprado@collabora.com Link: https://lore.kernel.org/r/20220523093346.28493-3-rex-bc.chen@mediatek.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/mediatek/reset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c index bcec4b89f449..834d26e9bdfd 100644 --- a/drivers/clk/mediatek/reset.c +++ b/drivers/clk/mediatek/reset.c @@ -25,7 +25,7 @@ static int mtk_reset_assert_set_clr(struct reset_controller_dev *rcdev, struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); unsigned int reg = data->regofs + ((id / 32) << 4);
- return regmap_write(data->regmap, reg, 1); + return regmap_write(data->regmap, reg, BIT(id % 32)); }
static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev, @@ -34,7 +34,7 @@ static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev, struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); unsigned int reg = data->regofs + ((id / 32) << 4) + 0x4;
- return regmap_write(data->regmap, reg, 1); + return regmap_write(data->regmap, reg, BIT(id % 32)); }
static int mtk_reset_assert(struct reset_controller_dev *rcdev,
From: Haibo Chen haibo.chen@nxp.com
[ Upstream commit 18d6d8fe4f24938985844d52c481b86fcce9d102 ]
When debug, find after system boot up, all adc register operation will trigger system hang, this is because the internal adc ipg clock is gate off. In dts, only reference the IMX93_CLK_ADC1_GATE, which is adc1, no one touch the adc_root, so adc_root will be gate off automatically after system boot up.
Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk") Signed-off-by: Haibo Chen haibo.chen@nxp.com Signed-off-by: Jacky Bai ping.bai@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com Reviewed-by: Peng Fan peng.fan@nxp.com Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/20220609132902.3504651-2-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-imx93.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c index edcc87661d1f..172cd56c9610 100644 --- a/drivers/clk/imx/clk-imx93.c +++ b/drivers/clk/imx/clk-imx93.c @@ -150,7 +150,7 @@ static const struct imx93_clk_ccgr { { IMX93_CLK_A55_GATE, "a55", "a55_root", 0x8000, }, /* M33 critical clk for system run */ { IMX93_CLK_CM33_GATE, "cm33", "m33_root", 0x8040, CLK_IS_CRITICAL }, - { IMX93_CLK_ADC1_GATE, "adc1", "osc_24m", 0x82c0, }, + { IMX93_CLK_ADC1_GATE, "adc1", "adc_root", 0x82c0, }, { IMX93_CLK_WDOG1_GATE, "wdog1", "osc_24m", 0x8300, }, { IMX93_CLK_WDOG2_GATE, "wdog2", "osc_24m", 0x8340, }, { IMX93_CLK_WDOG3_GATE, "wdog3", "osc_24m", 0x8380, },
From: Peng Fan peng.fan@nxp.com
[ Upstream commit 1e3c837a663e9a12c4afabb3279d18cb5110a8f4 ]
NIC_MEDIA sources from media_axi_root, not media_apb_root.
Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk") Signed-off-by: Peng Fan peng.fan@nxp.com Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/20220609132902.3504651-3-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-imx93.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c index 172cd56c9610..26885bd3971c 100644 --- a/drivers/clk/imx/clk-imx93.c +++ b/drivers/clk/imx/clk-imx93.c @@ -219,7 +219,7 @@ static const struct imx93_clk_ccgr { { IMX93_CLK_LCDIF_GATE, "lcdif", "media_apb_root", 0x9640, }, { IMX93_CLK_PXP_GATE, "pxp", "media_apb_root", 0x9680, }, { IMX93_CLK_ISI_GATE, "isi", "media_apb_root", 0x96c0, }, - { IMX93_CLK_NIC_MEDIA_GATE, "nic_media", "media_apb_root", 0x9700, }, + { IMX93_CLK_NIC_MEDIA_GATE, "nic_media", "media_axi_root", 0x9700, }, { IMX93_CLK_USB_CONTROLLER_GATE, "usb_controller", "hsio_root", 0x9a00, }, { IMX93_CLK_USB_TEST_60M_GATE, "usb_test_60m", "hsio_usb_test_60m_root", 0x9a40, }, { IMX93_CLK_HSIO_TROUT_24M_GATE, "hsio_trout_24m", "osc_24m", 0x9a80, },
From: Peng Fan peng.fan@nxp.com
[ Upstream commit 044034efbeea05f65c09d2ba15ceeab53b60e947 ]
According to spec: A value of 0 is disallowed and should not be programmed in this register
Fix to 1.
Fixes: 1b26cb8a77a4 ("clk: imx: support fracn gppll") Signed-off-by: Peng Fan peng.fan@nxp.com Reviewed-by: Jacky Bai ping.bai@nxp.com Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/20220609132902.3504651-5-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-fracn-gppll.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index 71c102d950ab..36a53c60e71f 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -64,10 +64,10 @@ struct clk_fracn_gppll { * Fout = Fvco / (rdiv * odiv) */ static const struct imx_fracn_gppll_rate_table fracn_tbl[] = { - PLL_FRACN_GP(650000000U, 81, 0, 0, 0, 3), - PLL_FRACN_GP(594000000U, 198, 0, 0, 0, 8), - PLL_FRACN_GP(560000000U, 70, 0, 0, 0, 3), - PLL_FRACN_GP(400000000U, 50, 0, 0, 0, 3), + PLL_FRACN_GP(650000000U, 81, 0, 1, 0, 3), + PLL_FRACN_GP(594000000U, 198, 0, 1, 0, 8), + PLL_FRACN_GP(560000000U, 70, 0, 1, 0, 3), + PLL_FRACN_GP(400000000U, 50, 0, 1, 0, 3), PLL_FRACN_GP(393216000U, 81, 92, 100, 0, 5) };
From: Liu Ying victor.liu@nxp.com
[ Upstream commit 5ebaf9f7da5bb2dc56d394eabfcbe46dc6b1ea8d ]
The PLL parameters in rate table should be directly compared with those read from PLL registers instead of the cooked ones.
Fixes: 1b26cb8a77a4 ("clk: imx: support fracn gppll") Cc: Abel Vesa abel.vesa@nxp.com Cc: Michael Turquette mturquette@baylibre.com Cc: Stephen Boyd sboyd@kernel.org Cc: Shawn Guo shawnguo@kernel.org Cc: Sascha Hauer s.hauer@pengutronix.de Cc: Pengutronix Kernel Team kernel@pengutronix.de Cc: Fabio Estevam festevam@gmail.com Cc: NXP Linux Team linux-imx@nxp.com Cc: Peng Fan peng.fan@nxp.com Signed-off-by: Liu Ying victor.liu@nxp.com Reviewed-by: Peng Fan peng.fan@nxp.com Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/20220609132902.3504651-6-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-fracn-gppll.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index 36a53c60e71f..cb06b0045e9e 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -131,18 +131,7 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon mfi = FIELD_GET(PLL_MFI_MASK, pll_div);
rdiv = FIELD_GET(PLL_RDIV_MASK, pll_div); - rdiv = rdiv + 1; odiv = FIELD_GET(PLL_ODIV_MASK, pll_div); - switch (odiv) { - case 0: - odiv = 2; - break; - case 1: - odiv = 3; - break; - default: - break; - }
/* * Sometimes, the recalculated rate has deviation due to @@ -160,6 +149,19 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon if (rate) return (unsigned long)rate;
+ rdiv = rdiv + 1; + + switch (odiv) { + case 0: + odiv = 2; + break; + case 1: + odiv = 3; + break; + default: + break; + } + /* Fvco = Fref * (MFI + MFN / MFD) */ fvco = fvco * mfi * mfd + fvco * mfn; do_div(fvco, mfd * rdiv * odiv);
From: Peng Fan peng.fan@nxp.com
[ Upstream commit f300cb7fccf69ba1835b983c76d70deb818ad194 ]
According to Reference Manual: 000b - Divide by 1 001b - Divide by 1 010b - Divide by 2 011b - Divide by 3 100b - Divide by 4 101b - Divide by 5 110b - Divide by 6 111b - Divide by 7
So only need increase rdiv by 1 when the register value is 0.
Fixes: 1b26cb8a77a4 ("clk: imx: support fracn gppll") Signed-off-by: Peng Fan peng.fan@nxp.com Reviewed-by: Jacky Bai ping.bai@nxp.com Reviewed-by: Abel Vesa abel.vesa@linaro.org Link: https://lore.kernel.org/r/20220609132902.3504651-7-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-fracn-gppll.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index cb06b0045e9e..025b73229cdd 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -149,7 +149,8 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon if (rate) return (unsigned long)rate;
- rdiv = rdiv + 1; + if (!rdiv) + rdiv = rdiv + 1;
switch (odiv) { case 0:
From: Dongliang Mu mudongliangabcd@gmail.com
[ Upstream commit 1a685940e6200e9def6e34bbaa19dd31dc5aeaf8 ]
Currently rxe_alloc checks ret to indicate error, but 1 is also a valid return and just indicates that the allocation succeeded with a wrap.
Fix this by modifying the check to be < 0.
Link: https://lore.kernel.org/r/20220609070656.1446121-1-dzm91@hust.edu.cn Fixes: 3225717f6dfa ("RDMA/rxe: Replace red-black trees by xarrays") Signed-off-by: Dongliang Mu mudongliangabcd@gmail.com Reviewed-by: Bob Pearson rpearsonhpe@gmail.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_pool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c index 19b14826385b..e9f3bbd8d605 100644 --- a/drivers/infiniband/sw/rxe/rxe_pool.c +++ b/drivers/infiniband/sw/rxe/rxe_pool.c @@ -139,7 +139,7 @@ void *rxe_alloc(struct rxe_pool *pool)
err = xa_alloc_cyclic(&pool->xa, &elem->index, elem, pool->limit, &pool->next, GFP_KERNEL); - if (err) + if (err < 0) goto err_free;
return obj; @@ -167,7 +167,7 @@ int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem)
err = xa_alloc_cyclic(&pool->xa, &elem->index, elem, pool->limit, &pool->next, GFP_KERNEL); - if (err) + if (err < 0) goto err_cnt;
return 0;
From: Miaohe Lin linmiaohe@huawei.com
[ Upstream commit ed913b055a74b723976f8e885a3395162a0371e6 ]
If make_device_exclusive_range() fails or returns pages marked for exclusive access less than required, remaining fields of pages will left uninitialized. So dmirror_atomic_map() will access those yet uninitialized fields of pages. To fix it, do dmirror_atomic_map() iff all pages are marked for exclusive access (we will break if mapped is less than required anyway) so we won't access those uninitialized fields of pages.
Link: https://lkml.kernel.org/r/20220609130835.35110-1-linmiaohe@huawei.com Fixes: b659baea7546 ("mm: selftests for exclusive device memory") Signed-off-by: Miaohe Lin linmiaohe@huawei.com Cc: Jerome Glisse jglisse@redhat.com Cc: Alistair Popple apopple@nvidia.com Cc: Jason Gunthorpe jgg@ziepe.ca Cc: Ralph Campbell rcampbell@nvidia.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/test_hmm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/lib/test_hmm.c b/lib/test_hmm.c index cfe632047839..f2c3015c5c82 100644 --- a/lib/test_hmm.c +++ b/lib/test_hmm.c @@ -732,7 +732,7 @@ static int dmirror_exclusive(struct dmirror *dmirror,
mmap_read_lock(mm); for (addr = start; addr < end; addr = next) { - unsigned long mapped; + unsigned long mapped = 0; int i;
if (end < addr + (ARRAY_SIZE(pages) << PAGE_SHIFT)) @@ -741,7 +741,13 @@ static int dmirror_exclusive(struct dmirror *dmirror, next = addr + (ARRAY_SIZE(pages) << PAGE_SHIFT);
ret = make_device_exclusive_range(mm, addr, next, pages, NULL); - mapped = dmirror_atomic_map(addr, next, pages, dmirror); + /* + * Do dmirror_atomic_map() iff all pages are marked for + * exclusive access to avoid accessing uninitialized + * fields of pages. + */ + if (ret == (next - addr) >> PAGE_SHIFT) + mapped = dmirror_atomic_map(addr, next, pages, dmirror); for (i = 0; i < ret; i++) { if (pages[i]) { unlock_page(pages[i]);
From: Miaohe Lin linmiaohe@huawei.com
[ Upstream commit 1e57ffb6e3fd9583268c6462c4e3853575b21701 ]
Think about the below scene:
CPU1 CPU2 memunmap_pages percpu_ref_exit __percpu_ref_exit free_percpu(percpu_count); /* percpu_count is freed here! */ get_dev_pagemap xa_load(&pgmap_array, PHYS_PFN(phys)) /* pgmap still in the pgmap_array */ percpu_ref_tryget_live(&pgmap->ref) if __ref_is_percpu /* __PERCPU_REF_ATOMIC_DEAD not set yet */ this_cpu_inc(*percpu_count) /* access freed percpu_count here! */ ref->percpu_count_ptr = __PERCPU_REF_ATOMIC_DEAD; /* too late... */ pageunmap_range
To fix the issue, do percpu_ref_exit() after pgmap_array is emptied. So we won't do percpu_ref_tryget_live() against a being freed percpu_ref.
Link: https://lkml.kernel.org/r/20220609121305.2508-1-linmiaohe@huawei.com Fixes: b7b3c01b1915 ("mm/memremap_pages: support multiple ranges per invocation") Signed-off-by: Miaohe Lin linmiaohe@huawei.com Cc: Dan Williams dan.j.williams@intel.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/memremap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/memremap.c b/mm/memremap.c index 745eea0f99c3..2bdb66854832 100644 --- a/mm/memremap.c +++ b/mm/memremap.c @@ -141,10 +141,10 @@ void memunmap_pages(struct dev_pagemap *pgmap) for (i = 0; i < pgmap->nr_range; i++) percpu_ref_put_many(&pgmap->ref, pfn_len(pgmap, i)); wait_for_completion(&pgmap->done); - percpu_ref_exit(&pgmap->ref);
for (i = 0; i < pgmap->nr_range; i++) pageunmap_range(pgmap, i); + percpu_ref_exit(&pgmap->ref);
WARN_ONCE(pgmap->altmap.alloc, "failed to free all reserved pages\n"); devmap_managed_enable_put(pgmap);
From: Sean Christopherson seanjc@google.com
[ Upstream commit a1040b0d42acf69bb4f6dbdc54c2dcd78eea1de5 ]
Don't set Accessed/Dirty bits for a struct page with PG_reserved set, i.e. don't set A/D bits for the ZERO_PAGE. The ZERO_PAGE (or pages depending on the architecture) should obviously never be written, and similarly there's no point in marking it accessed as the page will never be swapped out or reclaimed. The comment in page-flags.h is quite clear that PG_reserved pages should be managed only by their owner, and strictly following that mandate also simplifies KVM's logic.
Fixes: 7df003c85218 ("KVM: fix overflow of zero page refcount with ksm running") Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220429010416.2788472-4-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- virt/kvm/kvm_main.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 28126ee221b5..98246f3dea87 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2853,16 +2853,28 @@ void kvm_release_pfn_dirty(kvm_pfn_t pfn) } EXPORT_SYMBOL_GPL(kvm_release_pfn_dirty);
+static bool kvm_is_ad_tracked_pfn(kvm_pfn_t pfn) +{ + if (!pfn_valid(pfn)) + return false; + + /* + * Per page-flags.h, pages tagged PG_reserved "should in general not be + * touched (e.g. set dirty) except by its owner". + */ + return !PageReserved(pfn_to_page(pfn)); +} + void kvm_set_pfn_dirty(kvm_pfn_t pfn) { - if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) + if (kvm_is_ad_tracked_pfn(pfn)) SetPageDirty(pfn_to_page(pfn)); } EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty);
void kvm_set_pfn_accessed(kvm_pfn_t pfn) { - if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) + if (kvm_is_ad_tracked_pfn(pfn)) mark_page_accessed(pfn_to_page(pfn)); } EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed);
From: Sean Christopherson seanjc@google.com
[ Upstream commit 7cdcdfe50d8d68b7b9ba2e1b0345ff47fdda390f ]
Convert diag318_test_handler to use vm_create_with_vcpus() and pass around a 'struct kvm_vcpu' object instead of passing around vCPU IDs. Note, this is a "functional" change in the sense that the test now creates a vCPU with vcpu_id==0 instead of vcpu_id==6. The non-zero VCPU_ID was 100% arbitrary and added little to no validation coverage. If testing non-zero vCPU IDs is desirable for generic tests, that can be done in the future by tweaking the VM creation helpers.
Signed-off-by: Sean Christopherson seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../selftests/kvm/lib/s390x/diag318_test_handler.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/kvm/lib/s390x/diag318_test_handler.c b/tools/testing/selftests/kvm/lib/s390x/diag318_test_handler.c index 86b9e611ad87..21c31fe10c1a 100644 --- a/tools/testing/selftests/kvm/lib/s390x/diag318_test_handler.c +++ b/tools/testing/selftests/kvm/lib/s390x/diag318_test_handler.c @@ -8,8 +8,6 @@ #include "test_util.h" #include "kvm_util.h"
-#define VCPU_ID 6 - #define ICPT_INSTRUCTION 0x04 #define IPA0_DIAG 0x8300
@@ -27,14 +25,15 @@ static void guest_code(void) */ static uint64_t diag318_handler(void) { + struct kvm_vcpu *vcpu; struct kvm_vm *vm; struct kvm_run *run; uint64_t reg; uint64_t diag318_info;
- vm = vm_create_default(VCPU_ID, 0, guest_code); - vcpu_run(vm, VCPU_ID); - run = vcpu_state(vm, VCPU_ID); + vm = vm_create_with_one_vcpu(&vcpu, guest_code); + vcpu_run(vm, vcpu->id); + run = vcpu->run;
TEST_ASSERT(run->exit_reason == KVM_EXIT_S390_SIEIC, "DIAGNOSE 0x0318 instruction was not intercepted");
From: Sean Christopherson seanjc@google.com
[ Upstream commit 3468fd7d883110e481dfb8c8c7b802dc252ab186 ]
Use vm_create_with_vcpus() in max_guest_memory_test and reference vCPUs by their 'struct kvm_vcpu' object instead of their ID.
Signed-off-by: Sean Christopherson seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../selftests/kvm/max_guest_memory_test.c | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/tools/testing/selftests/kvm/max_guest_memory_test.c b/tools/testing/selftests/kvm/max_guest_memory_test.c index 15f046e19cb2..d59918d5cbe2 100644 --- a/tools/testing/selftests/kvm/max_guest_memory_test.c +++ b/tools/testing/selftests/kvm/max_guest_memory_test.c @@ -28,8 +28,7 @@ static void guest_code(uint64_t start_gpa, uint64_t end_gpa, uint64_t stride) }
struct vcpu_info { - struct kvm_vm *vm; - uint32_t id; + struct kvm_vcpu *vcpu; uint64_t start_gpa; uint64_t end_gpa; }; @@ -60,12 +59,13 @@ static void run_vcpu(struct kvm_vm *vm, uint32_t vcpu_id)
static void *vcpu_worker(void *data) { - struct vcpu_info *vcpu = data; + struct vcpu_info *info = data; + struct kvm_vcpu *vcpu = info->vcpu; struct kvm_vm *vm = vcpu->vm; struct kvm_sregs sregs; struct kvm_regs regs;
- vcpu_args_set(vm, vcpu->id, 3, vcpu->start_gpa, vcpu->end_gpa, + vcpu_args_set(vm, vcpu->id, 3, info->start_gpa, info->end_gpa, vm_get_page_size(vm));
/* Snapshot regs before the first run. */ @@ -89,8 +89,8 @@ static void *vcpu_worker(void *data) return NULL; }
-static pthread_t *spawn_workers(struct kvm_vm *vm, uint64_t start_gpa, - uint64_t end_gpa) +static pthread_t *spawn_workers(struct kvm_vm *vm, struct kvm_vcpu **vcpus, + uint64_t start_gpa, uint64_t end_gpa) { struct vcpu_info *info; uint64_t gpa, nr_bytes; @@ -108,8 +108,7 @@ static pthread_t *spawn_workers(struct kvm_vm *vm, uint64_t start_gpa, TEST_ASSERT(nr_bytes, "C'mon, no way you have %d CPUs", nr_vcpus);
for (i = 0, gpa = start_gpa; i < nr_vcpus; i++, gpa += nr_bytes) { - info[i].vm = vm; - info[i].id = i; + info[i].vcpu = vcpus[i]; info[i].start_gpa = gpa; info[i].end_gpa = gpa + nr_bytes; pthread_create(&threads[i], NULL, vcpu_worker, &info[i]); @@ -172,6 +171,7 @@ int main(int argc, char *argv[]) uint64_t max_gpa, gpa, slot_size, max_mem, i; int max_slots, slot, opt, fd; bool hugepages = false; + struct kvm_vcpu **vcpus; pthread_t *threads; struct kvm_vm *vm; void *mem; @@ -215,7 +215,10 @@ int main(int argc, char *argv[]) } }
- vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL); + vcpus = malloc(nr_vcpus * sizeof(*vcpus)); + TEST_ASSERT(vcpus, "Failed to allocate vCPU array"); + + vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
max_gpa = vm_get_max_gfn(vm) << vm_get_page_shift(vm); TEST_ASSERT(max_gpa > (4 * slot_size), "MAXPHYADDR <4gb "); @@ -252,7 +255,10 @@ int main(int argc, char *argv[]) }
atomic_set(&rendezvous, nr_vcpus + 1); - threads = spawn_workers(vm, start_gpa, gpa); + threads = spawn_workers(vm, vcpus, start_gpa, gpa); + + free(vcpus); + vcpus = NULL;
pr_info("Running with %lugb of guest memory and %u vCPUs\n", (gpa - start_gpa) / size_1gb, nr_vcpus);
From: Duoming Zhou duoming@zju.edu.cn
[ Upstream commit 77515ebaf01920e2db49e04672ef669a7c2907f2 ]
The dev_coredumpv() and dev_coredumpm() could not be used in atomic context, because they call kvasprintf_const() and kstrdup() with GFP_KERNEL parameter. The process is shown below:
dev_coredumpv(.., gfp_t gfp) dev_coredumpm(.., gfp_t gfp) dev_set_name kobject_set_name_vargs kvasprintf_const(GFP_KERNEL, ...); //may sleep kstrdup(s, GFP_KERNEL); //may sleep
This patch removes gfp_t parameter of dev_coredumpv() and dev_coredumpm() and changes the gfp_t parameter of kzalloc() in dev_coredumpm() to GFP_KERNEL in order to show they could not be used in atomic context.
Fixes: 833c95456a70 ("device coredump: add new device coredump class") Reviewed-by: Brian Norris briannorris@chromium.org Reviewed-by: Johannes Berg johannes@sipsolutions.net Signed-off-by: Duoming Zhou duoming@zju.edu.cn Link: https://lore.kernel.org/r/df72af3b1862bac7d8e793d1f3931857d3779dfd.165456929... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/devcoredump.c | 16 ++++++---------- drivers/bluetooth/btmrvl_sdio.c | 2 +- drivers/bluetooth/hci_qca.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_dump.c | 2 +- drivers/gpu/drm/msm/disp/msm_disp_snapshot.c | 4 ++-- drivers/gpu/drm/msm/msm_gpu.c | 4 ++-- drivers/media/platform/qcom/venus/core.c | 2 +- drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c | 2 +- drivers/net/wireless/ath/ath10k/coredump.c | 2 +- .../net/wireless/ath/wil6210/wil_crash_dump.c | 2 +- .../wireless/broadcom/brcm80211/brcmfmac/debug.c | 2 +- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 6 ++---- drivers/net/wireless/marvell/mwifiex/main.c | 3 +-- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 3 +-- drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 3 +-- drivers/net/wireless/realtek/rtw88/main.c | 2 +- drivers/net/wireless/realtek/rtw89/ser.c | 2 +- drivers/remoteproc/qcom_q6v5_mss.c | 2 +- drivers/remoteproc/remoteproc_coredump.c | 8 ++++---- include/drm/drm_print.h | 2 +- include/linux/devcoredump.h | 13 ++++++------- sound/soc/intel/avs/apl.c | 2 +- sound/soc/intel/avs/skl.c | 2 +- sound/soc/intel/catpt/dsp.c | 2 +- 24 files changed, 40 insertions(+), 50 deletions(-)
diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c index f4d794d6bb85..8535f0bd5dfb 100644 --- a/drivers/base/devcoredump.c +++ b/drivers/base/devcoredump.c @@ -173,15 +173,13 @@ static void devcd_freev(void *data) * @dev: the struct device for the crashed device * @data: vmalloc data containing the device coredump * @datalen: length of the data - * @gfp: allocation flags * * This function takes ownership of the vmalloc'ed data and will free * it when it is no longer used. See dev_coredumpm() for more information. */ -void dev_coredumpv(struct device *dev, void *data, size_t datalen, - gfp_t gfp) +void dev_coredumpv(struct device *dev, void *data, size_t datalen) { - dev_coredumpm(dev, NULL, data, datalen, gfp, devcd_readv, devcd_freev); + dev_coredumpm(dev, NULL, data, datalen, devcd_readv, devcd_freev); } EXPORT_SYMBOL_GPL(dev_coredumpv);
@@ -236,7 +234,6 @@ static ssize_t devcd_read_from_sgtable(char *buffer, loff_t offset, * @owner: the module that contains the read/free functions, use %THIS_MODULE * @data: data cookie for the @read/@free functions * @datalen: length of the data - * @gfp: allocation flags * @read: function to read from the given buffer * @free: function to free the given buffer * @@ -246,7 +243,7 @@ static ssize_t devcd_read_from_sgtable(char *buffer, loff_t offset, * function will be called to free the data. */ void dev_coredumpm(struct device *dev, struct module *owner, - void *data, size_t datalen, gfp_t gfp, + void *data, size_t datalen, ssize_t (*read)(char *buffer, loff_t offset, size_t count, void *data, size_t datalen), void (*free)(void *data)) @@ -268,7 +265,7 @@ void dev_coredumpm(struct device *dev, struct module *owner, if (!try_module_get(owner)) goto free;
- devcd = kzalloc(sizeof(*devcd), gfp); + devcd = kzalloc(sizeof(*devcd), GFP_KERNEL); if (!devcd) goto put_module;
@@ -318,7 +315,6 @@ EXPORT_SYMBOL_GPL(dev_coredumpm); * @dev: the struct device for the crashed device * @table: the dump data * @datalen: length of the data - * @gfp: allocation flags * * Creates a new device coredump for the given device. If a previous one hasn't * been read yet, the new coredump is discarded. The data lifetime is determined @@ -326,9 +322,9 @@ EXPORT_SYMBOL_GPL(dev_coredumpm); * it will free the data. */ void dev_coredumpsg(struct device *dev, struct scatterlist *table, - size_t datalen, gfp_t gfp) + size_t datalen) { - dev_coredumpm(dev, NULL, table, datalen, gfp, devcd_read_from_sgtable, + dev_coredumpm(dev, NULL, table, datalen, devcd_read_from_sgtable, devcd_free_sgtable); } EXPORT_SYMBOL_GPL(dev_coredumpsg); diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index b8ef66f89fc1..9b9728719db2 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -1515,7 +1515,7 @@ static void btmrvl_sdio_coredump(struct device *dev) /* fw_dump_data will be free in device coredump release function * after 5 min */ - dev_coredumpv(&card->func->dev, fw_dump_data, fw_dump_len, GFP_KERNEL); + dev_coredumpv(&card->func->dev, fw_dump_data, fw_dump_len); BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump end"); }
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 8df11016fd51..95a97b380823 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1120,7 +1120,7 @@ static void qca_controller_memdump(struct work_struct *work) qca_memdump->ram_dump_size); memdump_buf = qca_memdump->memdump_buf_head; dev_coredumpv(&hu->serdev->dev, memdump_buf, - qca_memdump->received_dump, GFP_KERNEL); + qca_memdump->received_dump); cancel_delayed_work(&qca->ctrl_memdump_timeout); kfree(qca->qca_memdump); qca->qca_memdump = NULL; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c index f418e0b75772..519fcb234b3e 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c @@ -225,5 +225,5 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit)
etnaviv_core_dump_header(&iter, ETDUMP_BUF_END, iter.data);
- dev_coredumpv(gpu->dev, iter.start, iter.data - iter.start, GFP_KERNEL); + dev_coredumpv(gpu->dev, iter.start, iter.data - iter.start); } diff --git a/drivers/gpu/drm/msm/disp/msm_disp_snapshot.c b/drivers/gpu/drm/msm/disp/msm_disp_snapshot.c index e75b97127c0d..f057d294c30b 100644 --- a/drivers/gpu/drm/msm/disp/msm_disp_snapshot.c +++ b/drivers/gpu/drm/msm/disp/msm_disp_snapshot.c @@ -74,8 +74,8 @@ static void _msm_disp_snapshot_work(struct kthread_work *work) * If there is a codedump pending for the device, the dev_coredumpm() * will also free new coredump state. */ - dev_coredumpm(disp_state->dev, THIS_MODULE, disp_state, 0, GFP_KERNEL, - disp_devcoredump_read, msm_disp_state_free); + dev_coredumpm(disp_state->dev, THIS_MODULE, disp_state, 0, + disp_devcoredump_read, msm_disp_state_free); }
void msm_disp_snapshot_state(struct drm_device *drm_dev) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index c8cd9bfa3eeb..240ded1bddbf 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -299,8 +299,8 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, gpu->crashstate = state;
/* FIXME: Release the crashstate if this errors out? */ - dev_coredumpm(gpu->dev->dev, THIS_MODULE, gpu, 0, GFP_KERNEL, - msm_gpu_devcoredump_read, msm_gpu_devcoredump_free); + dev_coredumpm(gpu->dev->dev, THIS_MODULE, gpu, 0, + msm_gpu_devcoredump_read, msm_gpu_devcoredump_free); } #else static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 877eca125803..db84dfb3fb11 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -49,7 +49,7 @@ static void venus_coredump(struct venus_core *core)
memcpy(data, mem_va, mem_size); memunmap(mem_va); - dev_coredumpv(dev, data, mem_size, GFP_KERNEL); + dev_coredumpv(dev, data, mem_size); }
static void venus_event_notify(struct venus_core *core, u32 event) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c index c991b30bc9f0..fa520ab7c960 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c @@ -281,5 +281,5 @@ void mcp251xfd_dump(const struct mcp251xfd_priv *priv) mcp251xfd_dump_end(priv, &iter);
dev_coredumpv(&priv->spi->dev, iter.start, - iter.data - iter.start, GFP_KERNEL); + iter.data - iter.start); } diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c index fe6b6f97a916..dc9237069921 100644 --- a/drivers/net/wireless/ath/ath10k/coredump.c +++ b/drivers/net/wireless/ath/ath10k/coredump.c @@ -1607,7 +1607,7 @@ int ath10k_coredump_submit(struct ath10k *ar) return -ENODATA; }
- dev_coredumpv(ar->dev, dump, le32_to_cpu(dump->len), GFP_KERNEL); + dev_coredumpv(ar->dev, dump, le32_to_cpu(dump->len));
return 0; } diff --git a/drivers/net/wireless/ath/wil6210/wil_crash_dump.c b/drivers/net/wireless/ath/wil6210/wil_crash_dump.c index 89c12cb2aaab..79299609dd62 100644 --- a/drivers/net/wireless/ath/wil6210/wil_crash_dump.c +++ b/drivers/net/wireless/ath/wil6210/wil_crash_dump.c @@ -117,6 +117,6 @@ void wil_fw_core_dump(struct wil6210_priv *wil) /* fw_dump_data will be free in device coredump release function * after 5 min */ - dev_coredumpv(wil_to_dev(wil), fw_dump_data, fw_dump_size, GFP_KERNEL); + dev_coredumpv(wil_to_dev(wil), fw_dump_data, fw_dump_size); wil_info(wil, "fw core dumped, size %d bytes\n", fw_dump_size); } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c index eecf8a38d94a..87f3652ef3bd 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c @@ -37,7 +37,7 @@ int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, return err; }
- dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL); + dev_coredumpv(bus->dev, dump, len + ramsize);
return 0; } diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index abf49022edbe..f2f7cf494a8c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2601,8 +2601,7 @@ static void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt, fw_error_dump.trans_ptr->data, fw_error_dump.trans_ptr->len, fw_error_dump.fwrt_len); - dev_coredumpsg(fwrt->trans->dev, sg_dump_data, file_len, - GFP_KERNEL); + dev_coredumpsg(fwrt->trans->dev, sg_dump_data, file_len); } vfree(fw_error_dump.fwrt_ptr); vfree(fw_error_dump.trans_ptr); @@ -2647,8 +2646,7 @@ static void iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt, entry->data, entry->size, offs); offs += entry->size; } - dev_coredumpsg(fwrt->trans->dev, sg_dump_data, file_len, - GFP_KERNEL); + dev_coredumpsg(fwrt->trans->dev, sg_dump_data, file_len); } iwl_dump_ini_list_free(&dump_list); } diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index ace7371c4773..26fef0ab1b0d 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -1115,8 +1115,7 @@ void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter) */ mwifiex_dbg(adapter, MSG, "== mwifiex dump information to /sys/class/devcoredump start\n"); - dev_coredumpv(adapter->dev, adapter->devdump_data, adapter->devdump_len, - GFP_KERNEL); + dev_coredumpv(adapter->dev, adapter->devdump_data, adapter->devdump_len); mwifiex_dbg(adapter, MSG, "== mwifiex dump information to /sys/class/devcoredump end\n");
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index 9e832b27170f..1ea11c767900 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -2422,6 +2422,5 @@ void mt7615_coredump_work(struct work_struct *work)
dev_kfree_skb(skb); } - dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ, - GFP_KERNEL); + dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index 2a2ea7b9977a..893847564ec9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -1419,8 +1419,7 @@ void mt7921_coredump_work(struct work_struct *work) }
if (dump) - dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ, - GFP_KERNEL); + dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ);
mt7921_reset(&dev->mt76); } diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 645ef1d01895..85c86ee37621 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -414,7 +414,7 @@ static void rtw_fwcd_dump(struct rtw_dev *rtwdev) * framework. Note that a new dump will be discarded if a previous one * hasn't been released yet. */ - dev_coredumpv(rtwdev->dev, desc->data, desc->size, GFP_KERNEL); + dev_coredumpv(rtwdev->dev, desc->data, desc->size); }
static void rtw_fwcd_free(struct rtw_dev *rtwdev, bool free_self) diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 9e95ed972710..d28fe01ad729 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -127,7 +127,7 @@ static void rtw89_ser_cd_send(struct rtw89_dev *rtwdev, * will be discarded if a previous one hasn't been released by * framework yet. */ - dev_coredumpv(rtwdev->dev, buf, sizeof(*buf), GFP_KERNEL); + dev_coredumpv(rtwdev->dev, buf, sizeof(*buf)); }
static void rtw89_ser_cd_free(struct rtw89_dev *rtwdev, diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index af217de75e4d..813d87faef6c 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -597,7 +597,7 @@ static void q6v5_dump_mba_logs(struct q6v5 *qproc) data = vmalloc(MBA_LOG_SIZE); if (data) { memcpy(data, mba_region, MBA_LOG_SIZE); - dev_coredumpv(&rproc->dev, data, MBA_LOG_SIZE, GFP_KERNEL); + dev_coredumpv(&rproc->dev, data, MBA_LOG_SIZE); } memunmap(mba_region); } diff --git a/drivers/remoteproc/remoteproc_coredump.c b/drivers/remoteproc/remoteproc_coredump.c index 4b093420d98a..cd55c2abd227 100644 --- a/drivers/remoteproc/remoteproc_coredump.c +++ b/drivers/remoteproc/remoteproc_coredump.c @@ -309,7 +309,7 @@ void rproc_coredump(struct rproc *rproc) phdr += elf_size_of_phdr(class); } if (dump_conf == RPROC_COREDUMP_ENABLED) { - dev_coredumpv(&rproc->dev, data, data_size, GFP_KERNEL); + dev_coredumpv(&rproc->dev, data, data_size); return; }
@@ -318,7 +318,7 @@ void rproc_coredump(struct rproc *rproc) dump_state.header = data; init_completion(&dump_state.dump_done);
- dev_coredumpm(&rproc->dev, NULL, &dump_state, data_size, GFP_KERNEL, + dev_coredumpm(&rproc->dev, NULL, &dump_state, data_size, rproc_coredump_read, rproc_coredump_free);
/* @@ -449,7 +449,7 @@ void rproc_coredump_using_sections(struct rproc *rproc) }
if (dump_conf == RPROC_COREDUMP_ENABLED) { - dev_coredumpv(&rproc->dev, data, data_size, GFP_KERNEL); + dev_coredumpv(&rproc->dev, data, data_size); return; }
@@ -458,7 +458,7 @@ void rproc_coredump_using_sections(struct rproc *rproc) dump_state.header = data; init_completion(&dump_state.dump_done);
- dev_coredumpm(&rproc->dev, NULL, &dump_state, data_size, GFP_KERNEL, + dev_coredumpm(&rproc->dev, NULL, &dump_state, data_size, rproc_coredump_read, rproc_coredump_free);
/* Wait until the dump is read and free is called. Data is freed diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 22fabdeed297..b41850366bcc 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -162,7 +162,7 @@ struct drm_print_iterator { * void makecoredump(...) * { * ... - * dev_coredumpm(dev, THIS_MODULE, data, 0, GFP_KERNEL, + * dev_coredumpm(dev, THIS_MODULE, data, 0, * coredump_read, ...) * } * diff --git a/include/linux/devcoredump.h b/include/linux/devcoredump.h index c008169ed2c6..c7d840d824c3 100644 --- a/include/linux/devcoredump.h +++ b/include/linux/devcoredump.h @@ -52,27 +52,26 @@ static inline void _devcd_free_sgtable(struct scatterlist *table)
#ifdef CONFIG_DEV_COREDUMP -void dev_coredumpv(struct device *dev, void *data, size_t datalen, - gfp_t gfp); +void dev_coredumpv(struct device *dev, void *data, size_t datalen);
void dev_coredumpm(struct device *dev, struct module *owner, - void *data, size_t datalen, gfp_t gfp, + void *data, size_t datalen, ssize_t (*read)(char *buffer, loff_t offset, size_t count, void *data, size_t datalen), void (*free)(void *data));
void dev_coredumpsg(struct device *dev, struct scatterlist *table, - size_t datalen, gfp_t gfp); + size_t datalen); #else static inline void dev_coredumpv(struct device *dev, void *data, - size_t datalen, gfp_t gfp) + size_t datalen) { vfree(data); }
static inline void dev_coredumpm(struct device *dev, struct module *owner, - void *data, size_t datalen, gfp_t gfp, + void *data, size_t datalen, ssize_t (*read)(char *buffer, loff_t offset, size_t count, void *data, size_t datalen), void (*free)(void *data)) @@ -81,7 +80,7 @@ dev_coredumpm(struct device *dev, struct module *owner, }
static inline void dev_coredumpsg(struct device *dev, struct scatterlist *table, - size_t datalen, gfp_t gfp) + size_t datalen) { _devcd_free_sgtable(table); } diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c index b8e2b23c9f64..1ff57f1a483d 100644 --- a/sound/soc/intel/avs/apl.c +++ b/sound/soc/intel/avs/apl.c @@ -164,7 +164,7 @@ static int apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) } while (offset < msg->ext.coredump.stack_dump_size);
exit: - dev_coredumpv(adev->dev, dump, dump_size, GFP_KERNEL); + dev_coredumpv(adev->dev, dump, dump_size);
return 0; } diff --git a/sound/soc/intel/avs/skl.c b/sound/soc/intel/avs/skl.c index bda5ec7510fe..3413162768dc 100644 --- a/sound/soc/intel/avs/skl.c +++ b/sound/soc/intel/avs/skl.c @@ -88,7 +88,7 @@ static int skl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) return -ENOMEM;
memcpy_fromio(dump, avs_sram_addr(adev, AVS_FW_REGS_WINDOW), AVS_FW_REGS_SIZE); - dev_coredumpv(adev->dev, dump, AVS_FW_REGS_SIZE, GFP_KERNEL); + dev_coredumpv(adev->dev, dump, AVS_FW_REGS_SIZE);
return 0; } diff --git a/sound/soc/intel/catpt/dsp.c b/sound/soc/intel/catpt/dsp.c index 346bec000306..d2afe9ff1e3a 100644 --- a/sound/soc/intel/catpt/dsp.c +++ b/sound/soc/intel/catpt/dsp.c @@ -539,7 +539,7 @@ int catpt_coredump(struct catpt_dev *cdev) pos += CATPT_DMA_REGS_SIZE; }
- dev_coredumpv(cdev->dev, dump, dump_size, GFP_KERNEL); + dev_coredumpv(cdev->dev, dump, dump_size);
return 0; }
From: Duoming Zhou duoming@zju.edu.cn
[ Upstream commit a52ed4866d2b90dd5e4ae9dabd453f3ed8fa3cbc ]
There are sleep in atomic context bugs when uploading device dump data in mwifiex. The root cause is that dev_coredumpv could not be used in atomic contexts, because it calls dev_set_name which include operations that may sleep. The call tree shows execution paths that could lead to bugs:
(Interrupt context) fw_dump_timer_fn mwifiex_upload_device_dump dev_coredumpv(..., GFP_KERNEL) dev_coredumpm() kzalloc(sizeof(*devcd), gfp); //may sleep dev_set_name kobject_set_name_vargs kvasprintf_const(GFP_KERNEL, ...); //may sleep kstrdup(s, GFP_KERNEL); //may sleep
The corresponding fail log is shown below:
[ 135.275938] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start [ 135.281029] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:265 ... [ 135.293613] Call Trace: [ 135.293613] <IRQ> [ 135.293613] dump_stack_lvl+0x57/0x7d [ 135.293613] __might_resched.cold+0x138/0x173 [ 135.293613] ? dev_coredumpm+0xca/0x2e0 [ 135.293613] kmem_cache_alloc_trace+0x189/0x1f0 [ 135.293613] ? devcd_match_failing+0x30/0x30 [ 135.293613] dev_coredumpm+0xca/0x2e0 [ 135.293613] ? devcd_freev+0x10/0x10 [ 135.293613] dev_coredumpv+0x1c/0x20 [ 135.293613] ? devcd_match_failing+0x30/0x30 [ 135.293613] mwifiex_upload_device_dump+0x65/0xb0 [ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0 [ 135.293613] call_timer_fn+0x122/0x3d0 [ 135.293613] ? msleep_interruptible+0xb0/0xb0 [ 135.293613] ? lock_downgrade+0x3c0/0x3c0 [ 135.293613] ? __next_timer_interrupt+0x13c/0x160 [ 135.293613] ? lockdep_hardirqs_on_prepare+0xe/0x220 [ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0 [ 135.293613] __run_timers.part.0+0x3f8/0x540 [ 135.293613] ? call_timer_fn+0x3d0/0x3d0 [ 135.293613] ? arch_restore_msi_irqs+0x10/0x10 [ 135.293613] ? lapic_next_event+0x31/0x40 [ 135.293613] run_timer_softirq+0x4f/0xb0 [ 135.293613] __do_softirq+0x1c2/0x651 ... [ 135.293613] RIP: 0010:default_idle+0xb/0x10 [ 135.293613] RSP: 0018:ffff888006317e68 EFLAGS: 00000246 [ 135.293613] RAX: ffffffff82ad8d10 RBX: ffff888006301cc0 RCX: ffffffff82ac90e1 [ 135.293613] RDX: ffffed100d9ff1b4 RSI: ffffffff831ad140 RDI: ffffffff82ad8f20 [ 135.293613] RBP: 0000000000000003 R08: 0000000000000000 R09: ffff88806cff8d9b [ 135.293613] R10: ffffed100d9ff1b3 R11: 0000000000000001 R12: ffffffff84593410 [ 135.293613] R13: 0000000000000000 R14: 0000000000000000 R15: 1ffff11000c62fd2 ... [ 135.389205] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end
This patch uses delayed work to replace timer and moves the operations that may sleep into a delayed work in order to mitigate bugs, it was tested on Marvell 88W8801 chip whose port is usb and the firmware is usb8801_uapsta.bin. The following is the result after using delayed work to replace timer.
[ 134.936453] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start [ 135.043344] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end
As we can see, there is no bug now.
Fixes: f5ecd02a8b20 ("mwifiex: device dump support for usb interface") Reviewed-by: Brian Norris briannorris@chromium.org Signed-off-by: Duoming Zhou duoming@zju.edu.cn Link: https://lore.kernel.org/r/b63b77fc84ed3e8a6bef02378e17c7c71a0bc3be.165456929... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/init.c | 9 +++++---- drivers/net/wireless/marvell/mwifiex/main.h | 3 ++- drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c index 88c72d1827a0..fca3ab948f6c 100644 --- a/drivers/net/wireless/marvell/mwifiex/init.c +++ b/drivers/net/wireless/marvell/mwifiex/init.c @@ -63,9 +63,10 @@ static void wakeup_timer_fn(struct timer_list *t) adapter->if_ops.card_reset(adapter); }
-static void fw_dump_timer_fn(struct timer_list *t) +static void fw_dump_work(struct work_struct *work) { - struct mwifiex_adapter *adapter = from_timer(adapter, t, devdump_timer); + struct mwifiex_adapter *adapter = + container_of(work, struct mwifiex_adapter, devdump_work.work);
mwifiex_upload_device_dump(adapter); } @@ -321,7 +322,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->active_scan_triggered = false; timer_setup(&adapter->wakeup_timer, wakeup_timer_fn, 0); adapter->devdump_len = 0; - timer_setup(&adapter->devdump_timer, fw_dump_timer_fn, 0); + INIT_DELAYED_WORK(&adapter->devdump_work, fw_dump_work); }
/* @@ -400,7 +401,7 @@ static void mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) { del_timer(&adapter->wakeup_timer); - del_timer_sync(&adapter->devdump_timer); + cancel_delayed_work_sync(&adapter->devdump_work); mwifiex_cancel_all_pending_cmd(adapter); wake_up_interruptible(&adapter->cmd_wait_q.wait); wake_up_interruptible(&adapter->hs_activate_wait_q); diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 332dd1c8db35..5d8646f16162 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -49,6 +49,7 @@ #include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/of_irq.h> +#include <linux/workqueue.h>
#include "decl.h" #include "ioctl.h" @@ -1055,7 +1056,7 @@ struct mwifiex_adapter { /* Device dump data/length */ void *devdump_data; int devdump_len; - struct timer_list devdump_timer; + struct delayed_work devdump_work;
bool ignore_btcoex_events; }; diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c index 7d42c5d2dbf6..4d93386494c5 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_event.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c @@ -623,8 +623,8 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv, * transmission event get lost, in this cornel case, * user would still get partial of the dump. */ - mod_timer(&adapter->devdump_timer, - jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); + schedule_delayed_work(&adapter->devdump_work, + msecs_to_jiffies(MWIFIEX_TIMER_10S)); }
/* Overflow check */ @@ -643,7 +643,7 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv, return;
upload_dump: - del_timer_sync(&adapter->devdump_timer); + cancel_delayed_work_sync(&adapter->devdump_work); mwifiex_upload_device_dump(adapter); }
From: Mike Christie michael.christie@oracle.com
[ Upstream commit 3328333b47f4163504267440ec0a36087a407a5f ]
iscsi_if_stop_conn() is only called from the userspace interface but in a subsequent commit we will want to call it from the kernel interface to allow drivers like qedi to remove sessions from inside the kernel during shutdown. This removes the iscsi_uevent code from iscsi_if_stop_conn() so we can call it in a new helper.
Link: https://lore.kernel.org/r/20220616222738.5722-3-michael.christie@oracle.com Tested-by: Nilesh Javali njavali@marvell.com Reviewed-by: Nilesh Javali njavali@marvell.com Signed-off-by: Mike Christie michael.christie@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/scsi_transport_iscsi.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 5d21f07456c6..a410d0b8a445 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -2264,16 +2264,8 @@ static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn, } }
-static int iscsi_if_stop_conn(struct iscsi_transport *transport, - struct iscsi_uevent *ev) +static int iscsi_if_stop_conn(struct iscsi_cls_conn *conn, int flag) { - int flag = ev->u.stop_conn.flag; - struct iscsi_cls_conn *conn; - - conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid); - if (!conn) - return -EINVAL; - ISCSI_DBG_TRANS_CONN(conn, "iscsi if conn stop.\n"); /* * If this is a termination we have to call stop_conn with that flag @@ -3720,7 +3712,12 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport, case ISCSI_UEVENT_DESTROY_CONN: return iscsi_if_destroy_conn(transport, ev); case ISCSI_UEVENT_STOP_CONN: - return iscsi_if_stop_conn(transport, ev); + conn = iscsi_conn_lookup(ev->u.stop_conn.sid, + ev->u.stop_conn.cid); + if (!conn) + return -EINVAL; + + return iscsi_if_stop_conn(conn, ev->u.stop_conn.flag); }
/*
From: Mike Christie michael.christie@oracle.com
[ Upstream commit bb42856bfd54fda1cbc7c470fcf5db1596938f4f ]
During qedi shutdown we need to stop the iSCSI layer from sending new nops as pings and from responding to target ones and make sure there is no running connection cleanups. Commit d1f2ce77638d ("scsi: qedi: Fix host removal with running sessions") converted the driver to use the libicsi helper to drive session removal, so the above issues could be handled. The problem is that during system shutdown iscsid will not be running so when we try to remove the root session we will hang waiting for userspace to reply.
Add a helper that will drive the destruction of sessions like these during system shutdown.
Link: https://lore.kernel.org/r/20220616222738.5722-5-michael.christie@oracle.com Tested-by: Nilesh Javali njavali@marvell.com Reviewed-by: Nilesh Javali njavali@marvell.com Signed-off-by: Mike Christie michael.christie@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/scsi_transport_iscsi.c | 49 +++++++++++++++++++++++++++++ include/scsi/scsi_transport_iscsi.h | 1 + 2 files changed, 50 insertions(+)
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index a410d0b8a445..2a38cd2d24ef 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -2341,6 +2341,55 @@ static void iscsi_cleanup_conn_work_fn(struct work_struct *work) ISCSI_DBG_TRANS_CONN(conn, "cleanup done.\n"); }
+static int iscsi_iter_force_destroy_conn_fn(struct device *dev, void *data) +{ + struct iscsi_transport *transport; + struct iscsi_cls_conn *conn; + + if (!iscsi_is_conn_dev(dev)) + return 0; + + conn = iscsi_dev_to_conn(dev); + transport = conn->transport; + + if (READ_ONCE(conn->state) != ISCSI_CONN_DOWN) + iscsi_if_stop_conn(conn, STOP_CONN_TERM); + + transport->destroy_conn(conn); + return 0; +} + +/** + * iscsi_force_destroy_session - destroy a session from the kernel + * @session: session to destroy + * + * Force the destruction of a session from the kernel. This should only be + * used when userspace is no longer running during system shutdown. + */ +void iscsi_force_destroy_session(struct iscsi_cls_session *session) +{ + struct iscsi_transport *transport = session->transport; + unsigned long flags; + + WARN_ON_ONCE(system_state == SYSTEM_RUNNING); + + spin_lock_irqsave(&sesslock, flags); + if (list_empty(&session->sess_list)) { + spin_unlock_irqrestore(&sesslock, flags); + /* + * Conn/ep is already freed. Session is being torn down via + * async path. For shutdown we don't care about it so return. + */ + return; + } + spin_unlock_irqrestore(&sesslock, flags); + + device_for_each_child(&session->dev, NULL, + iscsi_iter_force_destroy_conn_fn); + transport->destroy_session(session); +} +EXPORT_SYMBOL_GPL(iscsi_force_destroy_session); + void iscsi_free_session(struct iscsi_cls_session *session) { ISCSI_DBG_TRANS_SESSION(session, "Freeing session\n"); diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 9acb8422f680..d6eab7cb221a 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -442,6 +442,7 @@ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *t, int dd_size, unsigned int target_id); +extern void iscsi_force_destroy_session(struct iscsi_cls_session *session); extern void iscsi_remove_session(struct iscsi_cls_session *session); extern void iscsi_free_session(struct iscsi_cls_session *session); extern struct iscsi_cls_conn *iscsi_alloc_conn(struct iscsi_cls_session *sess,
From: Mike Christie michael.christie@oracle.com
[ Upstream commit 31500e902759322ba3c64b60dabae2704e738df8 ]
When the system is shutting down, iscsid is not running so we will not get a response to the ISCSI_ERR_INVALID_HOST error event. The system shutdown will then hang waiting on userspace to remove the session.
This has libiscsi force the destruction of the session from the kernel when iscsi_host_remove() is called from a driver's shutdown callout.
This fixes a regression added in qedi boot with commit d1f2ce77638d ("scsi: qedi: Fix host removal with running sessions") which made qedi use the common session removal function that waits on userspace instead of rolling its own kernel based removal.
Link: https://lore.kernel.org/r/20220616222738.5722-7-michael.christie@oracle.com Fixes: d1f2ce77638d ("scsi: qedi: Fix host removal with running sessions") Tested-by: Nilesh Javali njavali@marvell.com Reviewed-by: Lee Duncan lduncan@suse.com Reviewed-by: Nilesh Javali njavali@marvell.com Signed-off-by: Mike Christie michael.christie@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/iser/iscsi_iser.c | 4 ++-- drivers/scsi/be2iscsi/be_main.c | 2 +- drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +- drivers/scsi/cxgbi/libcxgbi.c | 2 +- drivers/scsi/iscsi_tcp.c | 4 ++-- drivers/scsi/libiscsi.c | 9 +++++++-- drivers/scsi/qedi/qedi_main.c | 9 ++++++--- include/scsi/libiscsi.h | 2 +- 8 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 321949a570ed..620ae5b2d80d 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -568,7 +568,7 @@ static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session) struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
iscsi_session_teardown(cls_session); - iscsi_host_remove(shost); + iscsi_host_remove(shost, false); iscsi_host_free(shost); }
@@ -685,7 +685,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep, return cls_session;
remove_host: - iscsi_host_remove(shost); + iscsi_host_remove(shost, false); free_host: iscsi_host_free(shost); return NULL; diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 3bb0adefbe06..02026476c39c 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -5745,7 +5745,7 @@ static void beiscsi_remove(struct pci_dev *pcidev) cancel_work_sync(&phba->sess_work);
beiscsi_iface_destroy_default(phba); - iscsi_host_remove(phba->shost); + iscsi_host_remove(phba->shost, false); beiscsi_disable_port(phba, 1);
/* after cancelling boot_work */ diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 15fbd09baa94..a3c800e04a2e 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -909,7 +909,7 @@ void bnx2i_free_hba(struct bnx2i_hba *hba) { struct Scsi_Host *shost = hba->shost;
- iscsi_host_remove(shost); + iscsi_host_remove(shost, false); INIT_LIST_HEAD(&hba->ep_ofld_list); INIT_LIST_HEAD(&hba->ep_active_list); INIT_LIST_HEAD(&hba->ep_destroy_list); diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index 4365d52c6430..32abdf0fa9aa 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -328,7 +328,7 @@ void cxgbi_hbas_remove(struct cxgbi_device *cdev) chba = cdev->hbas[i]; if (chba) { cdev->hbas[i] = NULL; - iscsi_host_remove(chba->shost); + iscsi_host_remove(chba->shost, false); pci_dev_put(cdev->pdev); iscsi_host_free(chba->shost); } diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 9fee70d6434a..52c6f70d60ec 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -898,7 +898,7 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, remove_session: iscsi_session_teardown(cls_session); remove_host: - iscsi_host_remove(shost); + iscsi_host_remove(shost, false); free_host: iscsi_host_free(shost); return NULL; @@ -915,7 +915,7 @@ static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session) iscsi_tcp_r2tpool_free(cls_session->dd_data); iscsi_session_teardown(cls_session);
- iscsi_host_remove(shost); + iscsi_host_remove(shost, false); iscsi_host_free(shost); }
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 797abf4f5399..3ddb701cd29c 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2828,11 +2828,12 @@ static void iscsi_notify_host_removed(struct iscsi_cls_session *cls_session) /** * iscsi_host_remove - remove host and sessions * @shost: scsi host + * @is_shutdown: true if called from a driver shutdown callout * * If there are any sessions left, this will initiate the removal and wait * for the completion. */ -void iscsi_host_remove(struct Scsi_Host *shost) +void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown) { struct iscsi_host *ihost = shost_priv(shost); unsigned long flags; @@ -2841,7 +2842,11 @@ void iscsi_host_remove(struct Scsi_Host *shost) ihost->state = ISCSI_HOST_REMOVED; spin_unlock_irqrestore(&ihost->lock, flags);
- iscsi_host_for_each_session(shost, iscsi_notify_host_removed); + if (!is_shutdown) + iscsi_host_for_each_session(shost, iscsi_notify_host_removed); + else + iscsi_host_for_each_session(shost, iscsi_force_destroy_session); + wait_event_interruptible(ihost->session_removal_wq, ihost->num_sessions == 0); if (signal_pending(current)) diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index 83ffba7f51da..780d975c85b5 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -2414,9 +2414,12 @@ static void __qedi_remove(struct pci_dev *pdev, int mode) int rval; u16 retry = 10;
- if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) { - iscsi_host_remove(qedi->shost); + if (mode == QEDI_MODE_NORMAL) + iscsi_host_remove(qedi->shost, false); + else if (mode == QEDI_MODE_SHUTDOWN) + iscsi_host_remove(qedi->shost, true);
+ if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) { if (qedi->tmf_thread) { destroy_workqueue(qedi->tmf_thread); qedi->tmf_thread = NULL; @@ -2791,7 +2794,7 @@ static int __qedi_probe(struct pci_dev *pdev, int mode) #ifdef CONFIG_DEBUG_FS qedi_dbg_host_exit(&qedi->dbg_ctx); #endif - iscsi_host_remove(qedi->shost); + iscsi_host_remove(qedi->shost, false); stop_iscsi_func: qedi_ops->stop(qedi->cdev); stop_slowpath: diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index c0703cd20a99..9758a4a9923f 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -411,7 +411,7 @@ extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev); extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, int dd_data_size, bool xmit_can_sleep); -extern void iscsi_host_remove(struct Scsi_Host *shost); +extern void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown); extern void iscsi_host_free(struct Scsi_Host *shost); extern int iscsi_target_alloc(struct scsi_target *starget); extern int iscsi_host_get_max_scsi_cmds(struct Scsi_Host *shost,
From: Serge Semin Sergey.Semin@baikalelectronics.ru
[ Upstream commit c1e33979171da63cf47e56243ccb8ba82363c7d3 ]
In accordance with [1, 2] the DW eDMA controller has been created to be part of the DW PCIe Root Port and DW PCIe End-point controllers and to offload the transferring of large blocks of data between application and remote PCIe domains leaving the system CPU free for other tasks. In the first case (eDMA being part of DW PCIe Root Port) the eDMA controller is always accessible via the CPU DBI interface and never over the PCIe wire.
The latter case is more complex. Depending on the DW PCIe End-Point IP-core synthesize parameters it's possible to have the eDMA registers accessible not only from the application CPU side, but also via mapping the eDMA CSRs over a dedicated endpoint BAR. So based on the specifics denoted above the eDMA driver is supposed to support two types of the DMA controller setups:
1) eDMA embedded into the DW PCIe Root Port/End-point and accessible over the local CPU from the application side.
2) eDMA embedded into the DW PCIe End-point and accessible via the PCIe wire with MWr/MRd TLPs generated by the CPU PCIe host controller.
Since the CPU memory resides different sides in these cases the semantics of the MEM_TO_DEV and DEV_TO_MEM operations is flipped with respect to the Tx and Rx DMA channels. So MEM_TO_DEV/DEV_TO_MEM corresponds to the Tx/Rx channels in setup 1) and to the Rx/Tx channels in case of setup 2).
The DW eDMA driver has supported the case 2) since e63d79d1ffcd ("dmaengine: Add Synopsys eDMA IP core driver") in the framework of the drivers/dma/dw-edma/dw-edma-pcie.c driver.
The case 1) support was added later by bd96f1b2f43a ("dmaengine: dw-edma: support local dma device transfer semantics"). Afterwards the driver was supposed to cover the both possible eDMA setups, but the latter commit turned out to be not fully correct.
The problem was that the commit together with the new functionality support also changed the channel direction semantics so the eDMA Read-channel (corresponding to the DMA_DEV_TO_MEM direction for case 1) now uses the sgl/cyclic base addresses as the Source addresses of the DMA transfers and dma_slave_config.dst_addr as the Destination address of the DMA transfers.
Similarly the eDMA Write-channel (corresponding to the DMA_MEM_TO_DEV direction for case 1) now uses dma_slave_config.src_addr as a source address of the DMA transfers and sgl/cyclic base address as the Destination address of the DMA transfers. This contradicts the logic of the DMA-interface, which implies that DEV side is supposed to belong to the PCIe device memory and MEM - to the CPU/Application memory. Indeed it seems irrational to have the SG-list defined in the PCIe bus space, while expecting a contiguous buffer allocated in the CPU memory. Moreover the passed SG-list and cyclic DMA buffers are supposed to be mapped in a way so to be seen by the DW eDMA Application (CPU) interface.
So in order to have the correct DW eDMA interface we need to invert the eDMA Rd/Wr-channels and DMA-slave directions semantics by selecting the src/dst addresses based on the DMA transfer direction instead of using the channel direction capability.
[1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, v.5.40a, March 2019, p.1092 [2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Endpoint, v.5.40a, March 2019, p.1189
Co-developed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Fixes: bd96f1b2f43a ("dmaengine: dw-edma: support local dma device transfer semantics") Link: https://lore.kernel.org/r/20220524152159.2370739-7-Frank.Li@nxp.com Tested-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Serge Semin Sergey.Semin@baikalelectronics.ru Signed-off-by: Frank Li Frank.Li@nxp.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Acked-By: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/dw-edma/dw-edma-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index 468d1097a1ec..f23569e4b0bd 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -423,7 +423,7 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer) chunk->ll_region.sz += burst->sz; desc->alloc_sz += burst->sz;
- if (chan->dir == EDMA_DIR_WRITE) { + if (dir == DMA_DEV_TO_MEM) { burst->sar = src_addr; if (xfer->type == EDMA_XFER_CYCLIC) { burst->dar = xfer->xfer.cyclic.paddr;
From: Ben Gardon bgardon@google.com
[ Upstream commit 1c4dc57328bf218e999951824dce75c6125c4f3c ]
The braces around the KVM_CAP_XSAVE2 block also surround the KVM_CAP_PMU_CAPABILITY block, likely the result of a merge issue. Simply move the curly brace back to where it belongs.
Fixes: ba7bb663f5547 ("KVM: x86: Provide per VM capability for disabling PMU virtualization")
Reviewed-by: David Matlack dmatlack@google.com Reviewed-by: Peter Xu peterx@redhat.com Signed-off-by: Ben Gardon bgardon@google.com Message-Id: 20220613212523.3436117-8-bgardon@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 583fe0dffcd8..3ed0e86bf305 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4398,10 +4398,10 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) if (r < sizeof(struct kvm_xsave)) r = sizeof(struct kvm_xsave); break; + } case KVM_CAP_PMU_CAPABILITY: r = enable_pmu ? KVM_CAP_PMU_VALID_MASK : 0; break; - } case KVM_CAP_DISABLE_QUIRKS2: r = KVM_X86_VALID_QUIRKS; break;
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit c223a38d62e57aa60a890ea7247e3c58a54478e6 ]
If rpcif_hw_init() fails, Runtime PM is left enabled.
Fixes: b04cc0d912eb80d3 ("memory: renesas-rpc-if: Add support for RZ/G2L") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Wolfram Sang wsa+renesas@sang-engineering.com Reviewed-by: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com Reviewed-by: Sergey Shtylyov s.shtylyov@omp.ru Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/f3070e1af480cb252ae183d479a593dbbf947685.1... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/hyperbus/rpc-if.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/hyperbus/rpc-if.c b/drivers/mtd/hyperbus/rpc-if.c index 6e08ec1d4f09..b70d259e48a7 100644 --- a/drivers/mtd/hyperbus/rpc-if.c +++ b/drivers/mtd/hyperbus/rpc-if.c @@ -134,7 +134,7 @@ static int rpcif_hb_probe(struct platform_device *pdev)
error = rpcif_hw_init(&hyperbus->rpc, true); if (error) - return error; + goto out_disable_rpm;
hyperbus->hbdev.map.size = hyperbus->rpc.size; hyperbus->hbdev.map.virt = hyperbus->rpc.dirmap; @@ -145,8 +145,12 @@ static int rpcif_hb_probe(struct platform_device *pdev) hyperbus->hbdev.np = of_get_next_child(pdev->dev.parent->of_node, NULL); error = hyperbus_register_device(&hyperbus->hbdev); if (error) - rpcif_disable_rpm(&hyperbus->rpc); + goto out_disable_rpm; + + return 0;
+out_disable_rpm: + rpcif_disable_rpm(&hyperbus->rpc); return error; }
From: Mark Brown broonie@kernel.org
[ Upstream commit ac4f83482afbfd927d0fe118151b747cf175e724 ]
Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding an id_table listing the SPI IDs for everything.
Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220620152313.708768-1-broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/devices/mtd_dataflash.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 134e27328597..25bad4318305 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -112,6 +112,13 @@ static const struct of_device_id dataflash_dt_ids[] = { MODULE_DEVICE_TABLE(of, dataflash_dt_ids); #endif
+static const struct spi_device_id dataflash_spi_ids[] = { + { .name = "at45", }, + { .name = "dataflash", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(spi, dataflash_spi_ids); + /* ......................................................................... */
/* @@ -936,6 +943,7 @@ static struct spi_driver dataflash_driver = {
.probe = dataflash_probe, .remove = dataflash_remove, + .id_table = dataflash_spi_ids,
/* FIXME: investigate suspend and resume... */ };
From: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org
[ Upstream commit c4f40351901a10cd662ac2c081396d8fb04f584d ]
Access to I/O of SM8250 camera clock controller IP depends on enabled GCC_CAMERA_AHB_CLK clock supplied by global clock controller, the latter one is inited on subsys level, so, to satisfy the dependency, it would make sense to deprive the init level of camcc-sm8250 driver.
If both drivers are compiled as built-in, there is a change that a board won't boot up due to a race, which happens on the same init level.
Fixes: 5d66ca79b58c ("clk: qcom: Add camera clock controller driver for SM8250") Signed-off-by: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org Reviewed-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Tested-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220518103554.949511-1-vladimir.zapolskiy@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/camcc-sm8250.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c index 439eaafdcc86..ae4e9774f36e 100644 --- a/drivers/clk/qcom/camcc-sm8250.c +++ b/drivers/clk/qcom/camcc-sm8250.c @@ -2440,17 +2440,7 @@ static struct platform_driver cam_cc_sm8250_driver = { }, };
-static int __init cam_cc_sm8250_init(void) -{ - return platform_driver_register(&cam_cc_sm8250_driver); -} -subsys_initcall(cam_cc_sm8250_init); - -static void __exit cam_cc_sm8250_exit(void) -{ - platform_driver_unregister(&cam_cc_sm8250_driver); -} -module_exit(cam_cc_sm8250_exit); +module_platform_driver(cam_cc_sm8250_driver);
MODULE_DESCRIPTION("QTI CAMCC SM8250 Driver"); MODULE_LICENSE("GPL v2");
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 44fd1917314e9d4f53dd95dd65df1c152f503d3a ]
If an error occurs after a successful idr_alloc() call, the corresponding resource must be released with idr_remove() as already done in the .remove function.
Update the error handling path to add the missing idr_remove() call.
Fixes: ada8a8a13b13 ("mfd: Add realtek pcie card reader driver") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/e8dc41716cbf52fb37a12e70d8972848e69df6d6.165527121... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/misc/cardreader/rtsx_pcr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c index 2a2619e3c72c..f001d99bf366 100644 --- a/drivers/misc/cardreader/rtsx_pcr.c +++ b/drivers/misc/cardreader/rtsx_pcr.c @@ -1507,7 +1507,7 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, pcr->remap_addr = ioremap(base, len); if (!pcr->remap_addr) { ret = -ENOMEM; - goto free_handle; + goto free_idr; }
pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev), @@ -1570,6 +1570,10 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr); unmap: iounmap(pcr->remap_addr); +free_idr: + spin_lock(&rtsx_pci_lock); + idr_remove(&rtsx_pci_idr, pcr->id); + spin_unlock(&rtsx_pci_lock); free_handle: kfree(handle); free_pcr:
From: Zhang Wensheng zhangwensheng5@huawei.com
[ Upstream commit 70fe758352cafdee72a7b13bf9db065f9613ced8 ]
In __driver_attach function, There are also AA deadlock problem, like the commit b232b02bf3c2 ("driver core: fix deadlock in __device_attach").
stack like commit b232b02bf3c2 ("driver core: fix deadlock in __device_attach"). list below: In __driver_attach function, The lock holding logic is as follows: ... __driver_attach if (driver_allows_async_probing(drv)) device_lock(dev) // get lock dev async_schedule_dev(__driver_attach_async_helper, dev); // func async_schedule_node async_schedule_node_domain(func) entry = kzalloc(sizeof(struct async_entry), GFP_ATOMIC); /* when fail or work limit, sync to execute func, but __driver_attach_async_helper will get lock dev as will, which will lead to A-A deadlock. */ if (!entry || atomic_read(&entry_count) > MAX_WORK) { func; else queue_work_node(node, system_unbound_wq, &entry->work) device_unlock(dev)
As above show, when it is allowed to do async probes, because of out of memory or work limit, async work is not be allowed, to do sync execute instead. it will lead to A-A deadlock because of __driver_attach_async_helper getting lock dev.
Reproduce: and it can be reproduce by make the condition (if (!entry || atomic_read(&entry_count) > MAX_WORK)) untenable, like below:
[ 370.785650] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 370.787154] task:swapper/0 state:D stack: 0 pid: 1 ppid: 0 flags:0x00004000 [ 370.788865] Call Trace: [ 370.789374] <TASK> [ 370.789841] __schedule+0x482/0x1050 [ 370.790613] schedule+0x92/0x1a0 [ 370.791290] schedule_preempt_disabled+0x2c/0x50 [ 370.792256] __mutex_lock.isra.0+0x757/0xec0 [ 370.793158] __mutex_lock_slowpath+0x1f/0x30 [ 370.794079] mutex_lock+0x50/0x60 [ 370.794795] __device_driver_lock+0x2f/0x70 [ 370.795677] ? driver_probe_device+0xd0/0xd0 [ 370.796576] __driver_attach_async_helper+0x1d/0xd0 [ 370.797318] ? driver_probe_device+0xd0/0xd0 [ 370.797957] async_schedule_node_domain+0xa5/0xc0 [ 370.798652] async_schedule_node+0x19/0x30 [ 370.799243] __driver_attach+0x246/0x290 [ 370.799828] ? driver_allows_async_probing+0xa0/0xa0 [ 370.800548] bus_for_each_dev+0x9d/0x130 [ 370.801132] driver_attach+0x22/0x30 [ 370.801666] bus_add_driver+0x290/0x340 [ 370.802246] driver_register+0x88/0x140 [ 370.802817] ? virtio_scsi_init+0x116/0x116 [ 370.803425] scsi_register_driver+0x1a/0x30 [ 370.804057] init_sd+0x184/0x226 [ 370.804533] do_one_initcall+0x71/0x3a0 [ 370.805107] kernel_init_freeable+0x39a/0x43a [ 370.805759] ? rest_init+0x150/0x150 [ 370.806283] kernel_init+0x26/0x230 [ 370.806799] ret_from_fork+0x1f/0x30
To fix the deadlock, move the async_schedule_dev outside device_lock, as we can see, in async_schedule_node_domain, the parameter of queue_work_node is system_unbound_wq, so it can accept concurrent operations. which will also not change the code logic, and will not lead to deadlock.
Fixes: ef0ff68351be ("driver core: Probe devices asynchronously instead of the driver") Signed-off-by: Zhang Wensheng zhangwensheng5@huawei.com Link: https://lore.kernel.org/r/20220622074327.497102-1-zhangwensheng5@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/dd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 11b0fb6414d3..b766968a873c 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -1115,6 +1115,7 @@ static void __driver_attach_async_helper(void *_dev, async_cookie_t cookie) static int __driver_attach(struct device *dev, void *data) { struct device_driver *drv = data; + bool async = false; int ret;
/* @@ -1153,9 +1154,11 @@ static int __driver_attach(struct device *dev, void *data) if (!dev->driver && !dev->p->async_driver) { get_device(dev); dev->p->async_driver = drv; - async_schedule_dev(__driver_attach_async_helper, dev); + async = true; } device_unlock(dev); + if (async) + async_schedule_dev(__driver_attach_async_helper, dev); return 0; }
From: Ansuel Smith ansuelsmth@gmail.com
[ Upstream commit df83d2c9e72910416f650ade1e07cc314ff02731 ]
Unlock spinlock after the mux switch is completed to prevent any corner case of mux request while the switch still needs to be done.
Fixes: 4d7dc77babfe ("clk: qcom: Add support for Krait clocks") Signed-off-by: Ansuel Smith ansuelsmth@gmail.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220430054458.31321-3-ansuelsmth@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/clk-krait.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c index 59f1af415b58..90046428693c 100644 --- a/drivers/clk/qcom/clk-krait.c +++ b/drivers/clk/qcom/clk-krait.c @@ -32,11 +32,16 @@ static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel) regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT); } krait_set_l2_indirect_reg(mux->offset, regval); - spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
/* Wait for switch to complete. */ mb(); udelay(1); + + /* + * Unlock now to make sure the mux register is not + * modified while switching to the new parent. + */ + spin_unlock_irqrestore(&krait_clock_reg_lock, flags); }
static int krait_mux_set_parent(struct clk_hw *hw, u8 index)
From: Mike Leach mike.leach@linaro.org
[ Upstream commit 199380decc5f9188a9e65676031950f1734aaffe ]
Any loaded configurations must be correctly unloaded on coresight module exit, or issues can arise with nested locking in the configfs directory code if built with CONFIG_LOCKDEP.
Prior to this patch, the preloaded configuration configfs directory entries were being unloaded by the recursive code in configfs_unregister_subsystem().
However, when built with CONFIG_LOCKDEP, this caused a nested lock warning, which was not mitigated by the LOCKDEP dependent code in fs/configfs/dir.c designed to prevent this, due to the different directory levels for the root of the directory being removed.
As the preloaded (and all other) configurations are registered after configfs_register_subsystem(), we now explicitly unload them before the call to configfs_unregister_subsystem().
The new routine cscfg_unload_cfgs_on_exit() iterates through the load owner list to unload any remaining configurations that were not unloaded by the user before the module exits. This covers both the CSCFG_OWNER_PRELOAD and CSCFG_OWNER_MODULE owner types, and will be extended to cover future load owner types for CoreSight configurations.
Fixes: eb2ec49606c2 ("coresight: syscfg: Update load API for config loadable modules") Reported-by: Suzuki Poulose suzuki.poulose@arm.com Signed-off-by: Mike Leach mike.leach@linaro.org Reviewed-and-tested-by: Suzuki K Poulose suzuki.poulose@arm.com Link: https://lore.kernel.org/r/20220628173004.30002-2-mike.leach@linaro.org Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../hwtracing/coresight/coresight-syscfg.c | 104 ++++++++++++++++-- 1 file changed, 93 insertions(+), 11 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index 11850fd8c3b5..17e728ab5c99 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -414,6 +414,27 @@ static void cscfg_remove_owned_csdev_features(struct coresight_device *csdev, vo } }
+/* + * Unregister all configuration and features from configfs owned by load_owner. + * Although this is called without the list mutex being held, it is in the + * context of an unload operation which are strictly serialised, + * so the lists cannot change during this call. + */ +static void cscfg_fs_unregister_cfgs_feats(void *load_owner) +{ + struct cscfg_config_desc *config_desc; + struct cscfg_feature_desc *feat_desc; + + list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) { + if (config_desc->load_owner == load_owner) + cscfg_configfs_del_config(config_desc); + } + list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) { + if (feat_desc->load_owner == load_owner) + cscfg_configfs_del_feature(feat_desc); + } +} + /* * removal is relatively easy - just remove from all lists, anything that * matches the owner. Memory for the descriptors will be managed by the owner, @@ -1022,8 +1043,10 @@ struct device *cscfg_device(void) /* Must have a release function or the kernel will complain on module unload */ static void cscfg_dev_release(struct device *dev) { + mutex_lock(&cscfg_mutex); kfree(cscfg_mgr); cscfg_mgr = NULL; + mutex_unlock(&cscfg_mutex); }
/* a device is needed to "own" some kernel elements such as sysfs entries. */ @@ -1042,6 +1065,13 @@ static int cscfg_create_device(void) if (!cscfg_mgr) goto create_dev_exit_unlock;
+ /* initialise the cscfg_mgr structure */ + INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list); + INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list); + INIT_LIST_HEAD(&cscfg_mgr->config_desc_list); + INIT_LIST_HEAD(&cscfg_mgr->load_order_list); + atomic_set(&cscfg_mgr->sys_active_cnt, 0); + /* setup the device */ dev = cscfg_device(); dev->release = cscfg_dev_release; @@ -1056,17 +1086,73 @@ static int cscfg_create_device(void) return err; }
-static void cscfg_clear_device(void) +/* + * Loading and unloading is generally on user discretion. + * If exiting due to coresight module unload, we need to unload any configurations that remain, + * before we unregister the configfs intrastructure. + * + * Do this by walking the load_owner list and taking appropriate action, depending on the load + * owner type. + */ +static void cscfg_unload_cfgs_on_exit(void) { - struct cscfg_config_desc *cfg_desc; + struct cscfg_load_owner_info *owner_info = NULL;
+ /* + * grab the mutex - even though we are exiting, some configfs files + * may still be live till we dump them, so ensure list data is + * protected from a race condition. + */ mutex_lock(&cscfg_mutex); - list_for_each_entry(cfg_desc, &cscfg_mgr->config_desc_list, item) { - etm_perf_del_symlink_cscfg(cfg_desc); + while (!list_empty(&cscfg_mgr->load_order_list)) { + + /* remove in reverse order of loading */ + owner_info = list_last_entry(&cscfg_mgr->load_order_list, + struct cscfg_load_owner_info, item); + + /* action according to type */ + switch (owner_info->type) { + case CSCFG_OWNER_PRELOAD: + /* + * preloaded descriptors are statically allocated in + * this module - just need to unload dynamic items from + * csdev lists, and remove from configfs directories. + */ + pr_info("cscfg: unloading preloaded configurations\n"); + break; + + case CSCFG_OWNER_MODULE: + /* + * this is an error - the loadable module must have been unloaded prior + * to the coresight module unload. Therefore that module has not + * correctly unloaded configs in its own exit code. + * Nothing to do other than emit an error string as the static descriptor + * references we need to unload will have disappeared with the module. + */ + pr_err("cscfg: ERROR: prior module failed to unload configuration\n"); + goto list_remove; + } + + /* remove from configfs - outside the scope of the list mutex */ + mutex_unlock(&cscfg_mutex); + cscfg_fs_unregister_cfgs_feats(owner_info); + mutex_lock(&cscfg_mutex); + + /* Next unload from csdev lists. */ + cscfg_unload_owned_cfgs_feats(owner_info); + +list_remove: + /* remove from load order list */ + list_del(&owner_info->item); } + mutex_unlock(&cscfg_mutex); +} + +static void cscfg_clear_device(void) +{ + cscfg_unload_cfgs_on_exit(); cscfg_configfs_release(cscfg_mgr); device_unregister(cscfg_device()); - mutex_unlock(&cscfg_mutex); }
/* Initialise system config management API device */ @@ -1074,20 +1160,16 @@ int __init cscfg_init(void) { int err = 0;
+ /* create the device and init cscfg_mgr */ err = cscfg_create_device(); if (err) return err;
+ /* initialise configfs subsystem */ err = cscfg_configfs_init(cscfg_mgr); if (err) goto exit_err;
- INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list); - INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list); - INIT_LIST_HEAD(&cscfg_mgr->config_desc_list); - INIT_LIST_HEAD(&cscfg_mgr->load_order_list); - atomic_set(&cscfg_mgr->sys_active_cnt, 0); - /* preload built-in configurations */ err = cscfg_preload(THIS_MODULE); if (err)
From: Mike Leach mike.leach@linaro.org
[ Upstream commit 8add26f7ef33bba7984cb6ff7911c6aa970fe55a ]
The configfs system is a source of access to the config information in the configuration and feature lists.
This can result in additional LOCKDEP issues as a result of the mutex ordering between the config list mutex (cscfg_mutex) and the configfs system mutexes.
As such we need to adjust how load/unload operations work to ensure correct operation.
1) Previously the cscfg_mutex was held throughout the load/unload operation. This is now only held during configuration list manipulations, resulting in a multi-stage load/unload process.
2) All operations that manipulate the configfs representation of the configurations and features are now separated out and run without the cscfg_mutex being held. This avoids circular lock_dep issue with the built-in configfs mutexes and semaphores
3) As the load and unload is now multi-stage, some parts under the cscfg_mutex and others not: i) A flag indicating a load / unload operation in progress is used to serialise load / unload operations. ii) activating any configuration not possible when unload is in progress. iii) Configurations have an "available" flag set only after the last load stage for the configuration is complete. Activation of the configuration not possible till flag is set.
4) Following load/unload rules remain: i) Unload prevented while any configuration is active remains. ii) Unload in strict reverse order of load. iii) Existing configurations can be activated while a new load operation is underway. (by definition there can be no dependencies between an existing configuration and a new loading one due to ii) above.)
Fixes: eb2ec49606c2 ("coresight: syscfg: Update load API for config loadable modules") Reported-by: Suzuki Poulose suzuki.poulose@arm.com Signed-off-by: Mike Leach mike.leach@linaro.org Reviewed-and-tested-by: Suzuki K Poulose suzuki.poulose@arm.com Link: https://lore.kernel.org/r/20220628173004.30002-3-mike.leach@linaro.org Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../hwtracing/coresight/coresight-config.h | 2 + .../hwtracing/coresight/coresight-syscfg.c | 191 ++++++++++++++---- .../hwtracing/coresight/coresight-syscfg.h | 13 ++ 3 files changed, 165 insertions(+), 41 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 2e1670523461..6ba013975741 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -134,6 +134,7 @@ struct cscfg_feature_desc { * @active_cnt: ref count for activate on this configuration. * @load_owner: handle to load owner for dynamic load and unload of configs. * @fs_group: reference to configfs group for dynamic unload. + * @available: config can be activated - multi-stage load sets true on completion. */ struct cscfg_config_desc { const char *name; @@ -148,6 +149,7 @@ struct cscfg_config_desc { atomic_t active_cnt; void *load_owner; struct config_group *fs_group; + bool available; };
/** diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index 17e728ab5c99..11138a9762b0 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -447,6 +447,8 @@ static void cscfg_unload_owned_cfgs_feats(void *load_owner) struct cscfg_feature_desc *feat_desc, *feat_tmp; struct cscfg_registered_csdev *csdev_item;
+ lockdep_assert_held(&cscfg_mutex); + /* remove from each csdev instance feature and config lists */ list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) { /* @@ -460,7 +462,6 @@ static void cscfg_unload_owned_cfgs_feats(void *load_owner) /* remove from the config descriptor lists */ list_for_each_entry_safe(config_desc, cfg_tmp, &cscfg_mgr->config_desc_list, item) { if (config_desc->load_owner == load_owner) { - cscfg_configfs_del_config(config_desc); etm_perf_del_symlink_cscfg(config_desc); list_del(&config_desc->item); } @@ -469,12 +470,90 @@ static void cscfg_unload_owned_cfgs_feats(void *load_owner) /* remove from the feature descriptor lists */ list_for_each_entry_safe(feat_desc, feat_tmp, &cscfg_mgr->feat_desc_list, item) { if (feat_desc->load_owner == load_owner) { - cscfg_configfs_del_feature(feat_desc); list_del(&feat_desc->item); } } }
+/* + * load the features and configs to the lists - called with list mutex held + */ +static int cscfg_load_owned_cfgs_feats(struct cscfg_config_desc **config_descs, + struct cscfg_feature_desc **feat_descs, + struct cscfg_load_owner_info *owner_info) +{ + int i, err; + + lockdep_assert_held(&cscfg_mutex); + + /* load features first */ + if (feat_descs) { + for (i = 0; feat_descs[i]; i++) { + err = cscfg_load_feat(feat_descs[i]); + if (err) { + pr_err("coresight-syscfg: Failed to load feature %s\n", + feat_descs[i]->name); + return err; + } + feat_descs[i]->load_owner = owner_info; + } + } + + /* next any configurations to check feature dependencies */ + if (config_descs) { + for (i = 0; config_descs[i]; i++) { + err = cscfg_load_config(config_descs[i]); + if (err) { + pr_err("coresight-syscfg: Failed to load configuration %s\n", + config_descs[i]->name); + return err; + } + config_descs[i]->load_owner = owner_info; + config_descs[i]->available = false; + } + } + return 0; +} + +/* set configurations as available to activate at the end of the load process */ +static void cscfg_set_configs_available(struct cscfg_config_desc **config_descs) +{ + int i; + + lockdep_assert_held(&cscfg_mutex); + + if (config_descs) { + for (i = 0; config_descs[i]; i++) + config_descs[i]->available = true; + } +} + +/* + * Create and register each of the configurations and features with configfs. + * Called without mutex being held. + */ +static int cscfg_fs_register_cfgs_feats(struct cscfg_config_desc **config_descs, + struct cscfg_feature_desc **feat_descs) +{ + int i, err; + + if (feat_descs) { + for (i = 0; feat_descs[i]; i++) { + err = cscfg_configfs_add_feature(feat_descs[i]); + if (err) + return err; + } + } + if (config_descs) { + for (i = 0; config_descs[i]; i++) { + err = cscfg_configfs_add_config(config_descs[i]); + if (err) + return err; + } + } + return 0; +} + /** * cscfg_load_config_sets - API function to load feature and config sets. * @@ -497,57 +576,63 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs, struct cscfg_feature_desc **feat_descs, struct cscfg_load_owner_info *owner_info) { - int err = 0, i = 0; + int err = 0;
mutex_lock(&cscfg_mutex); - - /* load features first */ - if (feat_descs) { - while (feat_descs[i]) { - err = cscfg_load_feat(feat_descs[i]); - if (!err) - err = cscfg_configfs_add_feature(feat_descs[i]); - if (err) { - pr_err("coresight-syscfg: Failed to load feature %s\n", - feat_descs[i]->name); - cscfg_unload_owned_cfgs_feats(owner_info); - goto exit_unlock; - } - feat_descs[i]->load_owner = owner_info; - i++; - } + if (cscfg_mgr->load_state != CSCFG_NONE) { + mutex_unlock(&cscfg_mutex); + return -EBUSY; } + cscfg_mgr->load_state = CSCFG_LOAD;
- /* next any configurations to check feature dependencies */ - i = 0; - if (config_descs) { - while (config_descs[i]) { - err = cscfg_load_config(config_descs[i]); - if (!err) - err = cscfg_configfs_add_config(config_descs[i]); - if (err) { - pr_err("coresight-syscfg: Failed to load configuration %s\n", - config_descs[i]->name); - cscfg_unload_owned_cfgs_feats(owner_info); - goto exit_unlock; - } - config_descs[i]->load_owner = owner_info; - i++; - } - } + /* first load and add to the lists */ + err = cscfg_load_owned_cfgs_feats(config_descs, feat_descs, owner_info); + if (err) + goto err_clean_load;
/* add the load owner to the load order list */ list_add_tail(&owner_info->item, &cscfg_mgr->load_order_list); if (!list_is_singular(&cscfg_mgr->load_order_list)) { /* lock previous item in load order list */ err = cscfg_owner_get(list_prev_entry(owner_info, item)); - if (err) { - cscfg_unload_owned_cfgs_feats(owner_info); - list_del(&owner_info->item); - } + if (err) + goto err_clean_owner_list; }
+ /* + * make visible to configfs - configfs manipulation must occur outside + * the list mutex lock to avoid circular lockdep issues with configfs + * built in mutexes and semaphores. This is safe as it is not possible + * to start a new load/unload operation till the current one is done. + */ + mutex_unlock(&cscfg_mutex); + + /* create the configfs elements */ + err = cscfg_fs_register_cfgs_feats(config_descs, feat_descs); + mutex_lock(&cscfg_mutex); + + if (err) + goto err_clean_cfs; + + /* mark any new configs as available for activation */ + cscfg_set_configs_available(config_descs); + goto exit_unlock; + +err_clean_cfs: + /* cleanup after error registering with configfs */ + cscfg_fs_unregister_cfgs_feats(owner_info); + + if (!list_is_singular(&cscfg_mgr->load_order_list)) + cscfg_owner_put(list_prev_entry(owner_info, item)); + +err_clean_owner_list: + list_del(&owner_info->item); + +err_clean_load: + cscfg_unload_owned_cfgs_feats(owner_info); + exit_unlock: + cscfg_mgr->load_state = CSCFG_NONE; mutex_unlock(&cscfg_mutex); return err; } @@ -564,6 +649,9 @@ EXPORT_SYMBOL_GPL(cscfg_load_config_sets); * 1) no configurations are active. * 2) the set being unloaded was the last to be loaded to maintain dependencies. * + * Once the unload operation commences, we disallow any configuration being + * made active until it is complete. + * * @owner_info: Information on owner for set being unloaded. */ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info) @@ -572,6 +660,13 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info) struct cscfg_load_owner_info *load_list_item = NULL;
mutex_lock(&cscfg_mutex); + if (cscfg_mgr->load_state != CSCFG_NONE) { + mutex_unlock(&cscfg_mutex); + return -EBUSY; + } + + /* unload op in progress also prevents activation of any config */ + cscfg_mgr->load_state = CSCFG_UNLOAD;
/* cannot unload if anything is active */ if (atomic_read(&cscfg_mgr->sys_active_cnt)) { @@ -592,7 +687,12 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info) goto exit_unlock; }
- /* unload all belonging to load_owner */ + /* remove from configfs - again outside the scope of the list mutex */ + mutex_unlock(&cscfg_mutex); + cscfg_fs_unregister_cfgs_feats(owner_info); + mutex_lock(&cscfg_mutex); + + /* unload everything from lists belonging to load_owner */ cscfg_unload_owned_cfgs_feats(owner_info);
/* remove from load order list */ @@ -603,6 +703,7 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info) list_del(&owner_info->item);
exit_unlock: + cscfg_mgr->load_state = CSCFG_NONE; mutex_unlock(&cscfg_mutex); return err; } @@ -780,8 +881,15 @@ static int _cscfg_activate_config(unsigned long cfg_hash) struct cscfg_config_desc *config_desc; int err = -EINVAL;
+ if (cscfg_mgr->load_state == CSCFG_UNLOAD) + return -EBUSY; + list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) { if ((unsigned long)config_desc->event_ea->var == cfg_hash) { + /* if we happen upon a partly loaded config, can't use it */ + if (config_desc->available == false) + return -EBUSY; + /* must ensure that config cannot be unloaded in use */ err = cscfg_owner_get(config_desc->load_owner); if (err) @@ -1071,6 +1179,7 @@ static int cscfg_create_device(void) INIT_LIST_HEAD(&cscfg_mgr->config_desc_list); INIT_LIST_HEAD(&cscfg_mgr->load_order_list); atomic_set(&cscfg_mgr->sys_active_cnt, 0); + cscfg_mgr->load_state = CSCFG_NONE;
/* setup the device */ dev = cscfg_device(); diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h index 9106ffab4833..66e2db890d82 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.h +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -12,6 +12,17 @@
#include "coresight-config.h"
+/* + * Load operation types. + * When loading or unloading, another load operation cannot be run. + * When unloading configurations cannot be activated. + */ +enum cscfg_load_ops { + CSCFG_NONE, + CSCFG_LOAD, + CSCFG_UNLOAD +}; + /** * System configuration manager device. * @@ -30,6 +41,7 @@ * @cfgfs_subsys: configfs subsystem used to manage configurations. * @sysfs_active_config:Active config hash used if CoreSight controlled from sysfs. * @sysfs_active_preset:Active preset index used if CoreSight controlled from sysfs. + * @load_state: A multi-stage load/unload operation is in progress. */ struct cscfg_manager { struct device dev; @@ -41,6 +53,7 @@ struct cscfg_manager { struct configfs_subsystem cfgfs_subsys; u32 sysfs_active_config; int sysfs_active_preset; + enum cscfg_load_ops load_state; };
/* get reference to dev in cscfg_manager */
From: Neal Liu neal_liu@aspeedtech.com
[ Upstream commit 3b91edd624ab1ab694deef513a45eb9e9d49d75f ]
Add read TOC with format 1 to support CD-ROM emulation with Windows OS. This patch is tested on Windows OS Server 2019.
Fixes: 89ada0fe669a ("usb: gadget: f_mass_storage: Make CD-ROM emulation work with Mac OS-X") Reviewed-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: Neal Liu neal_liu@aspeedtech.com Link: https://lore.kernel.org/r/20220628021436.3252262-1-neal_liu@aspeedtech.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_mass_storage.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 3a77bca0ebe1..e884f295504f 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -1192,13 +1192,14 @@ static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh) u8 format; int i, len;
+ format = common->cmnd[2] & 0xf; + if ((common->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ - start_track > 1) { + (start_track > 1 && format != 0x1)) { curlun->sense_data = SS_INVALID_FIELD_IN_CDB; return -EINVAL; }
- format = common->cmnd[2] & 0xf; /* * Check if CDB is old style SFF-8020i * i.e. format is in 2 MSBs of byte 9 @@ -1208,8 +1209,8 @@ static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh) format = (common->cmnd[9] >> 6) & 0x3;
switch (format) { - case 0: - /* Formatted TOC */ + case 0: /* Formatted TOC */ + case 1: /* Multi-session info */ len = 4 + 2*8; /* 4 byte header + 2 descriptors */ memset(buf, 0, len); buf[1] = len - 2; /* TOC Length excludes length field */ @@ -1250,7 +1251,7 @@ static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh) return len;
default: - /* Multi-session, PMA, ATIP, CD-TEXT not supported/required */ + /* PMA, ATIP, CD-TEXT not supported/required */ curlun->sense_data = SS_INVALID_FIELD_IN_CDB; return -EINVAL; }
From: Bryan O'Donoghue bryan.odonoghue@linaro.org
[ Upstream commit 07e7fcf1714c5f9930ad27613fea940aedba68da ]
When adding in the indexes for this clock-controller we missed SYSTEM_MM_NOC_BFDCD_CLK_SRC.
Add it in now.
Fixes: 4c71d6abc4fc ("clk: qcom: Add DT bindings for MSM8939 GCC") Cc: Rob Herring robh+dt@kernel.org Cc: Krzysztof Kozlowski krzysztof.kozlowski+dt@linaro.org Cc: devicetree@vger.kernel.org Signed-off-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Acked-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220504163835.40130-2-bryan.odonoghue@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/dt-bindings/clock/qcom,gcc-msm8939.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8939.h b/include/dt-bindings/clock/qcom,gcc-msm8939.h index 0634467c4ce5..2d545ed0d35a 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8939.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8939.h @@ -192,6 +192,7 @@ #define GCC_VENUS0_CORE0_VCODEC0_CLK 183 #define GCC_VENUS0_CORE1_VCODEC0_CLK 184 #define GCC_OXILI_TIMER_CLK 185 +#define SYSTEM_MM_NOC_BFDCD_CLK_SRC 186
/* Indexes for GDSCs */ #define BIMC_GDSC 0
From: Bryan O'Donoghue bryan.odonoghue@linaro.org
[ Upstream commit 63d42708320d6d2ca9ed505123d50ff4a542c36f ]
Reviewing qcom docs for the 8939 we can see the command rcgr is pointing to the wrong address. bimc_ddr_clk_src_rcgr is @ 0x01832024 not 0x01832004.
Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller") Signed-off-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220504163835.40130-3-bryan.odonoghue@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gcc-msm8939.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c index 39ebb443ae3d..31568658d23d 100644 --- a/drivers/clk/qcom/gcc-msm8939.c +++ b/drivers/clk/qcom/gcc-msm8939.c @@ -632,7 +632,7 @@ static struct clk_rcg2 system_noc_bfdcd_clk_src = { };
static struct clk_rcg2 bimc_ddr_clk_src = { - .cmd_rcgr = 0x32004, + .cmd_rcgr = 0x32024, .hid_width = 5, .parent_map = gcc_xo_gpll0_bimc_map, .clkr.hw.init = &(struct clk_init_data){
From: Bryan O'Donoghue bryan.odonoghue@linaro.org
[ Upstream commit dd363e2f7196278e7a30f509a0e8a841cb763b14 ]
The msm8939 has an additional higher operating point for the multi-media peripherals. The higher throughput MM componets operate off of the system-mm noc not the system noc.
system_mm_noc_bfdcd_clk_src is the source clock for the higher frequency capable system noc mm.
Maximum frequency for the MM SNOC is 400 MHz.
Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller") Signed-off-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220504163835.40130-4-bryan.odonoghue@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gcc-msm8939.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c index 31568658d23d..12bab9067ea8 100644 --- a/drivers/clk/qcom/gcc-msm8939.c +++ b/drivers/clk/qcom/gcc-msm8939.c @@ -644,6 +644,18 @@ static struct clk_rcg2 bimc_ddr_clk_src = { }, };
+static struct clk_rcg2 system_mm_noc_bfdcd_clk_src = { + .cmd_rcgr = 0x2600c, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll6a_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "system_mm_noc_bfdcd_clk_src", + .parent_data = gcc_xo_gpll0_gpll6a_parent_data, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + static const struct freq_tbl ftbl_gcc_camss_ahb_clk[] = { F(40000000, P_GPLL0, 10, 1, 2), F(80000000, P_GPLL0, 10, 0, 0), @@ -3623,6 +3635,7 @@ static struct clk_regmap *gcc_msm8939_clocks[] = { [GPLL2_VOTE] = &gpll2_vote, [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr, [SYSTEM_NOC_BFDCD_CLK_SRC] = &system_noc_bfdcd_clk_src.clkr, + [SYSTEM_MM_NOC_BFDCD_CLK_SRC] = &system_mm_noc_bfdcd_clk_src.clkr, [CAMSS_AHB_CLK_SRC] = &camss_ahb_clk_src.clkr, [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr, [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
From: Bryan O'Donoghue bryan.odonoghue@linaro.org
[ Upstream commit 05eed0990927aa9634682fec58660e30f7b7ae30 ]
Qcom docs indciate the following peripherals operating from System NOC MM not from System NOC clocks.
- MDP - VFE - JPEGe - Venus
Switch over the relevant parent pointers.
Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller") Signed-off-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220504163835.40130-5-bryan.odonoghue@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gcc-msm8939.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c index 12bab9067ea8..c7377ec0f423 100644 --- a/drivers/clk/qcom/gcc-msm8939.c +++ b/drivers/clk/qcom/gcc-msm8939.c @@ -2453,7 +2453,7 @@ static struct clk_branch gcc_camss_jpeg_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_camss_jpeg_axi_clk", .parent_data = &(const struct clk_parent_data){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2657,7 +2657,7 @@ static struct clk_branch gcc_camss_vfe_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_camss_vfe_axi_clk", .parent_data = &(const struct clk_parent_data){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2813,7 +2813,7 @@ static struct clk_branch gcc_mdss_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_mdss_axi_clk", .parent_data = &(const struct clk_parent_data){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -3205,7 +3205,7 @@ static struct clk_branch gcc_mdp_tbu_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_mdp_tbu_clk", .parent_data = &(const struct clk_parent_data){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -3223,7 +3223,7 @@ static struct clk_branch gcc_venus_tbu_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_venus_tbu_clk", .parent_data = &(const struct clk_parent_data){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -3241,7 +3241,7 @@ static struct clk_branch gcc_vfe_tbu_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_vfe_tbu_clk", .parent_data = &(const struct clk_parent_data){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -3259,7 +3259,7 @@ static struct clk_branch gcc_jpeg_tbu_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_jpeg_tbu_clk", .parent_data = &(const struct clk_parent_data){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -3496,7 +3496,7 @@ static struct clk_branch gcc_venus0_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_venus0_axi_clk", .parent_data = &(const struct clk_parent_data){ - .hw = &system_noc_bfdcd_clk_src.clkr.hw, + .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT,
From: Sergey Shtylyov s.shtylyov@omp.ru
[ Upstream commit 1ce69c35b86038dd11d3a6115a04501c5b89a940 ]
Commit cbf286e8ef83 ("xhci: fix unsafe memory usage in xhci tracing") apparently missed one sprintf() call in xhci_decode_trb() -- replace it with the snprintf() call as well...
Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool.
Fixes: cbf286e8ef83 ("xhci: fix unsafe memory usage in xhci tracing") Signed-off-by: Sergey Shtylyov s.shtylyov@omp.ru Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20220630124645.1805902-2-mathias.nyman@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 28aaf031f9a8..1960b47acfb2 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -2417,7 +2417,7 @@ static inline const char *xhci_decode_trb(char *str, size_t size, field3 & TRB_CYCLE ? 'C' : 'c'); break; case TRB_STOP_RING: - sprintf(str, + snprintf(str, size, "%s: slot %d sp %d ep %d flags %c", xhci_trb_type_string(type), TRB_TO_SLOT_ID(field3),
From: Bob Pearson rpearsonhpe@gmail.com
[ Upstream commit 0ed5493e430a1d887eb62b45c75dd5d6bb2dcf48 ]
Add a responder state for atomic reply similar to read reply and rename process_atomic() rxe_atomic_reply(). In preparation for merging the normal and retry atomic responder flows.
Link: https://lore.kernel.org/r/20220606143836.3323-3-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson rpearsonhpe@gmail.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_resp.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c index f4f6ee5d81fe..e38bf958ab48 100644 --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c @@ -21,6 +21,7 @@ enum resp_states { RESPST_CHK_RKEY, RESPST_EXECUTE, RESPST_READ_REPLY, + RESPST_ATOMIC_REPLY, RESPST_COMPLETE, RESPST_ACKNOWLEDGE, RESPST_CLEANUP, @@ -55,6 +56,7 @@ static char *resp_state_name[] = { [RESPST_CHK_RKEY] = "CHK_RKEY", [RESPST_EXECUTE] = "EXECUTE", [RESPST_READ_REPLY] = "READ_REPLY", + [RESPST_ATOMIC_REPLY] = "ATOMIC_REPLY", [RESPST_COMPLETE] = "COMPLETE", [RESPST_ACKNOWLEDGE] = "ACKNOWLEDGE", [RESPST_CLEANUP] = "CLEANUP", @@ -552,8 +554,8 @@ static enum resp_states write_data_in(struct rxe_qp *qp, /* Guarantee atomicity of atomic operations at the machine level. */ static DEFINE_SPINLOCK(atomic_ops_lock);
-static enum resp_states process_atomic(struct rxe_qp *qp, - struct rxe_pkt_info *pkt) +static enum resp_states rxe_atomic_reply(struct rxe_qp *qp, + struct rxe_pkt_info *pkt) { u64 *vaddr; enum resp_states ret; @@ -585,7 +587,16 @@ static enum resp_states process_atomic(struct rxe_qp *qp,
spin_unlock_bh(&atomic_ops_lock);
- ret = RESPST_NONE; + qp->resp.msn++; + + /* next expected psn, read handles this separately */ + qp->resp.psn = (pkt->psn + 1) & BTH_PSN_MASK; + qp->resp.ack_psn = qp->resp.psn; + + qp->resp.opcode = pkt->opcode; + qp->resp.status = IB_WC_SUCCESS; + + ret = RESPST_ACKNOWLEDGE; out: return ret; } @@ -858,9 +869,7 @@ static enum resp_states execute(struct rxe_qp *qp, struct rxe_pkt_info *pkt) qp->resp.msn++; return RESPST_READ_REPLY; } else if (pkt->mask & RXE_ATOMIC_MASK) { - err = process_atomic(qp, pkt); - if (err) - return err; + return RESPST_ATOMIC_REPLY; } else { /* Unreachable */ WARN_ON_ONCE(1); @@ -1316,6 +1325,9 @@ int rxe_responder(void *arg) case RESPST_READ_REPLY: state = read_reply(qp, pkt); break; + case RESPST_ATOMIC_REPLY: + state = rxe_atomic_reply(qp, pkt); + break; case RESPST_ACKNOWLEDGE: state = acknowledge(qp, pkt); break;
From: Bob Pearson rpearsonhpe@gmail.com
[ Upstream commit 7cb33d1bc1ac8e51fd88928f96674d392f8e07c4 ]
When a local operation (invalidate mr, reg mr, bind mw) is finished there will be no ack packet coming from a responder to cause the wqe to be completed. This may happen anyway if a subsequent wqe performs IO. Currently if the wqe is signalled the completer tasklet is scheduled immediately but not otherwise.
This leads to a deadlock if the next wqe has the fence bit set in send flags and the operation is not signalled. This patch removes the condition that the wqe must be signalled in order to schedule the completer tasklet which is the simplest fix for this deadlock and is fairly low cost. This is the analog for local operations of always setting the ackreq bit in all last or only request packets even if the operation is not signalled.
Link: https://lore.kernel.org/r/20220523223251.15350-1-rpearsonhpe@gmail.com Reported-by: Jenny Hack jhack@hpe.com Fixes: c1a411268a4b ("RDMA/rxe: Move local ops to subroutine") Signed-off-by: Bob Pearson rpearsonhpe@gmail.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_req.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c index 9d98237389cf..15fefc689ca3 100644 --- a/drivers/infiniband/sw/rxe/rxe_req.c +++ b/drivers/infiniband/sw/rxe/rxe_req.c @@ -581,9 +581,11 @@ static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe) wqe->status = IB_WC_SUCCESS; qp->req.wqe_index = queue_next_index(qp->sq.queue, qp->req.wqe_index);
- if ((wqe->wr.send_flags & IB_SEND_SIGNALED) || - qp->sq_sig_type == IB_SIGNAL_ALL_WR) - rxe_run_task(&qp->comp.task, 1); + /* There is no ack coming for local work requests + * which can lead to a deadlock. So go ahead and complete + * it now. + */ + rxe_run_task(&qp->comp.task, 1);
return 0; }
From: Robert Marko robimarko@gmail.com
[ Upstream commit ca41ec1b30434636c56c5600b24a8d964d359d9c ]
Like in IPQ6018 the NSS related Alpha PLL-s require initial configuration to work.
So, obtain the regmap that is required for the Alpha PLL configuration and thus utilize the qcom_cc_really_probe() as we already have the regmap. Then utilize the Alpha PLL configs from the downstream QCA 5.4 based kernel to configure them.
This fixes the UBI32 and NSS crypto PLL-s failing to get enabled by the kernel.
Fixes: b8e7e519625f ("clk: qcom: ipq8074: add remaining PLL’s") Signed-off-by: Robert Marko robimarko@gmail.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220515210048.483898-1-robimarko@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gcc-ipq8074.c | 39 +++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c index 541016db3c4b..1a5141da7e23 100644 --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c @@ -4371,6 +4371,33 @@ static struct clk_branch gcc_pcie0_axi_s_bridge_clk = { }, };
+static const struct alpha_pll_config ubi32_pll_config = { + .l = 0x4e, + .config_ctl_val = 0x200d4aa8, + .config_ctl_hi_val = 0x3c2, + .main_output_mask = BIT(0), + .aux_output_mask = BIT(1), + .pre_div_val = 0x0, + .pre_div_mask = BIT(12), + .post_div_val = 0x0, + .post_div_mask = GENMASK(9, 8), +}; + +static const struct alpha_pll_config nss_crypto_pll_config = { + .l = 0x3e, + .alpha = 0x0, + .alpha_hi = 0x80, + .config_ctl_val = 0x4001055b, + .main_output_mask = BIT(0), + .pre_div_val = 0x0, + .pre_div_mask = GENMASK(14, 12), + .post_div_val = 0x1 << 8, + .post_div_mask = GENMASK(11, 8), + .vco_mask = GENMASK(21, 20), + .vco_val = 0x0, + .alpha_en_mask = BIT(24), +}; + static struct clk_hw *gcc_ipq8074_hws[] = { &gpll0_out_main_div2.hw, &gpll6_out_main_div2.hw, @@ -4772,7 +4799,17 @@ static const struct qcom_cc_desc gcc_ipq8074_desc = {
static int gcc_ipq8074_probe(struct platform_device *pdev) { - return qcom_cc_probe(pdev, &gcc_ipq8074_desc); + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &gcc_ipq8074_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config); + clk_alpha_pll_configure(&nss_crypto_pll_main, regmap, + &nss_crypto_pll_config); + + return qcom_cc_really_probe(pdev, &gcc_ipq8074_desc, regmap); }
static struct platform_driver gcc_ipq8074_driver = {
From: Robert Marko robimarko@gmail.com
[ Upstream commit 3401ea2856ef84f39b75f0dc5ebcaeda81cb90ec ]
UBI32 Huayra PLL fails to lock in 5 us in some SoC silicon and thus it will cause the wait_for_pll() to timeout and thus return the error indicating that the PLL failed to lock.
This is bug in Huayra PLL HW for which SW workaround is to set bit 26 of TEST_CTL register.
This is ported from the QCA 5.4 based downstream kernel.
Fixes: b8e7e519625f ("clk: qcom: ipq8074: add remaining PLL’s") Signed-off-by: Robert Marko robimarko@gmail.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220515210048.483898-2-robimarko@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gcc-ipq8074.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c index 1a5141da7e23..b4291ba53c78 100644 --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c @@ -4805,6 +4805,9 @@ static int gcc_ipq8074_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap);
+ /* SW Workaround for UBI32 Huayra PLL */ + regmap_update_bits(regmap, 0x2501c, BIT(26), BIT(26)); + clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config); clk_alpha_pll_configure(&nss_crypto_pll_main, regmap, &nss_crypto_pll_config);
From: Robert Marko robimarko@gmail.com
[ Upstream commit 0e9e61a2815b5cd34f1b495b2d72e8127ce9b794 ]
NSS port 5 and 6 frequency tables are currently broken and are causing a wide ranges of issue like 1G not working at all on port 6 or port 5 being clocked with 312 instead of 125 MHz as UNIPHY1 gets selected.
So, update the frequency tables with the ones from the downstream QCA 5.4 based kernel which has already fixed this.
Fixes: 7117a51ed303 ("clk: qcom: ipq8074: add NSS ethernet port clocks") Signed-off-by: Robert Marko robimarko@gmail.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220515210048.483898-3-robimarko@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gcc-ipq8074.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c index b4291ba53c78..f1017f2e61bd 100644 --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c @@ -1788,8 +1788,10 @@ static struct clk_regmap_div nss_port4_tx_div_clk_src = { static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = { F(19200000, P_XO, 1, 0, 0), F(25000000, P_UNIPHY1_RX, 12.5, 0, 0), + F(25000000, P_UNIPHY0_RX, 5, 0, 0), F(78125000, P_UNIPHY1_RX, 4, 0, 0), F(125000000, P_UNIPHY1_RX, 2.5, 0, 0), + F(125000000, P_UNIPHY0_RX, 1, 0, 0), F(156250000, P_UNIPHY1_RX, 2, 0, 0), F(312500000, P_UNIPHY1_RX, 1, 0, 0), { } @@ -1828,8 +1830,10 @@ static struct clk_regmap_div nss_port5_rx_div_clk_src = { static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = { F(19200000, P_XO, 1, 0, 0), F(25000000, P_UNIPHY1_TX, 12.5, 0, 0), + F(25000000, P_UNIPHY0_TX, 5, 0, 0), F(78125000, P_UNIPHY1_TX, 4, 0, 0), F(125000000, P_UNIPHY1_TX, 2.5, 0, 0), + F(125000000, P_UNIPHY0_TX, 1, 0, 0), F(156250000, P_UNIPHY1_TX, 2, 0, 0), F(312500000, P_UNIPHY1_TX, 1, 0, 0), { } @@ -1867,8 +1871,10 @@ static struct clk_regmap_div nss_port5_tx_div_clk_src = {
static const struct freq_tbl ftbl_nss_port6_rx_clk_src[] = { F(19200000, P_XO, 1, 0, 0), + F(25000000, P_UNIPHY2_RX, 5, 0, 0), F(25000000, P_UNIPHY2_RX, 12.5, 0, 0), F(78125000, P_UNIPHY2_RX, 4, 0, 0), + F(125000000, P_UNIPHY2_RX, 1, 0, 0), F(125000000, P_UNIPHY2_RX, 2.5, 0, 0), F(156250000, P_UNIPHY2_RX, 2, 0, 0), F(312500000, P_UNIPHY2_RX, 1, 0, 0), @@ -1907,8 +1913,10 @@ static struct clk_regmap_div nss_port6_rx_div_clk_src = {
static const struct freq_tbl ftbl_nss_port6_tx_clk_src[] = { F(19200000, P_XO, 1, 0, 0), + F(25000000, P_UNIPHY2_TX, 5, 0, 0), F(25000000, P_UNIPHY2_TX, 12.5, 0, 0), F(78125000, P_UNIPHY2_TX, 4, 0, 0), + F(125000000, P_UNIPHY2_TX, 1, 0, 0), F(125000000, P_UNIPHY2_TX, 2.5, 0, 0), F(156250000, P_UNIPHY2_TX, 2, 0, 0), F(312500000, P_UNIPHY2_TX, 1, 0, 0),
From: Robert Marko robimarko@gmail.com
[ Upstream commit 2bd357e698207e2e65db03007e4be65bf9d6a7b3 ]
Currently, attempting to enable the UBI clocks will cause the stuck at off warning to be printed and clk_enable will fail.
[ 14.936694] gcc_ubi1_ahb_clk status stuck at 'off'
Downstream 5.4 QCA kernel has fixed this by seting the BRANCH_HALT_DELAY flag on UBI clocks, so lets do the same.
Fixes: 5736294aef83 ("clk: qcom: ipq8074: add NSS clocks") Signed-off-by: Robert Marko robimarko@gmail.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220515210048.483898-6-robimarko@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gcc-ipq8074.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c index f1017f2e61bd..2c2ecfc5e61f 100644 --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c @@ -3354,6 +3354,7 @@ static struct clk_branch gcc_nssnoc_ubi1_ahb_clk = {
static struct clk_branch gcc_ubi0_ahb_clk = { .halt_reg = 0x6820c, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x6820c, .enable_mask = BIT(0), @@ -3371,6 +3372,7 @@ static struct clk_branch gcc_ubi0_ahb_clk = {
static struct clk_branch gcc_ubi0_axi_clk = { .halt_reg = 0x68200, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68200, .enable_mask = BIT(0), @@ -3388,6 +3390,7 @@ static struct clk_branch gcc_ubi0_axi_clk = {
static struct clk_branch gcc_ubi0_nc_axi_clk = { .halt_reg = 0x68204, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68204, .enable_mask = BIT(0), @@ -3405,6 +3408,7 @@ static struct clk_branch gcc_ubi0_nc_axi_clk = {
static struct clk_branch gcc_ubi0_core_clk = { .halt_reg = 0x68210, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68210, .enable_mask = BIT(0), @@ -3422,6 +3426,7 @@ static struct clk_branch gcc_ubi0_core_clk = {
static struct clk_branch gcc_ubi0_mpt_clk = { .halt_reg = 0x68208, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68208, .enable_mask = BIT(0), @@ -3439,6 +3444,7 @@ static struct clk_branch gcc_ubi0_mpt_clk = {
static struct clk_branch gcc_ubi1_ahb_clk = { .halt_reg = 0x6822c, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x6822c, .enable_mask = BIT(0), @@ -3456,6 +3462,7 @@ static struct clk_branch gcc_ubi1_ahb_clk = {
static struct clk_branch gcc_ubi1_axi_clk = { .halt_reg = 0x68220, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68220, .enable_mask = BIT(0), @@ -3473,6 +3480,7 @@ static struct clk_branch gcc_ubi1_axi_clk = {
static struct clk_branch gcc_ubi1_nc_axi_clk = { .halt_reg = 0x68224, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68224, .enable_mask = BIT(0), @@ -3490,6 +3498,7 @@ static struct clk_branch gcc_ubi1_nc_axi_clk = {
static struct clk_branch gcc_ubi1_core_clk = { .halt_reg = 0x68230, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68230, .enable_mask = BIT(0), @@ -3507,6 +3516,7 @@ static struct clk_branch gcc_ubi1_core_clk = {
static struct clk_branch gcc_ubi1_mpt_clk = { .halt_reg = 0x68228, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68228, .enable_mask = BIT(0),
From: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org
[ Upstream commit 103dd2338bbff567bce7acd00fc5a09c806b38ec ]
On SDM845 two found VFE GDSC power domains shall not be operated, if titan top is turned off, thus the former power domains will be set as subdomains by a GDSC registration routine.
Fixes: 78412c262004 ("clk: qcom: Add camera clock controller driver for SDM845") Signed-off-by: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org Reviewed-by: Robert Foss robert.foss@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220519214133.1728979-2-vladimir.zapolskiy@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/camcc-sdm845.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c index be3f95326965..27d44188a7ab 100644 --- a/drivers/clk/qcom/camcc-sdm845.c +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -1534,6 +1534,8 @@ static struct clk_branch cam_cc_sys_tmr_clk = { }, };
+static struct gdsc titan_top_gdsc; + static struct gdsc bps_gdsc = { .gdscr = 0x6004, .pd = { @@ -1567,6 +1569,7 @@ static struct gdsc ife_0_gdsc = { .name = "ife_0_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, };
@@ -1576,6 +1579,7 @@ static struct gdsc ife_1_gdsc = { .name = "ife_1_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, };
From: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org
[ Upstream commit f8acf01a6a4f84baf05181e24bd48def4ba23f5b ]
On SM8250 two found VFE GDSC power domains shall not be operated, if titan top is turned off, thus the former power domains will be set as subdomains by a GDSC registration routine.
Fixes: 5d66ca79b58c ("clk: qcom: Add camera clock controller driver for SM8250") Signed-off-by: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org Reviewed-by: Robert Foss robert.foss@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220519214133.1728979-3-vladimir.zapolskiy@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/camcc-sm8250.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c index ae4e9774f36e..9b32c56a5bc5 100644 --- a/drivers/clk/qcom/camcc-sm8250.c +++ b/drivers/clk/qcom/camcc-sm8250.c @@ -2205,6 +2205,8 @@ static struct clk_branch cam_cc_sleep_clk = { }, };
+static struct gdsc titan_top_gdsc; + static struct gdsc bps_gdsc = { .gdscr = 0x7004, .pd = { @@ -2238,6 +2240,7 @@ static struct gdsc ife_0_gdsc = { .name = "ife_0_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, };
@@ -2247,6 +2250,7 @@ static struct gdsc ife_1_gdsc = { .name = "ife_1_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, };
From: Nikita Travkin nikita@trvn.ru
[ Upstream commit bdafb609c3bb848d710ad9cd4debd2ee9d6a4049 ]
In cases when MND is not enabled (e.g. when only Half Integer Divider is used), setting D registers makes no effect.
Fail instead of making ineffective write.
Fixes: 7f891faf596e ("clk: qcom: clk-rcg2: Add support for duty-cycle for RCG") Signed-off-by: Nikita Travkin nikita@trvn.ru Reviewed-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220612145955.385787-2-nikita@trvn.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/clk-rcg2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 8e5dce09d162..2375e8122012 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -437,7 +437,7 @@ static int clk_rcg2_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); - u32 notn_m, n, m, d, not2d, mask, duty_per; + u32 notn_m, n, m, d, not2d, mask, duty_per, cfg; int ret;
/* Duty-cycle cannot be modified for non-MND RCGs */ @@ -448,6 +448,11 @@ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), ¬n_m); regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m); + regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg); + + /* Duty-cycle cannot be modified if MND divider is in bypass mode. */ + if (!(cfg & CFG_MODE_MASK)) + return -EINVAL;
n = (~(notn_m) + m) & mask;
From: Nikita Travkin nikita@trvn.ru
[ Upstream commit d0696770cef35a1fd16ea2167e2198c18aa6fbfe ]
Sometimes calculation of d value may result in 0 because of the rounding after integer division. This causes the following error:
[ 113.969689] camss_gp1_clk_src: rcg didn't update its configuration. [ 113.969754] WARNING: CPU: 3 PID: 35 at drivers/clk/qcom/clk-rcg2.c:122 update_config+0xc8/0xdc
Make sure that D value is never zero.
Fixes: 7f891faf596e ("clk: qcom: clk-rcg2: Add support for duty-cycle for RCG") Signed-off-by: Nikita Travkin nikita@trvn.ru Reviewed-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220612145955.385787-3-nikita@trvn.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/clk-rcg2.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 2375e8122012..28019edd2a50 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -13,6 +13,7 @@ #include <linux/rational.h> #include <linux/regmap.h> #include <linux/math64.h> +#include <linux/minmax.h> #include <linux/slab.h>
#include <asm/div64.h> @@ -461,9 +462,11 @@ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) /* Calculate 2d value */ d = DIV_ROUND_CLOSEST(n * duty_per * 2, 100);
- /* Check bit widths of 2d. If D is too big reduce duty cycle. */ - if (d > mask) - d = mask; + /* + * Check bit widths of 2d. If D is too big reduce duty cycle. + * Also make sure it is never zero. + */ + d = clamp_val(d, 1, mask);
if ((d / 2) > (n - m)) d = (n - m) * 2;
From: Yushan Zhou katrinzhou@tencent.com
[ Upstream commit 72b5d5aef246a0387cefa23121dd90901c7a691a ]
When lockdep is enabled, lockdep_assert_held_write would cause potential NULL pointer dereference.
Fix the following smatch warnings:
fs/kernfs/dir.c:1353 __kernfs_remove() warn: variable dereferenced before check 'kn' (see line 1346)
Fixes: 393c3714081a ("kernfs: switch global kernfs_rwsem lock to per-fs lock") Signed-off-by: Yushan Zhou katrinzhou@tencent.com Link: https://lore.kernel.org/r/20220630082512.3482581-1-zys.zljxml@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/kernfs/dir.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 6eca72cfa1f2..1cc88ba6de90 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1343,14 +1343,17 @@ static void __kernfs_remove(struct kernfs_node *kn) { struct kernfs_node *pos;
+ /* Short-circuit if non-root @kn has already finished removal. */ + if (!kn) + return; + lockdep_assert_held_write(&kernfs_root(kn)->kernfs_rwsem);
/* - * Short-circuit if non-root @kn has already finished removal. * This is for kernfs_remove_self() which plays with active ref * after removal. */ - if (!kn || (kn->parent && RB_EMPTY_NODE(&kn->rb))) + if (kn->parent && RB_EMPTY_NODE(&kn->rb)) return;
pr_debug("kernfs %s: removing\n", kn->name);
From: Yang Shi shy828301@gmail.com
[ Upstream commit 507db7927cd181d409dd495c8384b8e14c21c600 ]
The parameter used by DEFINE_PAGE_VMA_WALK is _page not page, fix the parameter name. It didn't cause any build error, it is probably because the only caller is write_protect_page() from ksm.c, which pass in page.
Link: https://lkml.kernel.org/r/20220512174551.81279-1-shy828301@gmail.com Fixes: 2aff7a4755be ("mm: Convert page_vma_mapped_walk to work on PFNs") Signed-off-by: Yang Shi shy828301@gmail.com Reviewed-by: Muchun Song songmuchun@bytedance.com Reviewed-by: Matthew Wilcox (Oracle) willy@infradead.org Cc: Muchun Song songmuchun@bytedance.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/rmap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 9ec23138e410..bf80adca980b 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -325,8 +325,8 @@ struct page_vma_mapped_walk { #define DEFINE_PAGE_VMA_WALK(name, _page, _vma, _address, _flags) \ struct page_vma_mapped_walk name = { \ .pfn = page_to_pfn(_page), \ - .nr_pages = compound_nr(page), \ - .pgoff = page_to_pgoff(page), \ + .nr_pages = compound_nr(_page), \ + .pgoff = page_to_pgoff(_page), \ .vma = _vma, \ .address = _address, \ .flags = _flags, \
From: Miaohe Lin linmiaohe@huawei.com
[ Upstream commit 7ce82f4c3f3ead13a9d9498768e3b1a79975c4d8 ]
We might fail to isolate huge page due to e.g. the page is under migration which cleared HPageMigratable. We should return errno in this case rather than always return 1 which could confuse the user, i.e. the caller might think all of the memory is migrated while the hugetlb page is left behind. We make the prototype of isolate_huge_page consistent with isolate_lru_page as suggested by Huang Ying and rename isolate_huge_page to isolate_hugetlb as suggested by Muchun to improve the readability.
Link: https://lkml.kernel.org/r/20220530113016.16663-4-linmiaohe@huawei.com Fixes: e8db67eb0ded ("mm: migrate: move_pages() supports thp migration") Signed-off-by: Miaohe Lin linmiaohe@huawei.com Suggested-by: Huang Ying ying.huang@intel.com Reported-by: kernel test robot lkp@intel.com (build error) Cc: Alistair Popple apopple@nvidia.com Cc: Christoph Hellwig hch@lst.de Cc: Christoph Lameter cl@linux.com Cc: David Hildenbrand david@redhat.com Cc: David Howells dhowells@redhat.com Cc: Mike Kravetz mike.kravetz@oracle.com Cc: Muchun Song songmuchun@bytedance.com Cc: Oscar Salvador osalvador@suse.de Cc: Peter Xu peterx@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/hugetlb.h | 6 +++--- mm/gup.c | 2 +- mm/hugetlb.c | 11 +++++------ mm/memory-failure.c | 2 +- mm/memory_hotplug.c | 2 +- mm/mempolicy.c | 2 +- mm/migrate.c | 7 ++++--- 7 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index e4cff27d1198..756b66ff025e 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -170,7 +170,7 @@ bool hugetlb_reserve_pages(struct inode *inode, long from, long to, vm_flags_t vm_flags); long hugetlb_unreserve_pages(struct inode *inode, long start, long end, long freed); -bool isolate_huge_page(struct page *page, struct list_head *list); +int isolate_hugetlb(struct page *page, struct list_head *list); int get_hwpoison_huge_page(struct page *page, bool *hugetlb); int get_huge_page_for_hwpoison(unsigned long pfn, int flags); void putback_active_hugepage(struct page *page); @@ -376,9 +376,9 @@ static inline pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, return NULL; }
-static inline bool isolate_huge_page(struct page *page, struct list_head *list) +static inline int isolate_hugetlb(struct page *page, struct list_head *list) { - return false; + return -EBUSY; }
static inline int get_hwpoison_huge_page(struct page *page, bool *hugetlb) diff --git a/mm/gup.c b/mm/gup.c index e2a39e30756d..fd3262ae92fc 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -1900,7 +1900,7 @@ static long check_and_migrate_movable_pages(unsigned long nr_pages, * Try to move out any movable page before pinning the range. */ if (folio_test_hugetlb(folio)) { - if (!isolate_huge_page(&folio->page, + if (isolate_hugetlb(&folio->page, &movable_page_list)) isolation_error_count++; continue; diff --git a/mm/hugetlb.c b/mm/hugetlb.c index a18c071c294e..b7f007399be2 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2766,8 +2766,7 @@ static int alloc_and_dissolve_huge_page(struct hstate *h, struct page *old_page, * Fail with -EBUSY if not possible. */ spin_unlock_irq(&hugetlb_lock); - if (!isolate_huge_page(old_page, list)) - ret = -EBUSY; + ret = isolate_hugetlb(old_page, list); spin_lock_irq(&hugetlb_lock); goto free_new; } else if (!HPageFreed(old_page)) { @@ -2843,7 +2842,7 @@ int isolate_or_dissolve_huge_page(struct page *page, struct list_head *list) if (hstate_is_gigantic(h)) return -ENOMEM;
- if (page_count(head) && isolate_huge_page(head, list)) + if (page_count(head) && !isolate_hugetlb(head, list)) ret = 0; else if (!page_count(head)) ret = alloc_and_dissolve_huge_page(h, head, list); @@ -6966,15 +6965,15 @@ follow_huge_pgd(struct mm_struct *mm, unsigned long address, pgd_t *pgd, int fla return pte_page(*(pte_t *)pgd) + ((address & ~PGDIR_MASK) >> PAGE_SHIFT); }
-bool isolate_huge_page(struct page *page, struct list_head *list) +int isolate_hugetlb(struct page *page, struct list_head *list) { - bool ret = true; + int ret = 0;
spin_lock_irq(&hugetlb_lock); if (!PageHeadHuge(page) || !HPageMigratable(page) || !get_page_unless_zero(page)) { - ret = false; + ret = -EBUSY; goto unlock; } ClearHPageMigratable(page); diff --git a/mm/memory-failure.c b/mm/memory-failure.c index da39ec8afca8..845369f839e1 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -2178,7 +2178,7 @@ static bool isolate_page(struct page *page, struct list_head *pagelist) bool lru = PageLRU(page);
if (PageHuge(page)) { - isolated = isolate_huge_page(page, pagelist); + isolated = !isolate_hugetlb(page, pagelist); } else { if (lru) isolated = !isolate_lru_page(page); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 1213d0c67a53..649a50ed90f3 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1643,7 +1643,7 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
if (PageHuge(page)) { pfn = page_to_pfn(head) + compound_nr(head) - 1; - isolate_huge_page(head, &source); + isolate_hugetlb(head, &source); continue; } else if (PageTransHuge(page)) pfn = page_to_pfn(head) + thp_nr_pages(page) - 1; diff --git a/mm/mempolicy.c b/mm/mempolicy.c index d39b01fd52fe..9689919a2829 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -602,7 +602,7 @@ static int queue_pages_hugetlb(pte_t *pte, unsigned long hmask, /* With MPOL_MF_MOVE, we migrate only unshared hugepage. */ if (flags & (MPOL_MF_MOVE_ALL) || (flags & MPOL_MF_MOVE && page_mapcount(page) == 1)) { - if (!isolate_huge_page(page, qp->pagelist) && + if (isolate_hugetlb(page, qp->pagelist) && (flags & MPOL_MF_STRICT)) /* * Failed to isolate page but allow migrating pages diff --git a/mm/migrate.c b/mm/migrate.c index 6c1ea61f39d8..29b9faed4136 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -133,7 +133,7 @@ static void putback_movable_page(struct page *page) * * This function shall be used whenever the isolated pageset has been * built from lru, balloon, hugetlbfs page. See isolate_migratepages_range() - * and isolate_huge_page(). + * and isolate_hugetlb(). */ void putback_movable_pages(struct list_head *l) { @@ -1633,8 +1633,9 @@ static int add_page_for_migration(struct mm_struct *mm, unsigned long addr,
if (PageHuge(page)) { if (PageHead(page)) { - isolate_huge_page(page, pagelist); - err = 1; + err = isolate_hugetlb(page, pagelist); + if (!err) + err = 1; } } else { struct page *head;
From: Miaohe Lin linmiaohe@huawei.com
[ Upstream commit ad1ac596e8a8c4b06715dfbd89853eb73c9886b2 ]
__migration_entry_wait and migration_entry_wait_on_locked assume pte is always mapped from caller. But this is not the case when it's called from migration_entry_wait_huge and follow_huge_pmd. Add a hugetlbfs variant that calls hugetlb_migration_entry_wait(ptep == NULL) to fix this issue.
Link: https://lkml.kernel.org/r/20220530113016.16663-5-linmiaohe@huawei.com Fixes: 30dad30922cc ("mm: migration: add migrate_entry_wait_huge()") Signed-off-by: Miaohe Lin linmiaohe@huawei.com Suggested-by: David Hildenbrand david@redhat.com Reviewed-by: David Hildenbrand david@redhat.com Cc: Alistair Popple apopple@nvidia.com Cc: Christoph Hellwig hch@lst.de Cc: Christoph Lameter cl@linux.com Cc: David Howells dhowells@redhat.com Cc: Huang Ying ying.huang@intel.com Cc: kernel test robot lkp@intel.com Cc: Mike Kravetz mike.kravetz@oracle.com Cc: Muchun Song songmuchun@bytedance.com Cc: Oscar Salvador osalvador@suse.de Cc: Peter Xu peterx@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/swapops.h | 12 ++++++++---- mm/hugetlb.c | 4 ++-- mm/migrate.c | 23 +++++++++++++++++++---- 3 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/include/linux/swapops.h b/include/linux/swapops.h index f24775b41880..bb7afd03a324 100644 --- a/include/linux/swapops.h +++ b/include/linux/swapops.h @@ -244,8 +244,10 @@ extern void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep, spinlock_t *ptl); extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, unsigned long address); -extern void migration_entry_wait_huge(struct vm_area_struct *vma, - struct mm_struct *mm, pte_t *pte); +#ifdef CONFIG_HUGETLB_PAGE +extern void __migration_entry_wait_huge(pte_t *ptep, spinlock_t *ptl); +extern void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte); +#endif #else static inline swp_entry_t make_readable_migration_entry(pgoff_t offset) { @@ -271,8 +273,10 @@ static inline void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep, spinlock_t *ptl) { } static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, unsigned long address) { } -static inline void migration_entry_wait_huge(struct vm_area_struct *vma, - struct mm_struct *mm, pte_t *pte) { } +#ifdef CONFIG_HUGETLB_PAGE +static inline void __migration_entry_wait_huge(pte_t *ptep, spinlock_t *ptl) { } +static inline void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte) { } +#endif static inline int is_writable_migration_entry(swp_entry_t entry) { return 0; diff --git a/mm/hugetlb.c b/mm/hugetlb.c index b7f007399be2..474bfbe9929e 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -5707,7 +5707,7 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, */ entry = huge_ptep_get(ptep); if (unlikely(is_hugetlb_entry_migration(entry))) { - migration_entry_wait_huge(vma, mm, ptep); + migration_entry_wait_huge(vma, ptep); return 0; } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) return VM_FAULT_HWPOISON_LARGE | @@ -6933,7 +6933,7 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, } else { if (is_hugetlb_entry_migration(pte)) { spin_unlock(ptl); - __migration_entry_wait(mm, (pte_t *)pmd, ptl); + __migration_entry_wait_huge((pte_t *)pmd, ptl); goto retry; } /* diff --git a/mm/migrate.c b/mm/migrate.c index 29b9faed4136..a480f54016b3 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -315,13 +315,28 @@ void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, __migration_entry_wait(mm, ptep, ptl); }
-void migration_entry_wait_huge(struct vm_area_struct *vma, - struct mm_struct *mm, pte_t *pte) +#ifdef CONFIG_HUGETLB_PAGE +void __migration_entry_wait_huge(pte_t *ptep, spinlock_t *ptl) { - spinlock_t *ptl = huge_pte_lockptr(hstate_vma(vma), mm, pte); - __migration_entry_wait(mm, pte, ptl); + pte_t pte; + + spin_lock(ptl); + pte = huge_ptep_get(ptep); + + if (unlikely(!is_hugetlb_entry_migration(pte))) + spin_unlock(ptl); + else + migration_entry_wait_on_locked(pte_to_swp_entry(pte), NULL, ptl); }
+void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte) +{ + spinlock_t *ptl = huge_pte_lockptr(hstate_vma(vma), vma->vm_mm, pte); + + __migration_entry_wait_huge(pte, ptl); +} +#endif + #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd) {
From: Andrey Konovalov andreyknvl@google.com
[ Upstream commit 6c2f761dad7851d8088b91063ccaea3c970efe78 ]
HW_TAGS KASAN skips zeroing page_alloc allocations backing vmalloc mappings via __GFP_SKIP_ZERO. Instead, these pages are zeroed via kasan_unpoison_vmalloc() by passing the KASAN_VMALLOC_INIT flag.
The problem is that __kasan_unpoison_vmalloc() does not zero pages when either kasan_vmalloc_enabled() or is_vmalloc_or_module_addr() fail.
Thus:
1. Change __vmalloc_node_range() to only set KASAN_VMALLOC_INIT when __GFP_SKIP_ZERO is set.
2. Change __kasan_unpoison_vmalloc() to always zero pages when the KASAN_VMALLOC_INIT flag is set.
3. Add WARN_ON() asserts to check that KASAN_VMALLOC_INIT cannot be set in other early return paths of __kasan_unpoison_vmalloc().
Also clean up the comment in __kasan_unpoison_vmalloc.
Link: https://lkml.kernel.org/r/4bc503537efdc539ffc3f461c1b70162eea31cf6.165479851... Fixes: 23689e91fb22 ("kasan, vmalloc: add vmalloc tagging for HW_TAGS") Signed-off-by: Andrey Konovalov andreyknvl@google.com Cc: Marco Elver elver@google.com Cc: Alexander Potapenko glider@google.com Cc: Dmitry Vyukov dvyukov@google.com Cc: Andrey Ryabinin ryabinin.a.a@gmail.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/kasan/hw_tags.c | 32 +++++++++++++++++++++++--------- mm/vmalloc.c | 10 +++++----- 2 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c index 9e1b6544bfa8..9ad8eff71b28 100644 --- a/mm/kasan/hw_tags.c +++ b/mm/kasan/hw_tags.c @@ -257,27 +257,37 @@ static void unpoison_vmalloc_pages(const void *addr, u8 tag) } }
+static void init_vmalloc_pages(const void *start, unsigned long size) +{ + const void *addr; + + for (addr = start; addr < start + size; addr += PAGE_SIZE) { + struct page *page = virt_to_page(addr); + + clear_highpage_kasan_tagged(page); + } +} + void *__kasan_unpoison_vmalloc(const void *start, unsigned long size, kasan_vmalloc_flags_t flags) { u8 tag; unsigned long redzone_start, redzone_size;
- if (!kasan_vmalloc_enabled()) - return (void *)start; - - if (!is_vmalloc_or_module_addr(start)) + if (!kasan_vmalloc_enabled() || !is_vmalloc_or_module_addr(start)) { + if (flags & KASAN_VMALLOC_INIT) + init_vmalloc_pages(start, size); return (void *)start; + }
/* - * Skip unpoisoning and assigning a pointer tag for non-VM_ALLOC - * mappings as: + * Don't tag non-VM_ALLOC mappings, as: * * 1. Unlike the software KASAN modes, hardware tag-based KASAN only * supports tagging physical memory. Therefore, it can only tag a * single mapping of normal physical pages. * 2. Hardware tag-based KASAN can only tag memory mapped with special - * mapping protection bits, see arch_vmalloc_pgprot_modify(). + * mapping protection bits, see arch_vmap_pgprot_tagged(). * As non-VM_ALLOC mappings can be mapped outside of vmalloc code, * providing these bits would require tracking all non-VM_ALLOC * mappers. @@ -289,15 +299,19 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size, * * For non-VM_ALLOC allocations, page_alloc memory is tagged as usual. */ - if (!(flags & KASAN_VMALLOC_VM_ALLOC)) + if (!(flags & KASAN_VMALLOC_VM_ALLOC)) { + WARN_ON(flags & KASAN_VMALLOC_INIT); return (void *)start; + }
/* * Don't tag executable memory. * The kernel doesn't tolerate having the PC register tagged. */ - if (!(flags & KASAN_VMALLOC_PROT_NORMAL)) + if (!(flags & KASAN_VMALLOC_PROT_NORMAL)) { + WARN_ON(flags & KASAN_VMALLOC_INIT); return (void *)start; + }
tag = kasan_random_tag(); start = set_tag(start, tag); diff --git a/mm/vmalloc.c b/mm/vmalloc.c index effd1ff6a4b4..a1ab9b472571 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -3168,15 +3168,15 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
/* * Mark the pages as accessible, now that they are mapped. - * The init condition should match the one in post_alloc_hook() - * (except for the should_skip_init() check) to make sure that memory - * is initialized under the same conditions regardless of the enabled - * KASAN mode. + * The condition for setting KASAN_VMALLOC_INIT should complement the + * one in post_alloc_hook() with regards to the __GFP_SKIP_ZERO check + * to make sure that memory is initialized under the same conditions. * Tag-based KASAN modes only assign tags to normal non-executable * allocations, see __kasan_unpoison_vmalloc(). */ kasan_flags |= KASAN_VMALLOC_VM_ALLOC; - if (!want_init_on_free() && want_init_on_alloc(gfp_mask)) + if (!want_init_on_free() && want_init_on_alloc(gfp_mask) && + (gfp_mask & __GFP_SKIP_ZERO)) kasan_flags |= KASAN_VMALLOC_INIT; /* KASAN_VMALLOC_PROT_NORMAL already set if required. */ area->addr = kasan_unpoison_vmalloc(area->addr, real_size, kasan_flags);
On 15. 08. 22, 20:02, Greg Kroah-Hartman wrote:
From: Andrey Konovalov andreyknvl@google.com
[ Upstream commit 6c2f761dad7851d8088b91063ccaea3c970efe78 ]
HW_TAGS KASAN skips zeroing page_alloc allocations backing vmalloc mappings via __GFP_SKIP_ZERO. Instead, these pages are zeroed via kasan_unpoison_vmalloc() by passing the KASAN_VMALLOC_INIT flag.
The problem is that __kasan_unpoison_vmalloc() does not zero pages when either kasan_vmalloc_enabled() or is_vmalloc_or_module_addr() fail.
Thus:
Change __vmalloc_node_range() to only set KASAN_VMALLOC_INIT when __GFP_SKIP_ZERO is set.
Change __kasan_unpoison_vmalloc() to always zero pages when the KASAN_VMALLOC_INIT flag is set.
Add WARN_ON() asserts to check that KASAN_VMALLOC_INIT cannot be set in other early return paths of __kasan_unpoison_vmalloc().
Also clean up the comment in __kasan_unpoison_vmalloc.
Link: https://lkml.kernel.org/r/4bc503537efdc539ffc3f461c1b70162eea31cf6.165479851... Fixes: 23689e91fb22 ("kasan, vmalloc: add vmalloc tagging for HW_TAGS") Signed-off-by: Andrey Konovalov andreyknvl@google.com Cc: Marco Elver elver@google.com Cc: Alexander Potapenko glider@google.com Cc: Dmitry Vyukov dvyukov@google.com Cc: Andrey Ryabinin ryabinin.a.a@gmail.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org
mm/kasan/hw_tags.c | 32 +++++++++++++++++++++++--------- mm/vmalloc.c | 10 +++++----- 2 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c index 9e1b6544bfa8..9ad8eff71b28 100644 --- a/mm/kasan/hw_tags.c +++ b/mm/kasan/hw_tags.c @@ -257,27 +257,37 @@ static void unpoison_vmalloc_pages(const void *addr, u8 tag) } } +static void init_vmalloc_pages(const void *start, unsigned long size) +{
- const void *addr;
- for (addr = start; addr < start + size; addr += PAGE_SIZE) {
struct page *page = virt_to_page(addr);
clear_highpage_kasan_tagged(page);
This breaks build on aarch64:
mm/kasan/hw_tags.c: In function 'init_vmalloc_pages': mm/kasan/hw_tags.c:267:17: error: implicit declaration of function 'clear_highpage_kasan_tagged' [-Werror=implicit-function-declaration]
- }
+}
- void *__kasan_unpoison_vmalloc(const void *start, unsigned long size, kasan_vmalloc_flags_t flags) { u8 tag; unsigned long redzone_start, redzone_size;
- if (!kasan_vmalloc_enabled())
return (void *)start;
- if (!is_vmalloc_or_module_addr(start))
- if (!kasan_vmalloc_enabled() || !is_vmalloc_or_module_addr(start)) {
if (flags & KASAN_VMALLOC_INIT)
return (void *)start;init_vmalloc_pages(start, size);
- }
/*
* Skip unpoisoning and assigning a pointer tag for non-VM_ALLOC
* mappings as:
* Don't tag non-VM_ALLOC mappings, as:
- Unlike the software KASAN modes, hardware tag-based KASAN only
- supports tagging physical memory. Therefore, it can only tag a
- single mapping of normal physical pages.
- Hardware tag-based KASAN can only tag memory mapped with special
* mapping protection bits, see arch_vmalloc_pgprot_modify().
* mapping protection bits, see arch_vmap_pgprot_tagged().
- As non-VM_ALLOC mappings can be mapped outside of vmalloc code,
- providing these bits would require tracking all non-VM_ALLOC
- mappers.
@@ -289,15 +299,19 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size, * * For non-VM_ALLOC allocations, page_alloc memory is tagged as usual. */
- if (!(flags & KASAN_VMALLOC_VM_ALLOC))
- if (!(flags & KASAN_VMALLOC_VM_ALLOC)) {
return (void *)start;WARN_ON(flags & KASAN_VMALLOC_INIT);
- }
/* * Don't tag executable memory. * The kernel doesn't tolerate having the PC register tagged. */
- if (!(flags & KASAN_VMALLOC_PROT_NORMAL))
- if (!(flags & KASAN_VMALLOC_PROT_NORMAL)) {
return (void *)start;WARN_ON(flags & KASAN_VMALLOC_INIT);
- }
tag = kasan_random_tag(); start = set_tag(start, tag); diff --git a/mm/vmalloc.c b/mm/vmalloc.c index effd1ff6a4b4..a1ab9b472571 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -3168,15 +3168,15 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, /* * Mark the pages as accessible, now that they are mapped.
* The init condition should match the one in post_alloc_hook()
* (except for the should_skip_init() check) to make sure that memory
* is initialized under the same conditions regardless of the enabled
* KASAN mode.
* The condition for setting KASAN_VMALLOC_INIT should complement the
* one in post_alloc_hook() with regards to the __GFP_SKIP_ZERO check
* to make sure that memory is initialized under the same conditions.
*/ kasan_flags |= KASAN_VMALLOC_VM_ALLOC;
- Tag-based KASAN modes only assign tags to normal non-executable
- allocations, see __kasan_unpoison_vmalloc().
- if (!want_init_on_free() && want_init_on_alloc(gfp_mask))
- if (!want_init_on_free() && want_init_on_alloc(gfp_mask) &&
kasan_flags |= KASAN_VMALLOC_INIT; /* KASAN_VMALLOC_PROT_NORMAL already set if required. */ area->addr = kasan_unpoison_vmalloc(area->addr, real_size, kasan_flags);(gfp_mask & __GFP_SKIP_ZERO))
On 16. 08. 22, 13:04, Jiri Slaby wrote:
On 15. 08. 22, 20:02, Greg Kroah-Hartman wrote:
From: Andrey Konovalov andreyknvl@google.com
[ Upstream commit 6c2f761dad7851d8088b91063ccaea3c970efe78 ]
HW_TAGS KASAN skips zeroing page_alloc allocations backing vmalloc mappings via __GFP_SKIP_ZERO. Instead, these pages are zeroed via kasan_unpoison_vmalloc() by passing the KASAN_VMALLOC_INIT flag.
The problem is that __kasan_unpoison_vmalloc() does not zero pages when either kasan_vmalloc_enabled() or is_vmalloc_or_module_addr() fail.
Thus:
- Change __vmalloc_node_range() to only set KASAN_VMALLOC_INIT when
__GFP_SKIP_ZERO is set.
- Change __kasan_unpoison_vmalloc() to always zero pages when the
KASAN_VMALLOC_INIT flag is set.
- Add WARN_ON() asserts to check that KASAN_VMALLOC_INIT cannot be set
in other early return paths of __kasan_unpoison_vmalloc().
Also clean up the comment in __kasan_unpoison_vmalloc.
Link: https://lkml.kernel.org/r/4bc503537efdc539ffc3f461c1b70162eea31cf6.165479851... Fixes: 23689e91fb22 ("kasan, vmalloc: add vmalloc tagging for HW_TAGS") Signed-off-by: Andrey Konovalov andreyknvl@google.com Cc: Marco Elver elver@google.com Cc: Alexander Potapenko glider@google.com Cc: Dmitry Vyukov dvyukov@google.com Cc: Andrey Ryabinin ryabinin.a.a@gmail.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org
mm/kasan/hw_tags.c | 32 +++++++++++++++++++++++--------- mm/vmalloc.c | 10 +++++----- 2 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c index 9e1b6544bfa8..9ad8eff71b28 100644 --- a/mm/kasan/hw_tags.c +++ b/mm/kasan/hw_tags.c @@ -257,27 +257,37 @@ static void unpoison_vmalloc_pages(const void *addr, u8 tag) } } +static void init_vmalloc_pages(const void *start, unsigned long size) +{ + const void *addr;
+ for (addr = start; addr < start + size; addr += PAGE_SIZE) { + struct page *page = virt_to_page(addr);
+ clear_highpage_kasan_tagged(page);
This breaks build on aarch64:
mm/kasan/hw_tags.c: In function 'init_vmalloc_pages': mm/kasan/hw_tags.c:267:17: error: implicit declaration of function 'clear_highpage_kasan_tagged' [-Werror=implicit-function-declaration]
Which translates into: this is missing: commit d9da8f6cf55eeca642c021912af1890002464c64 Author: Andrey Konovalov andreyknvl@gmail.com Date: Thu Jun 9 20:18:46 2022 +0200
mm: introduce clear_highpage_kasan_tagged
+ } +}
void *__kasan_unpoison_vmalloc(const void *start, unsigned long size, kasan_vmalloc_flags_t flags) { u8 tag; unsigned long redzone_start, redzone_size; - if (!kasan_vmalloc_enabled()) - return (void *)start;
- if (!is_vmalloc_or_module_addr(start)) + if (!kasan_vmalloc_enabled() || !is_vmalloc_or_module_addr(start)) { + if (flags & KASAN_VMALLOC_INIT) + init_vmalloc_pages(start, size); return (void *)start; + } /* - * Skip unpoisoning and assigning a pointer tag for non-VM_ALLOC - * mappings as: + * Don't tag non-VM_ALLOC mappings, as: * * 1. Unlike the software KASAN modes, hardware tag-based KASAN only * supports tagging physical memory. Therefore, it can only tag a * single mapping of normal physical pages. * 2. Hardware tag-based KASAN can only tag memory mapped with special - * mapping protection bits, see arch_vmalloc_pgprot_modify(). + * mapping protection bits, see arch_vmap_pgprot_tagged(). * As non-VM_ALLOC mappings can be mapped outside of vmalloc code, * providing these bits would require tracking all non-VM_ALLOC * mappers. @@ -289,15 +299,19 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size, * * For non-VM_ALLOC allocations, page_alloc memory is tagged as usual. */ - if (!(flags & KASAN_VMALLOC_VM_ALLOC)) + if (!(flags & KASAN_VMALLOC_VM_ALLOC)) { + WARN_ON(flags & KASAN_VMALLOC_INIT); return (void *)start; + } /* * Don't tag executable memory. * The kernel doesn't tolerate having the PC register tagged. */ - if (!(flags & KASAN_VMALLOC_PROT_NORMAL)) + if (!(flags & KASAN_VMALLOC_PROT_NORMAL)) { + WARN_ON(flags & KASAN_VMALLOC_INIT); return (void *)start; + } tag = kasan_random_tag(); start = set_tag(start, tag); diff --git a/mm/vmalloc.c b/mm/vmalloc.c index effd1ff6a4b4..a1ab9b472571 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -3168,15 +3168,15 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, /* * Mark the pages as accessible, now that they are mapped. - * The init condition should match the one in post_alloc_hook() - * (except for the should_skip_init() check) to make sure that memory - * is initialized under the same conditions regardless of the enabled - * KASAN mode. + * The condition for setting KASAN_VMALLOC_INIT should complement the + * one in post_alloc_hook() with regards to the __GFP_SKIP_ZERO check + * to make sure that memory is initialized under the same conditions. * Tag-based KASAN modes only assign tags to normal non-executable * allocations, see __kasan_unpoison_vmalloc(). */ kasan_flags |= KASAN_VMALLOC_VM_ALLOC; - if (!want_init_on_free() && want_init_on_alloc(gfp_mask)) + if (!want_init_on_free() && want_init_on_alloc(gfp_mask) && + (gfp_mask & __GFP_SKIP_ZERO)) kasan_flags |= KASAN_VMALLOC_INIT; /* KASAN_VMALLOC_PROT_NORMAL already set if required. */ area->addr = kasan_unpoison_vmalloc(area->addr, real_size, kasan_flags);
On Tue, Aug 16, 2022 at 01:14:13PM +0200, Jiri Slaby wrote:
On 16. 08. 22, 13:04, Jiri Slaby wrote:
On 15. 08. 22, 20:02, Greg Kroah-Hartman wrote:
From: Andrey Konovalov andreyknvl@google.com
[ Upstream commit 6c2f761dad7851d8088b91063ccaea3c970efe78 ]
HW_TAGS KASAN skips zeroing page_alloc allocations backing vmalloc mappings via __GFP_SKIP_ZERO. Instead, these pages are zeroed via kasan_unpoison_vmalloc() by passing the KASAN_VMALLOC_INIT flag.
The problem is that __kasan_unpoison_vmalloc() does not zero pages when either kasan_vmalloc_enabled() or is_vmalloc_or_module_addr() fail.
Thus:
- Change __vmalloc_node_range() to only set KASAN_VMALLOC_INIT when
__GFP_SKIP_ZERO is set.
- Change __kasan_unpoison_vmalloc() to always zero pages when the
KASAN_VMALLOC_INIT flag is set.
- Add WARN_ON() asserts to check that KASAN_VMALLOC_INIT cannot be set
in other early return paths of __kasan_unpoison_vmalloc().
Also clean up the comment in __kasan_unpoison_vmalloc.
Link: https://lkml.kernel.org/r/4bc503537efdc539ffc3f461c1b70162eea31cf6.165479851... Fixes: 23689e91fb22 ("kasan, vmalloc: add vmalloc tagging for HW_TAGS") Signed-off-by: Andrey Konovalov andreyknvl@google.com Cc: Marco Elver elver@google.com Cc: Alexander Potapenko glider@google.com Cc: Dmitry Vyukov dvyukov@google.com Cc: Andrey Ryabinin ryabinin.a.a@gmail.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org
mm/kasan/hw_tags.c | 32 +++++++++++++++++++++++--------- mm/vmalloc.c | 10 +++++----- 2 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c index 9e1b6544bfa8..9ad8eff71b28 100644 --- a/mm/kasan/hw_tags.c +++ b/mm/kasan/hw_tags.c @@ -257,27 +257,37 @@ static void unpoison_vmalloc_pages(const void *addr, u8 tag) } } +static void init_vmalloc_pages(const void *start, unsigned long size) +{ + const void *addr;
+ for (addr = start; addr < start + size; addr += PAGE_SIZE) { + struct page *page = virt_to_page(addr);
+ clear_highpage_kasan_tagged(page);
This breaks build on aarch64:
mm/kasan/hw_tags.c: In function 'init_vmalloc_pages': mm/kasan/hw_tags.c:267:17: error: implicit declaration of function 'clear_highpage_kasan_tagged' [-Werror=implicit-function-declaration]
Which translates into: this is missing: commit d9da8f6cf55eeca642c021912af1890002464c64 Author: Andrey Konovalov andreyknvl@gmail.com Date: Thu Jun 9 20:18:46 2022 +0200
mm: introduce clear_highpage_kasan_tagged
Thanks, now added to both 5.18.y and 5.19.y. I'll push out some -rc2 releases with this in it so it can get some testing.
greg k-h
From: Tianyu Li tianyu.li@arm.com
[ Upstream commit 000eca5d044d1ee23b4ca311793cf3fc528da6c6 ]
When user specified more nodes than supported, get_nodes will access nmask array out of bounds.
Link: https://lkml.kernel.org/r/20220601093211.2970565-1-tianyu.li@arm.com Fixes: e130242dc351 ("mm: simplify compat numa syscalls") Signed-off-by: Tianyu Li tianyu.li@arm.com Cc: Arnd Bergmann arnd@arndb.de Cc: Mark Rutland mark.rutland@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/mempolicy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 9689919a2829..f4cd963550c1 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1388,7 +1388,7 @@ static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask, unsigned long bits = min_t(unsigned long, maxnode, BITS_PER_LONG); unsigned long t;
- if (get_bitmap(&t, &nmask[maxnode / BITS_PER_LONG], bits)) + if (get_bitmap(&t, &nmask[(maxnode - 1) / BITS_PER_LONG], bits)) return -EFAULT;
if (maxnode - bits >= MAX_NUMNODES) {
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit d4a0a189b72a7c98e4256292b18b67c69fbc9343 ]
On some platforms, like Intel Merrifield, the writing values during power on may timeout:
tusb1210 dwc3.0.auto.ulpi: error -110 writing val 0x41 to reg 0x80 phy phy-dwc3.0.auto.ulpi.0: phy poweron failed --> -110 dwc3 dwc3.0.auto: error -ETIMEDOUT: failed to initialize core dwc3: probe of dwc3.0.auto failed with error -110
which effectively fails the probe of the USB controller. Drop the check as it was before the culprit commit (see Fixes tag).
Fixes: 09a3512681b3 ("phy: ti: tusb1210: Improve ulpi_read()/_write() error checking") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Hans de Goede hdegoede@redhat.com Tested-by: Ferry Toth fntoth@gmail.com Link: https://lore.kernel.org/r/20220613160848.82746-1-andriy.shevchenko@linux.int... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/ti/phy-tusb1210.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c index c3ab4b69ea68..669c13d6e402 100644 --- a/drivers/phy/ti/phy-tusb1210.c +++ b/drivers/phy/ti/phy-tusb1210.c @@ -105,8 +105,9 @@ static int tusb1210_power_on(struct phy *phy) msleep(TUSB1210_RESET_TIME_MS);
/* Restore the optional eye diagram optimization value */ - return tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, - tusb->vendor_specific2); + tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, tusb->vendor_specific2); + + return 0; }
static int tusb1210_power_off(struct phy *phy)
From: Peter Geis pgwipeout@gmail.com
[ Upstream commit 8dc60f8da22fdbaa1fafcfb5ff6d24bc9eff56aa ]
The initial otg state for the phy defaults to device mode. The actual state isn't detected until an ID IRQ fires. Fix this by syncing the ID state during initialization.
Fixes: 51a9b2c03dd3 ("phy: rockchip-inno-usb2: Handle ID IRQ") Signed-off-by: Peter Geis pgwipeout@gmail.com Reviewed-by: Samuel Holland samuel@sholland.org Link: https://lore.kernel.org/r/20220622003140.30365-1-pgwipeout@gmail.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 6711659f727c..6e44069617df 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -1162,6 +1162,12 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy, EXTCON_USB_HOST, &rport->event_nb); if (ret) dev_err(rphy->dev, "register USB HOST notifier failed\n"); + + if (!of_property_read_bool(rphy->dev->of_node, "extcon")) { + /* do initial sync of usb state */ + ret = property_enabled(rphy->grf, &rport->port_cfg->utmi_id); + extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !ret); + } }
out:
From: Serge Semin Sergey.Semin@baikalelectronics.ru
[ Upstream commit 113fa857b74c947137d845e7e635afcf6a59c43a ]
It's logically correct to undo everything that was done when an error is discovered or in the corresponding cleanup counterpart. Otherwise the host controller will be left in an undetermined state. Since the link is set up in the host_init method, deactivate it there in the cleanup-on-error block and stop the link in the antagonistic routine - dw_pcie_host_deinit(). Link deactivation is platform-specific and should be implemented in dw_pcie_ops.stop_link().
Fixes: 886a9c134755 ("PCI: dwc: Move link handling into common code") Link: https://lore.kernel.org/r/20220624143428.8334-2-Sergey.Semin@baikalelectroni... Tested-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Serge Semin Sergey.Semin@baikalelectronics.ru Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../pci/controller/dwc/pcie-designware-host.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 9979302532b7..bc9a7df130ef 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -421,8 +421,14 @@ int dw_pcie_host_init(struct pcie_port *pp) bridge->sysdata = pp;
ret = pci_host_probe(bridge); - if (!ret) - return 0; + if (ret) + goto err_stop_link; + + return 0; + +err_stop_link: + if (pci->ops && pci->ops->stop_link) + pci->ops->stop_link(pci);
err_free_msi: if (pp->has_msi_ctrl) @@ -433,8 +439,14 @@ EXPORT_SYMBOL_GPL(dw_pcie_host_init);
void dw_pcie_host_deinit(struct pcie_port *pp) { + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + pci_stop_root_bus(pp->bridge->bus); pci_remove_root_bus(pp->bridge->bus); + + if (pci->ops && pci->ops->stop_link) + pci->ops->stop_link(pci); + if (pp->has_msi_ctrl) dw_pcie_free_msi(pp); }
From: Serge Semin Sergey.Semin@baikalelectronics.ru
[ Upstream commit d1cf738f2b65a5640234e1da90a68d3523fbed83 ]
dw_pcie_disable_atu() was introduced by f8aed6ec624f ("PCI: dwc: designware: Add EP mode support") and supported only the viewport version of the iATU CSRs.
DW PCIe IP cores v4.80a and newer also support unrolled iATU/eDMA space. Callers of dw_pcie_disable_atu(), including pci_epc_ops.clear_bar(), pci_epc_ops.unmap_addr(), and dw_pcie_setup_rc(), don't work correctly when it is enabled.
Add dw_pcie_disable_atu() support for controllers with unrolled iATU CSRs enabled.
[bhelgaas: commit log] Fixes: f8aed6ec624f ("PCI: dwc: designware: Add EP mode support") Link: https://lore.kernel.org/r/20220624143428.8334-3-Sergey.Semin@baikalelectroni... Tested-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Serge Semin Sergey.Semin@baikalelectronics.ru Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-designware.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index d92c8a25094f..84fef21efdbc 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -491,7 +491,7 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index, void dw_pcie_disable_atu(struct dw_pcie *pci, int index, enum dw_pcie_region_type type) { - int region; + u32 region;
switch (type) { case DW_PCIE_REGION_INBOUND: @@ -504,8 +504,18 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, int index, return; }
- dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index); - dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, ~(u32)PCIE_ATU_ENABLE); + if (pci->iatu_unroll_enabled) { + if (region == PCIE_ATU_REGION_INBOUND) { + dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2, + ~(u32)PCIE_ATU_ENABLE); + } else { + dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2, + ~(u32)PCIE_ATU_ENABLE); + } + } else { + dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index); + dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, ~(u32)PCIE_ATU_ENABLE); + } }
int dw_pcie_wait_for_link(struct dw_pcie *pci)
From: Serge Semin Sergey.Semin@baikalelectronics.ru
[ Upstream commit d60a2e281e9de2b2f67343b2e39417ca0f4fd54e ]
Some DWC-based controllers (e.g., pcie-al.c and pci-keystone.c, identified by the fact that they override the default dw_child_pcie_ops) use their own address translation approach instead of the DWC internal ATU (iATU). For those controllers, skip disabling the iATU outbound windows.
[bhelgaas: commit log, update multiple window comment] Fixes: 458ad06c4cdd ("PCI: dwc: Ensure all outbound ATU windows are reset") Link: https://lore.kernel.org/r/20220624143428.8334-4-Sergey.Semin@baikalelectroni... Tested-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Serge Semin Sergey.Semin@baikalelectronics.ru Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-designware-host.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index bc9a7df130ef..d0d768f22ac3 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -543,7 +543,6 @@ static struct pci_ops dw_pcie_ops = {
void dw_pcie_setup_rc(struct pcie_port *pp) { - int i; u32 val, ctrl, num_ctrls; struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -594,19 +593,22 @@ void dw_pcie_setup_rc(struct pcie_port *pp) PCI_COMMAND_MASTER | PCI_COMMAND_SERR; dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
- /* Ensure all outbound windows are disabled so there are multiple matches */ - for (i = 0; i < pci->num_ob_windows; i++) - dw_pcie_disable_atu(pci, i, DW_PCIE_REGION_OUTBOUND); - /* * If the platform provides its own child bus config accesses, it means * the platform uses its own address translation component rather than * ATU, so we should not program the ATU here. */ if (pp->bridge->child_ops == &dw_child_pcie_ops) { - int atu_idx = 0; + int i, atu_idx = 0; struct resource_entry *entry;
+ /* + * Disable all outbound windows to make sure a transaction + * can't match multiple windows. + */ + for (i = 0; i < pci->num_ob_windows; i++) + dw_pcie_disable_atu(pci, i, DW_PCIE_REGION_OUTBOUND); + /* Get last memory resource entry */ resource_list_for_each_entry(entry, &pp->bridge->windows) { if (resource_type(entry->res) != IORESOURCE_MEM)
From: Serge Semin Sergey.Semin@baikalelectronics.ru
[ Upstream commit 777e7c3ab73036105e6fc4a67ed950179dbffbab ]
We program the 64-bit ATU limit address (in PCIE_ATU_LIMIT/ PCIE_ATU_UPPER_LIMIT or PCIE_ATU_UNR_LOWER_LIMIT/PCIE_ATU_UNR_UPPER_LIMIT), but in addition, the PCIE_ATU_INCREASE_REGION_SIZE bit must be set if the upper 32 bits of the limit address differ from the upper 32 bits of the base address (see [1,2]).
5b4cf0f65324 ("PCI: dwc: Add upper limit address for outbound iATU") set PCIE_ATU_INCREASE_REGION_SIZE, but only when the *size* was greater than 4GB. It did not set it when a smaller region crossed a 4GB boundary, e.g., [mem 0x0_f0000000-0x1_0fffffff].
Set PCIE_ATU_INCREASE_REGION_SIZE whenever PCIE_ATU_UPPER_LIMIT is greater than PCIE_ATU_UPPER_BASE.
[1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, v5.40a, March 2019, fig.3-36, p.175 [2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, v5.40a, March 2019, fig.3-37, p.176
[bhelgaas: commit log] Fixes: 5b4cf0f65324 ("PCI: dwc: Add upper limit address for outbound iATU") Link: https://lore.kernel.org/r/20220624143428.8334-5-Sergey.Semin@baikalelectroni... Tested-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Serge Semin Sergey.Semin@baikalelectronics.ru Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-designware.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 84fef21efdbc..347251bf87d0 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -287,8 +287,8 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8 func_no, dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET, upper_32_bits(pci_addr)); val = type | PCIE_ATU_FUNC_NUM(func_no); - val = upper_32_bits(size - 1) ? - val | PCIE_ATU_INCREASE_REGION_SIZE : val; + if (upper_32_bits(limit_addr) > upper_32_bits(cpu_addr)) + val |= PCIE_ATU_INCREASE_REGION_SIZE; if (pci->version == 0x490A) val = dw_pcie_enable_ecrc(val); dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, val); @@ -315,6 +315,7 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no, u64 pci_addr, u64 size) { u32 retries, val; + u64 limit_addr;
if (pci->ops && pci->ops->cpu_addr_fixup) cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr); @@ -325,6 +326,8 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no, return; }
+ limit_addr = cpu_addr + size - 1; + dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, PCIE_ATU_REGION_OUTBOUND | index); dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_BASE, @@ -332,17 +335,18 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no, dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_BASE, upper_32_bits(cpu_addr)); dw_pcie_writel_dbi(pci, PCIE_ATU_LIMIT, - lower_32_bits(cpu_addr + size - 1)); + lower_32_bits(limit_addr)); if (pci->version >= 0x460A) dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_LIMIT, - upper_32_bits(cpu_addr + size - 1)); + upper_32_bits(limit_addr)); dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET, lower_32_bits(pci_addr)); dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET, upper_32_bits(pci_addr)); val = type | PCIE_ATU_FUNC_NUM(func_no); - val = ((upper_32_bits(size - 1)) && (pci->version >= 0x460A)) ? - val | PCIE_ATU_INCREASE_REGION_SIZE : val; + if (upper_32_bits(limit_addr) > upper_32_bits(cpu_addr) && + pci->version >= 0x460A) + val |= PCIE_ATU_INCREASE_REGION_SIZE; if (pci->version == 0x490A) val = dw_pcie_enable_ecrc(val); dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, val);
From: Serge Semin Sergey.Semin@baikalelectronics.ru
[ Upstream commit 8161e9626b50892eaedbd8070ecb1586ecedb109 ]
If dw_pcie_ep_init() fails to perform any action after the EPC memory is initialized and the MSI memory region is allocated, the latter parts won't be undone thus causing a memory leak. Add a cleanup-on-error path to fix these leaks.
[bhelgaas: commit log] Fixes: 2fd0c9d966cc ("PCI: designware-ep: Pre-allocate memory for MSI in dw_pcie_ep_init") Link: https://lore.kernel.org/r/20220624143428.8334-6-Sergey.Semin@baikalelectroni... Tested-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Serge Semin Sergey.Semin@baikalelectronics.ru Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Rob Herring robh@kernel.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../pci/controller/dwc/pcie-designware-ep.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 0eda8236c125..13c2e73f0eaf 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -780,8 +780,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys, epc->mem->window.page_size); if (!ep->msi_mem) { + ret = -ENOMEM; dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n"); - return -ENOMEM; + goto err_exit_epc_mem; }
if (ep->ops->get_features) { @@ -790,6 +791,19 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) return 0; }
- return dw_pcie_ep_init_complete(ep); + ret = dw_pcie_ep_init_complete(ep); + if (ret) + goto err_free_epc_mem; + + return 0; + +err_free_epc_mem: + pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, + epc->mem->window.page_size); + +err_exit_epc_mem: + pci_epc_mem_exit(epc); + + return ret; } EXPORT_SYMBOL_GPL(dw_pcie_ep_init);
From: Serge Semin Sergey.Semin@baikalelectronics.ru
[ Upstream commit ec7b952f453ce7eabe7e1bea584626934d44f668 ]
If the "snps,enable-cdm-check" property exists, we should enable the CDM check. But previously dw_pcie_setup() could exit before doing so if the "num-lanes" property was absent or invalid.
Move the CDM enable earlier so we do it regardless of whether "num-lanes" is present.
[bhelgaas: commit log] Fixes: 07f123def73e ("PCI: dwc: Add support to enable CDM register check") Link: https://lore.kernel.org/r/20220624143428.8334-7-Sergey.Semin@baikalelectroni... Signed-off-by: Serge Semin Sergey.Semin@baikalelectronics.ru Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Vidya Sagar vidyas@nvidia.com Reviewed-by: Rob Herring robh@kernel.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-designware.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 347251bf87d0..5848cc520b52 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -740,6 +740,13 @@ void dw_pcie_setup(struct dw_pcie *pci) val |= PORT_LINK_DLL_LINK_EN; dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
+ if (of_property_read_bool(np, "snps,enable-cdm-check")) { + val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS); + val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS | + PCIE_PL_CHK_REG_CHK_REG_START; + dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val); + } + of_property_read_u32(np, "num-lanes", &pci->num_lanes); if (!pci->num_lanes) { dev_dbg(pci->dev, "Using h/w default number of lanes\n"); @@ -786,11 +793,4 @@ void dw_pcie_setup(struct dw_pcie *pci) break; } dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val); - - if (of_property_read_bool(np, "snps,enable-cdm-check")) { - val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS); - val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS | - PCIE_PL_CHK_REG_CHK_REG_START; - dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val); - } }
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit df6407782964dc7e35ad84230abb38f46314b245 ]
The bus sdw_drv_remove() and sdw_drv_shutdown() helpers are used conditionally, if the driver provides these routines.
These helpers already test if the driver provides a .remove or .shutdown callback, so there's no harm in invoking the sdw_drv_remove() and sdw_drv_shutdown() unconditionally.
In addition, the current code is imbalanced with dev_pm_domain_attach() called from sdw_drv_probe(), but dev_pm_domain_detach() called from sdw_drv_remove() only if the driver provides a .remove callback.
Fixes: 9251345dca24b ("soundwire: Add SoundWire bus type") Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Rander Wang rander.wang@intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Link: https://lore.kernel.org/r/20220610015105.25987-1-yung-chuan.liao@linux.intel... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soundwire/bus_type.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c index 893296f3fe39..b81e04dd3a9f 100644 --- a/drivers/soundwire/bus_type.c +++ b/drivers/soundwire/bus_type.c @@ -193,12 +193,8 @@ int __sdw_register_driver(struct sdw_driver *drv, struct module *owner)
drv->driver.owner = owner; drv->driver.probe = sdw_drv_probe; - - if (drv->remove) - drv->driver.remove = sdw_drv_remove; - - if (drv->shutdown) - drv->driver.shutdown = sdw_drv_shutdown; + drv->driver.remove = sdw_drv_remove; + drv->driver.shutdown = sdw_drv_shutdown;
return driver_register(&drv->driver); }
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit bd29c00edd0a5dac8b6e7332bb470cd50f92e893 ]
In the SoundWire probe, we store a pointer from the driver ops into the 'slave' structure. This can lead to kernel oopses when unbinding codec drivers, e.g. with the following sequence to remove machine driver and codec driver.
/sbin/modprobe -r snd_soc_sof_sdw /sbin/modprobe -r snd_soc_rt711
The full details can be found in the BugLink below, for reference the two following examples show different cases of driver ops/callbacks being invoked after the driver .remove().
kernel: BUG: kernel NULL pointer dereference, address: 0000000000000150 kernel: Workqueue: events cdns_update_slave_status_work [soundwire_cadence] kernel: RIP: 0010:mutex_lock+0x19/0x30 kernel: Call Trace: kernel: ? sdw_handle_slave_status+0x426/0xe00 [soundwire_bus 94ff184bf398570c3f8ff7efe9e32529f532e4ae] kernel: ? newidle_balance+0x26a/0x400 kernel: ? cdns_update_slave_status_work+0x1e9/0x200 [soundwire_cadence 1bcf98eebe5ba9833cd433323769ac923c9c6f82]
kernel: BUG: unable to handle page fault for address: ffffffffc07654c8 kernel: Workqueue: pm pm_runtime_work kernel: RIP: 0010:sdw_bus_prep_clk_stop+0x6f/0x160 [soundwire_bus] kernel: Call Trace: kernel: <TASK> kernel: sdw_cdns_clock_stop+0xb5/0x1b0 [soundwire_cadence 1bcf98eebe5ba9833cd433323769ac923c9c6f82] kernel: intel_suspend_runtime+0x5f/0x120 [soundwire_intel aca858f7c87048d3152a4a41bb68abb9b663a1dd] kernel: ? dpm_sysfs_remove+0x60/0x60
This was not detected earlier in Intel tests since the tests first remove the parent PCI device and shut down the bus. The sequence above is a corner case which keeps the bus operational but without a driver bound.
While trying to solve this kernel oopses, it became clear that the existing SoundWire bus does not deal well with the unbind case.
Commit 528be501b7d4a ("soundwire: sdw_slave: add probe_complete structure and new fields") added a 'probed' status variable and a 'probe_complete' struct completion. This status is however not reset on remove and likewise the 'probe complete' is not re-initialized, so the bind/unbind/bind test cases would fail. The timeout used before the 'update_status' callback was also a bad idea in hindsight, there should really be no timing assumption as to if and when a driver is bound to a device.
An initial draft was based on device_lock() and device_unlock() was tested. This proved too complicated, with deadlocks created during the suspend-resume sequences, which also use the same device_lock/unlock() as the bind/unbind sequences. On a CometLake device, a bad DSDT/BIOS caused spurious resumes and the use of device_lock() caused hangs during suspend. After multiple weeks or testing and painful reverse-engineering of deadlocks on different devices, we looked for alternatives that did not interfere with the device core.
A bus notifier was used successfully to keep track of DRIVER_BOUND and DRIVER_UNBIND events. This solved the bind-unbind-bind case in tests, but it can still be defeated with a theoretical corner case where the memory is freed by a .remove while the callback is in use. The notifier only helps make sure the driver callbacks are valid, but not that the memory allocated in probe remains valid while the callbacks are invoked.
This patch suggests the introduction of a new 'sdw_dev_lock' mutex protecting probe/remove and all driver callbacks. Since this mutex is 'local' to SoundWire only, it does not interfere with existing locks and does not create deadlocks. In addition, this patch removes the 'probe_complete' completion, instead we directly invoke the 'update_status' from the probe routine. That removes any sort of timing dependency and a much better support for the device/driver model, the driver could be bound before the bus started, or eons after the bus started and the hardware would be properly initialized in all cases.
BugLink: https://github.com/thesofproject/linux/issues/3531 Fixes: 56d4fe31af77 ("soundwire: Add MIPI DisCo property helpers") Fixes: 528be501b7d4a ("soundwire: sdw_slave: add probe_complete structure and new fields") Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Rander Wang rander.wang@intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com Link: https://lore.kernel.org/r/20220621225641.221170-2-pierre-louis.bossart@linux... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soundwire/bus.c | 75 ++++++++++++++++++++--------------- drivers/soundwire/bus_type.c | 30 +++++++++++--- drivers/soundwire/slave.c | 3 +- drivers/soundwire/stream.c | 53 ++++++++++++++++--------- include/linux/soundwire/sdw.h | 6 +-- 5 files changed, 106 insertions(+), 61 deletions(-)
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c index a2bfb0434a67..8d4000664fa3 100644 --- a/drivers/soundwire/bus.c +++ b/drivers/soundwire/bus.c @@ -7,6 +7,7 @@ #include <linux/pm_runtime.h> #include <linux/soundwire/sdw_registers.h> #include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_type.h> #include "bus.h" #include "sysfs_local.h"
@@ -842,15 +843,21 @@ static int sdw_slave_clk_stop_callback(struct sdw_slave *slave, enum sdw_clk_stop_mode mode, enum sdw_clk_stop_type type) { - int ret; + int ret = 0;
- if (slave->ops && slave->ops->clk_stop) { - ret = slave->ops->clk_stop(slave, mode, type); - if (ret < 0) - return ret; + mutex_lock(&slave->sdw_dev_lock); + + if (slave->probed) { + struct device *dev = &slave->dev; + struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); + + if (drv->ops && drv->ops->clk_stop) + ret = drv->ops->clk_stop(slave, mode, type); }
- return 0; + mutex_unlock(&slave->sdw_dev_lock); + + return ret; }
static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave, @@ -1611,14 +1618,24 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave) }
/* Update the Slave driver */ - if (slave_notify && slave->ops && - slave->ops->interrupt_callback) { - slave_intr.sdca_cascade = sdca_cascade; - slave_intr.control_port = clear; - memcpy(slave_intr.port, &port_status, - sizeof(slave_intr.port)); - - slave->ops->interrupt_callback(slave, &slave_intr); + if (slave_notify) { + mutex_lock(&slave->sdw_dev_lock); + + if (slave->probed) { + struct device *dev = &slave->dev; + struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); + + if (drv->ops && drv->ops->interrupt_callback) { + slave_intr.sdca_cascade = sdca_cascade; + slave_intr.control_port = clear; + memcpy(slave_intr.port, &port_status, + sizeof(slave_intr.port)); + + drv->ops->interrupt_callback(slave, &slave_intr); + } + } + + mutex_unlock(&slave->sdw_dev_lock); }
/* Ack interrupt */ @@ -1692,29 +1709,21 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave) static int sdw_update_slave_status(struct sdw_slave *slave, enum sdw_slave_status status) { - unsigned long time; + int ret = 0;
- if (!slave->probed) { - /* - * the slave status update is typically handled in an - * interrupt thread, which can race with the driver - * probe, e.g. when a module needs to be loaded. - * - * make sure the probe is complete before updating - * status. - */ - time = wait_for_completion_timeout(&slave->probe_complete, - msecs_to_jiffies(DEFAULT_PROBE_TIMEOUT)); - if (!time) { - dev_err(&slave->dev, "Probe not complete, timed out\n"); - return -ETIMEDOUT; - } + mutex_lock(&slave->sdw_dev_lock); + + if (slave->probed) { + struct device *dev = &slave->dev; + struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); + + if (drv->ops && drv->ops->update_status) + ret = drv->ops->update_status(slave, status); }
- if (!slave->ops || !slave->ops->update_status) - return 0; + mutex_unlock(&slave->sdw_dev_lock);
- return slave->ops->update_status(slave, status); + return ret; }
/** diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c index b81e04dd3a9f..04b3529f8929 100644 --- a/drivers/soundwire/bus_type.c +++ b/drivers/soundwire/bus_type.c @@ -98,8 +98,6 @@ static int sdw_drv_probe(struct device *dev) if (!id) return -ENODEV;
- slave->ops = drv->ops; - /* * attach to power domain but don't turn on (last arg) */ @@ -107,19 +105,23 @@ static int sdw_drv_probe(struct device *dev) if (ret) return ret;
+ mutex_lock(&slave->sdw_dev_lock); + ret = drv->probe(slave, id); if (ret) { name = drv->name; if (!name) name = drv->driver.name; + mutex_unlock(&slave->sdw_dev_lock); + dev_err(dev, "Probe of %s failed: %d\n", name, ret); dev_pm_domain_detach(dev, false); return ret; }
/* device is probed so let's read the properties now */ - if (slave->ops && slave->ops->read_prop) - slave->ops->read_prop(slave); + if (drv->ops && drv->ops->read_prop) + drv->ops->read_prop(slave);
/* init the sysfs as we have properties now */ ret = sdw_slave_sysfs_init(slave); @@ -139,7 +141,19 @@ static int sdw_drv_probe(struct device *dev) slave->prop.clk_stop_timeout);
slave->probed = true; - complete(&slave->probe_complete); + + /* + * if the probe happened after the bus was started, notify the codec driver + * of the current hardware status to e.g. start the initialization. + * Errors are only logged as warnings to avoid failing the probe. + */ + if (drv->ops && drv->ops->update_status) { + ret = drv->ops->update_status(slave, slave->status); + if (ret < 0) + dev_warn(dev, "%s: update_status failed with status %d\n", __func__, ret); + } + + mutex_unlock(&slave->sdw_dev_lock);
dev_dbg(dev, "probe complete\n");
@@ -152,9 +166,15 @@ static int sdw_drv_remove(struct device *dev) struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); int ret = 0;
+ mutex_lock(&slave->sdw_dev_lock); + + slave->probed = false; + if (drv->remove) ret = drv->remove(slave);
+ mutex_unlock(&slave->sdw_dev_lock); + dev_pm_domain_detach(dev, false);
return ret; diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c index 669d7573320b..25e76b5d4a1a 100644 --- a/drivers/soundwire/slave.c +++ b/drivers/soundwire/slave.c @@ -12,6 +12,7 @@ static void sdw_slave_release(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev);
+ mutex_destroy(&slave->sdw_dev_lock); kfree(slave); }
@@ -58,9 +59,9 @@ int sdw_slave_add(struct sdw_bus *bus, init_completion(&slave->enumeration_complete); init_completion(&slave->initialization_complete); slave->dev_num = 0; - init_completion(&slave->probe_complete); slave->probed = false; slave->first_interrupt_done = false; + mutex_init(&slave->sdw_dev_lock);
for (i = 0; i < SDW_MAX_PORTS; i++) init_completion(&slave->port_ready[i]); diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index d34150559142..bd502368339e 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -13,6 +13,7 @@ #include <linux/slab.h> #include <linux/soundwire/sdw_registers.h> #include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_type.h> #include <sound/soc.h> #include "bus.h"
@@ -401,20 +402,26 @@ static int sdw_do_port_prep(struct sdw_slave_runtime *s_rt, struct sdw_prepare_ch prep_ch, enum sdw_port_prep_ops cmd) { - const struct sdw_slave_ops *ops = s_rt->slave->ops; - int ret; + int ret = 0; + struct sdw_slave *slave = s_rt->slave;
- if (ops->port_prep) { - ret = ops->port_prep(s_rt->slave, &prep_ch, cmd); - if (ret < 0) { - dev_err(&s_rt->slave->dev, - "Slave Port Prep cmd %d failed: %d\n", - cmd, ret); - return ret; + mutex_lock(&slave->sdw_dev_lock); + + if (slave->probed) { + struct device *dev = &slave->dev; + struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); + + if (drv->ops && drv->ops->port_prep) { + ret = drv->ops->port_prep(slave, &prep_ch, cmd); + if (ret < 0) + dev_err(dev, "Slave Port Prep cmd %d failed: %d\n", + cmd, ret); } }
- return 0; + mutex_unlock(&slave->sdw_dev_lock); + + return ret; }
static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus, @@ -578,7 +585,7 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt) struct sdw_slave_runtime *s_rt; struct sdw_bus *bus = m_rt->bus; struct sdw_slave *slave; - int ret = 0; + int ret;
if (bus->ops->set_bus_conf) { ret = bus->ops->set_bus_conf(bus, &bus->params); @@ -589,17 +596,27 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt) list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) { slave = s_rt->slave;
- if (slave->ops->bus_config) { - ret = slave->ops->bus_config(slave, &bus->params); - if (ret < 0) { - dev_err(bus->dev, "Notify Slave: %d failed\n", - slave->dev_num); - return ret; + mutex_lock(&slave->sdw_dev_lock); + + if (slave->probed) { + struct device *dev = &slave->dev; + struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); + + if (drv->ops && drv->ops->bus_config) { + ret = drv->ops->bus_config(slave, &bus->params); + if (ret < 0) { + dev_err(dev, "Notify Slave: %d failed\n", + slave->dev_num); + mutex_unlock(&slave->sdw_dev_lock); + return ret; + } } } + + mutex_unlock(&slave->sdw_dev_lock); }
- return ret; + return 0; }
/** diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index 76ce3f3ac0f2..bf6f0decb3f6 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -646,9 +646,6 @@ struct sdw_slave_ops { * @dev_num: Current Device Number, values can be 0 or dev_num_sticky * @dev_num_sticky: one-time static Device Number assigned by Bus * @probed: boolean tracking driver state - * @probe_complete: completion utility to control potential races - * on startup between driver probe/initialization and SoundWire - * Slave state changes/implementation-defined interrupts * @enumeration_complete: completion utility to control potential races * on startup between device enumeration and read/write access to the * Slave device @@ -663,6 +660,7 @@ struct sdw_slave_ops { * for a Slave happens for the first time after enumeration * @is_mockup_device: status flag used to squelch errors in the command/control * protocol for SoundWire mockup devices + * @sdw_dev_lock: mutex used to protect callbacks/remove races */ struct sdw_slave { struct sdw_slave_id id; @@ -680,12 +678,12 @@ struct sdw_slave { u16 dev_num; u16 dev_num_sticky; bool probed; - struct completion probe_complete; struct completion enumeration_complete; struct completion initialization_complete; u32 unattach_request; bool first_interrupt_done; bool is_mockup_device; + struct mutex sdw_dev_lock; /* protect callbacks/remove races */ };
#define dev_to_sdw_dev(_dev) container_of(_dev, struct sdw_slave, dev)
From: Quentin Perret qperret@google.com
[ Upstream commit 1c3ace2b8b3995d3213c5e2d2aca01a0577a3b0f ]
Although harmless, the return statement in kvm_unexpected_el2_exception is rather confusing as the function itself has a void return type. The C standard is also pretty clear that "A return statement with an expression shall not appear in a function whose return type is void". Given that this return statement does not seem to add any actual value, let's not pointlessly violate the standard.
Build-tested with GCC 10 and CLANG 13 for good measure, the disassembled code is identical with or without the return statement.
Fixes: e9ee186bb735 ("KVM: arm64: Add kvm_extable for vaxorcism code") Signed-off-by: Quentin Perret qperret@google.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220705142310.3847918-1-qperret@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kvm/hyp/nvhe/switch.c | 2 +- arch/arm64/kvm/hyp/vhe/switch.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index 6db801db8f27..925b34b7708d 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -386,5 +386,5 @@ asmlinkage void __noreturn hyp_panic_bad_stack(void)
asmlinkage void kvm_unexpected_el2_exception(void) { - return __kvm_unexpected_el2_exception(); + __kvm_unexpected_el2_exception(); } diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c index 969f20daf97a..390af1a6a9b4 100644 --- a/arch/arm64/kvm/hyp/vhe/switch.c +++ b/arch/arm64/kvm/hyp/vhe/switch.c @@ -249,5 +249,5 @@ void __noreturn hyp_panic(void)
asmlinkage void kvm_unexpected_el2_exception(void) { - return __kvm_unexpected_el2_exception(); + __kvm_unexpected_el2_exception(); }
From: Viacheslav Mitrofanov v.v.mitrofanov@yadro.com
[ Upstream commit b2cc5c465c2cb8ab697c3fd6583c614e3f6cfbcc ]
When we get a DMA channel and try to use it in multiple threads it will cause oops and hanging the system.
% echo 64 > /sys/module/dmatest/parameters/threads_per_chan % echo 10000 > /sys/module/dmatest/parameters/iterations % echo 1 > /sys/module/dmatest/parameters/run [ 89.480664] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000a0 [ 89.488725] Oops [#1] [ 89.494708] CPU: 2 PID: 1008 Comm: dma0chan0-copy0 Not tainted 5.17.0-rc5 [ 89.509385] epc : vchan_find_desc+0x32/0x46 [ 89.513553] ra : sf_pdma_tx_status+0xca/0xd6
This happens because of data race. Each thread rewrite channels's descriptor as soon as device_prep_dma_memcpy() is called. It leads to the situation when the driver thinks that it uses right descriptor that actually is freed or substituted for other one.
With current fixes a descriptor changes its value only when it has been used. A new descriptor is acquired from vc->desc_issued queue that is already filled with descriptors that are ready to be sent. Threads have no direct access to DMA channel descriptor. Now it is just possible to queue a descriptor for further processing.
Fixes: 6973886ad58e ("dmaengine: sf-pdma: add platform DMA support for HiFive Unleashed A00") Signed-off-by: Viacheslav Mitrofanov v.v.mitrofanov@yadro.com Link: https://lore.kernel.org/r/20220701082942.12835-1-v.v.mitrofanov@yadro.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/sf-pdma/sf-pdma.c | 44 ++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c index db5a4ef76077..4f8b8498c5c6 100644 --- a/drivers/dma/sf-pdma/sf-pdma.c +++ b/drivers/dma/sf-pdma/sf-pdma.c @@ -52,16 +52,6 @@ static inline struct sf_pdma_desc *to_sf_pdma_desc(struct virt_dma_desc *vd) static struct sf_pdma_desc *sf_pdma_alloc_desc(struct sf_pdma_chan *chan) { struct sf_pdma_desc *desc; - unsigned long flags; - - spin_lock_irqsave(&chan->lock, flags); - - if (chan->desc && !chan->desc->in_use) { - spin_unlock_irqrestore(&chan->lock, flags); - return chan->desc; - } - - spin_unlock_irqrestore(&chan->lock, flags);
desc = kzalloc(sizeof(*desc), GFP_NOWAIT); if (!desc) @@ -111,7 +101,6 @@ sf_pdma_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dest, dma_addr_t src, desc->async_tx = vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
spin_lock_irqsave(&chan->vchan.lock, iflags); - chan->desc = desc; sf_pdma_fill_desc(desc, dest, src, len); spin_unlock_irqrestore(&chan->vchan.lock, iflags);
@@ -170,11 +159,17 @@ static size_t sf_pdma_desc_residue(struct sf_pdma_chan *chan, unsigned long flags; u64 residue = 0; struct sf_pdma_desc *desc; - struct dma_async_tx_descriptor *tx; + struct dma_async_tx_descriptor *tx = NULL;
spin_lock_irqsave(&chan->vchan.lock, flags);
- tx = &chan->desc->vdesc.tx; + list_for_each_entry(vd, &chan->vchan.desc_submitted, node) + if (vd->tx.cookie == cookie) + tx = &vd->tx; + + if (!tx) + goto out; + if (cookie == tx->chan->completed_cookie) goto out;
@@ -241,6 +236,19 @@ static void sf_pdma_enable_request(struct sf_pdma_chan *chan) writel(v, regs->ctrl); }
+static struct sf_pdma_desc *sf_pdma_get_first_pending_desc(struct sf_pdma_chan *chan) +{ + struct virt_dma_chan *vchan = &chan->vchan; + struct virt_dma_desc *vdesc; + + if (list_empty(&vchan->desc_issued)) + return NULL; + + vdesc = list_first_entry(&vchan->desc_issued, struct virt_dma_desc, node); + + return container_of(vdesc, struct sf_pdma_desc, vdesc); +} + static void sf_pdma_xfer_desc(struct sf_pdma_chan *chan) { struct sf_pdma_desc *desc = chan->desc; @@ -268,8 +276,11 @@ static void sf_pdma_issue_pending(struct dma_chan *dchan)
spin_lock_irqsave(&chan->vchan.lock, flags);
- if (vchan_issue_pending(&chan->vchan) && chan->desc) + if (!chan->desc && vchan_issue_pending(&chan->vchan)) { + /* vchan_issue_pending has made a check that desc in not NULL */ + chan->desc = sf_pdma_get_first_pending_desc(chan); sf_pdma_xfer_desc(chan); + }
spin_unlock_irqrestore(&chan->vchan.lock, flags); } @@ -298,6 +309,11 @@ static void sf_pdma_donebh_tasklet(struct tasklet_struct *t) spin_lock_irqsave(&chan->vchan.lock, flags); list_del(&chan->desc->vdesc.node); vchan_cookie_complete(&chan->desc->vdesc); + + chan->desc = sf_pdma_get_first_pending_desc(chan); + if (chan->desc) + sf_pdma_xfer_desc(chan); + spin_unlock_irqrestore(&chan->vchan.lock, flags); }
From: Shunsuke Mie mie@igel.co.jp
[ Upstream commit 1bc2b7bfba6e2f64edf5e246f3af2967261f6c3d ]
Unbinding an endpoint function from the endpoint controller shouldn't stop the controller. This is especially a problem for multi-function endpoints where other endpoints may still be active.
Don't stop the controller when unbinding one of its endpoints. Normally the controller is stopped via configfs.
Fixes: 349e7a85b25f ("PCI: endpoint: functions: Add an EP function to test PCI") Link: https://lore.kernel.org/r/20220622040924.113279-1-mie@igel.co.jp Signed-off-by: Shunsuke Mie mie@igel.co.jp Signed-off-by: Bjorn Helgaas bhelgaas@google.com Acked-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/endpoint/functions/pci-epf-test.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index 5b833f00e980..a5ed779b0a51 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -627,7 +627,6 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
cancel_delayed_work(&epf_test->cmd_handler); pci_epf_test_clean_dma_chan(epf_test); - pci_epc_stop(epc); for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) { epf_bar = &epf->bar[bar];
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 488987b2d5cade4e7680f7e81590435a848d1fa9 ]
Change QSERDES_V5_COM_CMN_MODE to be defined to 0x1a0 rather than 0x1a4. The only user of this register name (sm8450_qmp_gen4x2_pcie_serdes_tbl) should use the 0x1a0 register, as stated in the downstream dtsi tree.
Fixes: 2c91bf6bf290 ("phy: qcom-qmp: Add SM8450 PCIe1 PHY support") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Link: https://lore.kernel.org/r/20220705094320.1313312-2-dmitry.baryshkov@linaro.o... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/qualcomm/phy-qcom-qmp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h index 06b2556ed93a..b9a91520439c 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h @@ -1116,7 +1116,8 @@ #define QSERDES_V5_COM_CORE_CLK_EN 0x174 #define QSERDES_V5_COM_CMN_CONFIG 0x17c #define QSERDES_V5_COM_CMN_MISC1 0x19c -#define QSERDES_V5_COM_CMN_MODE 0x1a4 +#define QSERDES_V5_COM_CMN_MODE 0x1a0 +#define QSERDES_V5_COM_CMN_MODE_CONTD 0x1a4 #define QSERDES_V5_COM_VCO_DC_LEVEL_CTRL 0x1a8 #define QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x1ac #define QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x1b0
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 7c33e477bd883f79cccec418980cb8f7f2d50347 ]
There is a copy and paste bug here. It should check ".rsp" instead of ".req". The error message is copy and pasted as well so update that too.
Link: https://lore.kernel.org/r/YrK1A/t3L6HKnswO@kili Fixes: 9c40c36e75ff ("scsi: qla2xxx: edif: Reduce Initiator-Initiator thrashing") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_gs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 574251b2e0ef..c914b5df9c12 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3386,9 +3386,9 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool wait) sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, &sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL); - if (!sp->u.iocb_cmd.u.ctarg.req) { + if (!sp->u.iocb_cmd.u.ctarg.rsp) { ql_log(ql_log_warn, vha, 0xd041, - "%s: Failed to allocate ct_sns request.\n", + "%s: Failed to allocate ct_sns response.\n", __func__); goto done_free_sp; }
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 88f1669019bd62b3009a3cebf772fbaaa21b9f38 ]
For some technologies, e.g. an ATA bus, resuming can take multiple seconds. Waiting for resume to finish can cause a very noticeable delay. Hence this commit that restores the behavior from before "scsi: core: pm: Rely on the device driver core for async power management" for most SCSI devices.
This commit introduces a behavior change: if the START command fails, do not consider this as a SCSI disk resume failure.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215880 Link: https://lore.kernel.org/r/20220630195703.10155-3-bvanassche@acm.org Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management") Cc: Ming Lei ming.lei@redhat.com Cc: Hannes Reinecke hare@suse.de Cc: John Garry john.garry@huawei.com Cc: ericspero@icloud.com Cc: jason600.groome@gmail.com Tested-by: jason600.groome@gmail.com Signed-off-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/sd.c | 84 +++++++++++++++++++++++++++++++++++++---------- drivers/scsi/sd.h | 5 +++ 2 files changed, 71 insertions(+), 18 deletions(-)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index a1a2ac09066f..081e39b3543b 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -103,6 +103,7 @@ static void sd_config_discard(struct scsi_disk *, unsigned int); static void sd_config_write_same(struct scsi_disk *); static int sd_revalidate_disk(struct gendisk *); static void sd_unlock_native_capacity(struct gendisk *disk); +static void sd_start_done_work(struct work_struct *work); static int sd_probe(struct device *); static int sd_remove(struct device *); static void sd_shutdown(struct device *); @@ -3463,6 +3464,7 @@ static int sd_probe(struct device *dev) sdkp->max_retries = SD_MAX_RETRIES; atomic_set(&sdkp->openers, 0); atomic_set(&sdkp->device->ioerr_cnt, 0); + INIT_WORK(&sdkp->start_done_work, sd_start_done_work);
if (!sdp->request_queue->rq_timeout) { if (sdp->type != TYPE_MOD) @@ -3585,12 +3587,69 @@ static void scsi_disk_release(struct device *dev) kfree(sdkp); }
+/* Process sense data after a START command finished. */ +static void sd_start_done_work(struct work_struct *work) +{ + struct scsi_disk *sdkp = container_of(work, typeof(*sdkp), + start_done_work); + struct scsi_sense_hdr sshdr; + int res = sdkp->start_result; + + if (res == 0) + return; + + sd_print_result(sdkp, "Start/Stop Unit failed", res); + + if (res < 0) + return; + + if (scsi_normalize_sense(sdkp->start_sense_buffer, + sdkp->start_sense_len, &sshdr)) + sd_print_sense_hdr(sdkp, &sshdr); +} + +/* A START command finished. May be called from interrupt context. */ +static void sd_start_done(struct request *req, blk_status_t status) +{ + const struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req); + struct scsi_disk *sdkp = scsi_disk(req->q->disk); + + sdkp->start_result = scmd->result; + WARN_ON_ONCE(scmd->sense_len > SCSI_SENSE_BUFFERSIZE); + sdkp->start_sense_len = scmd->sense_len; + memcpy(sdkp->start_sense_buffer, scmd->sense_buffer, + ARRAY_SIZE(sdkp->start_sense_buffer)); + WARN_ON_ONCE(!schedule_work(&sdkp->start_done_work)); +} + +/* Submit a START command asynchronously. */ +static int sd_submit_start(struct scsi_disk *sdkp, u8 cmd[], u8 cmd_len) +{ + struct scsi_device *sdev = sdkp->device; + struct request_queue *q = sdev->request_queue; + struct request *req; + struct scsi_cmnd *scmd; + + req = scsi_alloc_request(q, REQ_OP_DRV_IN, BLK_MQ_REQ_PM); + if (IS_ERR(req)) + return PTR_ERR(req); + + scmd = blk_mq_rq_to_pdu(req); + scmd->cmd_len = cmd_len; + memcpy(scmd->cmnd, cmd, cmd_len); + scmd->allowed = sdkp->max_retries; + req->timeout = SD_TIMEOUT; + req->rq_flags |= RQF_PM | RQF_QUIET; + req->end_io = sd_start_done; + blk_execute_rq_nowait(req, /*at_head=*/true); + + return 0; +} + static int sd_start_stop_device(struct scsi_disk *sdkp, int start) { unsigned char cmd[6] = { START_STOP }; /* START_VALID */ - struct scsi_sense_hdr sshdr; struct scsi_device *sdp = sdkp->device; - int res;
if (start) cmd[4] |= 1; /* START */ @@ -3601,23 +3660,10 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) if (!scsi_device_online(sdp)) return -ENODEV;
- res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr, - SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL); - if (res) { - sd_print_result(sdkp, "Start/Stop Unit failed", res); - if (res > 0 && scsi_sense_valid(&sshdr)) { - sd_print_sense_hdr(sdkp, &sshdr); - /* 0x3a is medium not present */ - if (sshdr.asc == 0x3a) - res = 0; - } - } + /* Wait until processing of sense data has finished. */ + flush_work(&sdkp->start_done_work);
- /* SCSI error codes must not go to the generic layer */ - if (res) - return -EIO; - - return 0; + return sd_submit_start(sdkp, cmd, sizeof(cmd)); }
/* @@ -3644,6 +3690,8 @@ static void sd_shutdown(struct device *dev) sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); sd_start_stop_device(sdkp, 0); } + + flush_work(&sdkp->start_done_work); }
static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 5eea762f84d1..b89187761d61 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -150,6 +150,11 @@ struct scsi_disk { unsigned urswrz : 1; unsigned security : 1; unsigned ignore_medium_access_errors : 1; + + int start_result; + u32 start_sense_len; + u8 start_sense_buffer[SCSI_SENSE_BUFFERSIZE]; + struct work_struct start_done_work; }; #define to_scsi_disk(obj) container_of(obj, struct scsi_disk, disk_dev)
On 8/15/22 11:02, Greg Kroah-Hartman wrote:
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 88f1669019bd62b3009a3cebf772fbaaa21b9f38 ]
For some technologies, e.g. an ATA bus, resuming can take multiple seconds. Waiting for resume to finish can cause a very noticeable delay. Hence this commit that restores the behavior from before "scsi: core: pm: Rely on the device driver core for async power management" for most SCSI devices.
This commit introduces a behavior change: if the START command fails, do not consider this as a SCSI disk resume failure.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215880 Link: https://lore.kernel.org/r/20220630195703.10155-3-bvanassche@acm.org Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management")
Hi Greg,
It has been reported that this patch causes a regression, namely disks not coming back after a resume. That issue is worse than the issue fixed by this patch - eliminating a delay. Please drop this patch from the stable tree.
A revert of this patch has been posted on the linux-scsi mailing list. See also https://lore.kernel.org/linux-scsi/8a83665a-1951-a326-f930-8fcbb0c4dd9a@huaw....
Thanks,
Bart.
On Tue, Aug 16, 2022 at 11:05:27AM -0700, Bart Van Assche wrote:
On 8/15/22 11:02, Greg Kroah-Hartman wrote:
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 88f1669019bd62b3009a3cebf772fbaaa21b9f38 ]
For some technologies, e.g. an ATA bus, resuming can take multiple seconds. Waiting for resume to finish can cause a very noticeable delay. Hence this commit that restores the behavior from before "scsi: core: pm: Rely on the device driver core for async power management" for most SCSI devices.
This commit introduces a behavior change: if the START command fails, do not consider this as a SCSI disk resume failure.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215880 Link: https://lore.kernel.org/r/20220630195703.10155-3-bvanassche@acm.org Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management")
Hi Greg,
It has been reported that this patch causes a regression, namely disks not coming back after a resume. That issue is worse than the issue fixed by this patch - eliminating a delay. Please drop this patch from the stable tree.
A revert of this patch has been posted on the linux-scsi mailing list. See also https://lore.kernel.org/linux-scsi/8a83665a-1951-a326-f930-8fcbb0c4dd9a@huaw....
Now dropped from the queue, thanks.
greg k-h
From: James Smart jsmart2021@gmail.com
[ Upstream commit ffc566411aded3c12c63e1310fb23830e9608c59 ]
The RSCN_MEMENTO logic was to workaround a target that does not register both FCP and NVMe FC4 types at the same time. This caused the configuration to not produce a second RSCN for the NVMe FC4 type registration in a timely manner. The intention of the RSCN_MEMENTO flag was to always signal to try NVMe PRLI.
However, there are other FCP-only target arrays in correctly behaved configurations that reject the NVMe PRLI followed by a LOGO leading to never rediscovering the target after an issue_lip (as LOGO causes a repeat of PLOGI/PRLIs).
Revert the RSCN_MEMENTO patch as it is causing correctly behaved configs to fail while it exists only to succeed on a misbehaved config.
Link: https://lore.kernel.org/r/20220701211425.2708-9-jsmart2021@gmail.com Fixes: 1045592fc968 ("scsi: lpfc: Introduce FC_RSCN_MEMENTO flag for tracking post RSCN completion") Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc.h | 1 - drivers/scsi/lpfc/lpfc_els.c | 8 ++------ drivers/scsi/lpfc/lpfc_hbadisc.c | 3 +-- 3 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index da9070cdad91..212f9b962187 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -604,7 +604,6 @@ struct lpfc_vport { #define FC_VFI_REGISTERED 0x800000 /* VFI is registered */ #define FC_FDISC_COMPLETED 0x1000000/* FDISC completed */ #define FC_DISC_DELAYED 0x2000000/* Delay NPort discovery */ -#define FC_RSCN_MEMENTO 0x4000000/* RSCN cmd processed */
uint32_t ct_flags; #define FC_CT_RFF_ID 0x1 /* RFF_ID accepted by switch */ diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 3fababb7c181..c904e9486b92 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1886,7 +1886,6 @@ lpfc_end_rscn(struct lpfc_vport *vport) else { spin_lock_irq(shost->host_lock); vport->fc_flag &= ~FC_RSCN_MODE; - vport->fc_flag |= FC_RSCN_MEMENTO; spin_unlock_irq(shost->host_lock); } } @@ -2434,14 +2433,13 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, u32 local_nlp_type, elscmd;
/* - * If discovery was kicked off from RSCN mode, - * the FC4 types supported from a + * If we are in RSCN mode, the FC4 types supported from a * previous GFT_ID command may not be accurate. So, if we * are a NVME Initiator, always look for the possibility of * the remote NPort beng a NVME Target. */ if (phba->sli_rev == LPFC_SLI_REV4 && - vport->fc_flag & (FC_RSCN_MODE | FC_RSCN_MEMENTO) && + vport->fc_flag & FC_RSCN_MODE && vport->nvmei_support) ndlp->nlp_fc4_type |= NLP_FC4_NVME; local_nlp_type = ndlp->nlp_fc4_type; @@ -7915,7 +7913,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, if ((rscn_cnt < FC_MAX_HOLD_RSCN) && !(vport->fc_flag & FC_RSCN_DISCOVERY)) { vport->fc_flag |= FC_RSCN_MODE; - vport->fc_flag &= ~FC_RSCN_MEMENTO; spin_unlock_irq(shost->host_lock); if (rscn_cnt) { cmd = vport->fc_rscn_id_list[rscn_cnt-1]->virt; @@ -7965,7 +7962,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_RSCN_MODE; - vport->fc_flag &= ~FC_RSCN_MEMENTO; spin_unlock_irq(shost->host_lock); vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd; /* Indicate we are done walking fc_rscn_id_list on this vport */ diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index fb36f26170e4..5cd838eac455 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1354,8 +1354,7 @@ lpfc_linkup_port(struct lpfc_vport *vport)
spin_lock_irq(shost->host_lock); vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY | - FC_RSCN_MEMENTO | FC_RSCN_MODE | - FC_NLP_MORE | FC_RSCN_DISCOVERY); + FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY); vport->fc_flag |= FC_NDISC_ACTIVE; vport->fc_ns_retry = 0; spin_unlock_irq(shost->host_lock);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 086c28ab7c5699256aced0049aae9c42f1410313 ]
If an error occurs after calling 'pci_alloc_irq_vectors()', 'pci_free_irq_vectors()' must be called as already done in the remove function.
Fixes: 7b7036d47c35 ("intel_th: pci: Use MSI interrupt signalling") Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Alexander Shishkin alexander.shishkin@linux.intel.com Link: https://lore.kernel.org/r/20220705082637.59979-2-alexander.shishkin@linux.in... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwtracing/intel_th/pci.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index 7da4f298ed01..fcd0aca75007 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -100,8 +100,10 @@ static int intel_th_pci_probe(struct pci_dev *pdev, }
th = intel_th_alloc(&pdev->dev, drvdata, resource, r); - if (IS_ERR(th)) - return PTR_ERR(th); + if (IS_ERR(th)) { + err = PTR_ERR(th); + goto err_free_irq; + }
th->activate = intel_th_pci_activate; th->deactivate = intel_th_pci_deactivate; @@ -109,6 +111,10 @@ static int intel_th_pci_probe(struct pci_dev *pdev, pci_set_master(pdev);
return 0; + +err_free_irq: + pci_free_irq_vectors(pdev); + return err; }
static void intel_th_pci_remove(struct pci_dev *pdev)
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit 82f76a4a720791d889de775b5f7541d601efc8bd ]
The return value of dma_alloc_coherent() needs to be checked. To avoid use of null pointer in sg_set_buf() in case of the failure of alloc.
Fixes: f220df66f676 ("intel_th: msu-sink: An example msu buffer "sink"") Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Signed-off-by: Alexander Shishkin alexander.shishkin@linux.intel.com Link: https://lore.kernel.org/r/20220705082637.59979-3-alexander.shishkin@linux.in... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwtracing/intel_th/msu-sink.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/hwtracing/intel_th/msu-sink.c b/drivers/hwtracing/intel_th/msu-sink.c index 2c7f5116be12..891b28ea25fe 100644 --- a/drivers/hwtracing/intel_th/msu-sink.c +++ b/drivers/hwtracing/intel_th/msu-sink.c @@ -71,6 +71,9 @@ static int msu_sink_alloc_window(void *data, struct sg_table **sgt, size_t size) block = dma_alloc_coherent(priv->dev->parent->parent, PAGE_SIZE, &sg_dma_address(sg_ptr), GFP_KERNEL); + if (!block) + return -ENOMEM; + sg_set_buf(sg_ptr, block, PAGE_SIZE); }
From: Alexander Shishkin alexander.shishkin@linux.intel.com
[ Upstream commit ac12ad3ccf6d386e64a9d6a890595a2509d24edd ]
After commit f5ff79fddf0e ("dma-mapping: remove CONFIG_DMA_REMAP") there's a chance of DMA buffer getting allocated via vmalloc(), which messes up the mmapping code:
RIP: msc_mmap_fault [intel_th_msu] Call Trace:
<TASK> __do_fault do_fault
...
Fix this by accounting for vmalloc possibility.
Fixes: ba39bd830605 ("intel_th: msu: Switch over to scatterlist") Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Alexander Shishkin alexander.shishkin@linux.intel.com Link: https://lore.kernel.org/r/20220705082637.59979-4-alexander.shishkin@linux.in... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwtracing/intel_th/msu.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c index 70a07b4e9967..6c8215a47a60 100644 --- a/drivers/hwtracing/intel_th/msu.c +++ b/drivers/hwtracing/intel_th/msu.c @@ -1067,6 +1067,16 @@ msc_buffer_set_uc(struct msc *msc) {} static inline void msc_buffer_set_wb(struct msc *msc) {} #endif /* CONFIG_X86 */
+static struct page *msc_sg_page(struct scatterlist *sg) +{ + void *addr = sg_virt(sg); + + if (is_vmalloc_addr(addr)) + return vmalloc_to_page(addr); + + return sg_page(sg); +} + /** * msc_buffer_win_alloc() - alloc a window for a multiblock mode * @msc: MSC device @@ -1137,7 +1147,7 @@ static void __msc_buffer_win_free(struct msc *msc, struct msc_window *win) int i;
for_each_sg(win->sgt->sgl, sg, win->nr_segs, i) { - struct page *page = sg_page(sg); + struct page *page = msc_sg_page(sg);
page->mapping = NULL; dma_free_coherent(msc_dev(win->msc)->parent->parent, PAGE_SIZE, @@ -1401,7 +1411,7 @@ static struct page *msc_buffer_get_page(struct msc *msc, unsigned long pgoff) pgoff -= win->pgoff;
for_each_sg(win->sgt->sgl, sg, win->nr_segs, blk) { - struct page *page = sg_page(sg); + struct page *page = msc_sg_page(sg); size_t pgsz = PFN_DOWN(sg->length);
if (pgoff < pgsz)
From: Carlos Llamas cmllamas@google.com
[ Upstream commit b7e241bbff24f9e106bf616408fd58bcedc44bae ]
The patchset in [1] exported some definitions to binder_internal.h in order to make the debugfs entries such as 'stats' and 'transaction_log' available in a binderfs instance. However, the DEFINE_SHOW_ATTRIBUTE macro expands into a static function/variable pair, which in turn get redefined each time a source file includes this internal header.
This problem was made evident after a report from the kernel test robot lkp@intel.com where several W=1 build warnings are seen in downstream kernels. See the following example:
include/../drivers/android/binder_internal.h:111:23: warning: 'binder_stats_fops' defined but not used [-Wunused-const-variable=] 111 | DEFINE_SHOW_ATTRIBUTE(binder_stats); | ^~~~~~~~~~~~ include/linux/seq_file.h:174:37: note: in definition of macro 'DEFINE_SHOW_ATTRIBUTE' 174 | static const struct file_operations __name ## _fops = { \ | ^~~~~~
This patch fixes the above issues by moving back the definitions into binder.c and instead creates an array of the debugfs entries which is more convenient to share with binderfs and iterate through.
[1] https://lore.kernel.org/all/20190903161655.107408-1-hridya@google.com/
Fixes: 0e13e452dafc ("binder: Add stats, state and transactions files") Fixes: 03e2e07e3814 ("binder: Make transaction_log available in binderfs") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Carlos Llamas cmllamas@google.com Link: https://lore.kernel.org/r/20220701182041.2134313-1-cmllamas@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/android/binder.c | 114 +++++++++++++++++++++--------- drivers/android/binder_internal.h | 46 +++--------- drivers/android/binderfs.c | 47 +++--------- 3 files changed, 100 insertions(+), 107 deletions(-)
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 362c0deb65f1..54ac94fed015 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -197,8 +197,32 @@ static inline void binder_stats_created(enum binder_stat_types type) atomic_inc(&binder_stats.obj_created[type]); }
-struct binder_transaction_log binder_transaction_log; -struct binder_transaction_log binder_transaction_log_failed; +struct binder_transaction_log_entry { + int debug_id; + int debug_id_done; + int call_type; + int from_proc; + int from_thread; + int target_handle; + int to_proc; + int to_thread; + int to_node; + int data_size; + int offsets_size; + int return_error_line; + uint32_t return_error; + uint32_t return_error_param; + char context_name[BINDERFS_MAX_NAME + 1]; +}; + +struct binder_transaction_log { + atomic_t cur; + bool full; + struct binder_transaction_log_entry entry[32]; +}; + +static struct binder_transaction_log binder_transaction_log; +static struct binder_transaction_log binder_transaction_log_failed;
static struct binder_transaction_log_entry *binder_transaction_log_add( struct binder_transaction_log *log) @@ -6197,8 +6221,7 @@ static void print_binder_proc_stats(struct seq_file *m, print_binder_stats(m, " ", &proc->stats); }
- -int binder_state_show(struct seq_file *m, void *unused) +static int state_show(struct seq_file *m, void *unused) { struct binder_proc *proc; struct binder_node *node; @@ -6237,7 +6260,7 @@ int binder_state_show(struct seq_file *m, void *unused) return 0; }
-int binder_stats_show(struct seq_file *m, void *unused) +static int stats_show(struct seq_file *m, void *unused) { struct binder_proc *proc;
@@ -6253,7 +6276,7 @@ int binder_stats_show(struct seq_file *m, void *unused) return 0; }
-int binder_transactions_show(struct seq_file *m, void *unused) +static int transactions_show(struct seq_file *m, void *unused) { struct binder_proc *proc;
@@ -6309,7 +6332,7 @@ static void print_binder_transaction_log_entry(struct seq_file *m, "\n" : " (incomplete)\n"); }
-int binder_transaction_log_show(struct seq_file *m, void *unused) +static int transaction_log_show(struct seq_file *m, void *unused) { struct binder_transaction_log *log = m->private; unsigned int log_cur = atomic_read(&log->cur); @@ -6341,6 +6364,45 @@ const struct file_operations binder_fops = { .release = binder_release, };
+DEFINE_SHOW_ATTRIBUTE(state); +DEFINE_SHOW_ATTRIBUTE(stats); +DEFINE_SHOW_ATTRIBUTE(transactions); +DEFINE_SHOW_ATTRIBUTE(transaction_log); + +const struct binder_debugfs_entry binder_debugfs_entries[] = { + { + .name = "state", + .mode = 0444, + .fops = &state_fops, + .data = NULL, + }, + { + .name = "stats", + .mode = 0444, + .fops = &stats_fops, + .data = NULL, + }, + { + .name = "transactions", + .mode = 0444, + .fops = &transactions_fops, + .data = NULL, + }, + { + .name = "transaction_log", + .mode = 0444, + .fops = &transaction_log_fops, + .data = &binder_transaction_log, + }, + { + .name = "failed_transaction_log", + .mode = 0444, + .fops = &transaction_log_fops, + .data = &binder_transaction_log_failed, + }, + {} /* terminator */ +}; + static int __init init_binder_device(const char *name) { int ret; @@ -6386,36 +6448,18 @@ static int __init binder_init(void) atomic_set(&binder_transaction_log_failed.cur, ~0U);
binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL); - if (binder_debugfs_dir_entry_root) + if (binder_debugfs_dir_entry_root) { + const struct binder_debugfs_entry *db_entry; + + binder_for_each_debugfs_entry(db_entry) + debugfs_create_file(db_entry->name, + db_entry->mode, + binder_debugfs_dir_entry_root, + db_entry->data, + db_entry->fops); + binder_debugfs_dir_entry_proc = debugfs_create_dir("proc", binder_debugfs_dir_entry_root); - - if (binder_debugfs_dir_entry_root) { - debugfs_create_file("state", - 0444, - binder_debugfs_dir_entry_root, - NULL, - &binder_state_fops); - debugfs_create_file("stats", - 0444, - binder_debugfs_dir_entry_root, - NULL, - &binder_stats_fops); - debugfs_create_file("transactions", - 0444, - binder_debugfs_dir_entry_root, - NULL, - &binder_transactions_fops); - debugfs_create_file("transaction_log", - 0444, - binder_debugfs_dir_entry_root, - &binder_transaction_log, - &binder_transaction_log_fops); - debugfs_create_file("failed_transaction_log", - 0444, - binder_debugfs_dir_entry_root, - &binder_transaction_log_failed, - &binder_transaction_log_fops); }
if (!IS_ENABLED(CONFIG_ANDROID_BINDERFS) && diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h index 8dc0bccf8513..abe19d88c6ec 100644 --- a/drivers/android/binder_internal.h +++ b/drivers/android/binder_internal.h @@ -107,41 +107,19 @@ static inline int __init init_binderfs(void) } #endif
-int binder_stats_show(struct seq_file *m, void *unused); -DEFINE_SHOW_ATTRIBUTE(binder_stats); - -int binder_state_show(struct seq_file *m, void *unused); -DEFINE_SHOW_ATTRIBUTE(binder_state); - -int binder_transactions_show(struct seq_file *m, void *unused); -DEFINE_SHOW_ATTRIBUTE(binder_transactions); - -int binder_transaction_log_show(struct seq_file *m, void *unused); -DEFINE_SHOW_ATTRIBUTE(binder_transaction_log); - -struct binder_transaction_log_entry { - int debug_id; - int debug_id_done; - int call_type; - int from_proc; - int from_thread; - int target_handle; - int to_proc; - int to_thread; - int to_node; - int data_size; - int offsets_size; - int return_error_line; - uint32_t return_error; - uint32_t return_error_param; - char context_name[BINDERFS_MAX_NAME + 1]; +struct binder_debugfs_entry { + const char *name; + umode_t mode; + const struct file_operations *fops; + void *data; };
-struct binder_transaction_log { - atomic_t cur; - bool full; - struct binder_transaction_log_entry entry[32]; -}; +extern const struct binder_debugfs_entry binder_debugfs_entries[]; + +#define binder_for_each_debugfs_entry(entry) \ + for ((entry) = binder_debugfs_entries; \ + (entry)->name; \ + (entry)++)
enum binder_stat_types { BINDER_STAT_PROC, @@ -580,6 +558,4 @@ struct binder_object { }; };
-extern struct binder_transaction_log binder_transaction_log; -extern struct binder_transaction_log binder_transaction_log_failed; #endif /* _LINUX_BINDER_INTERNAL_H */ diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index 6c5e94f6cb3a..588d753a7a19 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -629,6 +629,7 @@ static int init_binder_features(struct super_block *sb) static int init_binder_logs(struct super_block *sb) { struct dentry *binder_logs_root_dir, *dentry, *proc_log_dir; + const struct binder_debugfs_entry *db_entry; struct binderfs_info *info; int ret = 0;
@@ -639,43 +640,15 @@ static int init_binder_logs(struct super_block *sb) goto out; }
- dentry = binderfs_create_file(binder_logs_root_dir, "stats", - &binder_stats_fops, NULL); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto out; - } - - dentry = binderfs_create_file(binder_logs_root_dir, "state", - &binder_state_fops, NULL); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto out; - } - - dentry = binderfs_create_file(binder_logs_root_dir, "transactions", - &binder_transactions_fops, NULL); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto out; - } - - dentry = binderfs_create_file(binder_logs_root_dir, - "transaction_log", - &binder_transaction_log_fops, - &binder_transaction_log); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto out; - } - - dentry = binderfs_create_file(binder_logs_root_dir, - "failed_transaction_log", - &binder_transaction_log_fops, - &binder_transaction_log_failed); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto out; + binder_for_each_debugfs_entry(db_entry) { + dentry = binderfs_create_file(binder_logs_root_dir, + db_entry->name, + db_entry->fops, + db_entry->data); + if (IS_ERR(dentry)) { + ret = PTR_ERR(dentry); + goto out; + } }
proc_log_dir = binderfs_create_dir(binder_logs_root_dir, "proc");
From: Duoming Zhou duoming@zju.edu.cn
[ Upstream commit 6a0c054930d554ad8f8044ef1fc856d9da391c81 ]
There are sleep in atomic context bugs when dm_fsync_timer_callback is executing. The root cause is that the memory allocation functions with GFP_KERNEL or GFP_NOIO parameters are called in dm_fsync_timer_callback which is a timer handler. The call paths that could trigger bugs are shown below:
(interrupt context) dm_fsync_timer_callback write_nic_byte kzalloc(sizeof(data), GFP_KERNEL); //may sleep usb_control_msg kmalloc(.., GFP_NOIO); //may sleep write_nic_dword kzalloc(sizeof(data), GFP_KERNEL); //may sleep usb_control_msg kmalloc(.., GFP_NOIO); //may sleep
This patch uses delayed work to replace timer and moves the operations that may sleep into the delayed work in order to mitigate bugs.
Fixes: 8fc8598e61f6 ("Staging: Added Realtek rtl8192u driver to staging") Signed-off-by: Duoming Zhou duoming@zju.edu.cn Link: https://lore.kernel.org/r/20220710103002.63283-1-duoming@zju.edu.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/rtl8192u/r8192U.h | 2 +- drivers/staging/rtl8192u/r8192U_dm.c | 38 +++++++++++++--------------- drivers/staging/rtl8192u/r8192U_dm.h | 2 +- 3 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h index 14ca00a2789b..1942cb849374 100644 --- a/drivers/staging/rtl8192u/r8192U.h +++ b/drivers/staging/rtl8192u/r8192U.h @@ -1013,7 +1013,7 @@ typedef struct r8192_priv { bool bis_any_nonbepkts; bool bcurrent_turbo_EDCA; bool bis_cur_rdlstate; - struct timer_list fsync_timer; + struct delayed_work fsync_work; bool bfsync_processing; /* 500ms Fsync timer is active or not */ u32 rate_record; u32 rateCountDiffRecord; diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index 725bf5ca9e34..0fcfcaa6500b 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -2578,19 +2578,20 @@ static void dm_init_fsync(struct net_device *dev) priv->ieee80211->fsync_seconddiff_ratethreshold = 200; priv->ieee80211->fsync_state = Default_Fsync; priv->framesyncMonitor = 1; /* current default 0xc38 monitor on */ - timer_setup(&priv->fsync_timer, dm_fsync_timer_callback, 0); + INIT_DELAYED_WORK(&priv->fsync_work, dm_fsync_work_callback); }
static void dm_deInit_fsync(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev);
- del_timer_sync(&priv->fsync_timer); + cancel_delayed_work_sync(&priv->fsync_work); }
-void dm_fsync_timer_callback(struct timer_list *t) +void dm_fsync_work_callback(struct work_struct *work) { - struct r8192_priv *priv = from_timer(priv, t, fsync_timer); + struct r8192_priv *priv = + container_of(work, struct r8192_priv, fsync_work.work); struct net_device *dev = priv->ieee80211->dev; u32 rate_index, rate_count = 0, rate_count_diff = 0; bool bSwitchFromCountDiff = false; @@ -2657,17 +2658,16 @@ void dm_fsync_timer_callback(struct timer_list *t) } } if (bDoubleTimeInterval) { - if (timer_pending(&priv->fsync_timer)) - del_timer_sync(&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + - msecs_to_jiffies(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval); - add_timer(&priv->fsync_timer); + cancel_delayed_work_sync(&priv->fsync_work); + schedule_delayed_work(&priv->fsync_work, + msecs_to_jiffies(priv + ->ieee80211->fsync_time_interval * + priv->ieee80211->fsync_multiple_timeinterval)); } else { - if (timer_pending(&priv->fsync_timer)) - del_timer_sync(&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + - msecs_to_jiffies(priv->ieee80211->fsync_time_interval); - add_timer(&priv->fsync_timer); + cancel_delayed_work_sync(&priv->fsync_work); + schedule_delayed_work(&priv->fsync_work, + msecs_to_jiffies(priv + ->ieee80211->fsync_time_interval)); } } else { /* Let Register return to default value; */ @@ -2695,7 +2695,7 @@ static void dm_EndSWFsync(struct net_device *dev) struct r8192_priv *priv = ieee80211_priv(dev);
RT_TRACE(COMP_HALDM, "%s\n", __func__); - del_timer_sync(&(priv->fsync_timer)); + cancel_delayed_work_sync(&priv->fsync_work);
/* Let Register return to default value; */ if (priv->bswitch_fsync) { @@ -2736,11 +2736,9 @@ static void dm_StartSWFsync(struct net_device *dev) if (priv->ieee80211->fsync_rate_bitmap & rateBitmap) priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex]; } - if (timer_pending(&priv->fsync_timer)) - del_timer_sync(&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + - msecs_to_jiffies(priv->ieee80211->fsync_time_interval); - add_timer(&priv->fsync_timer); + cancel_delayed_work_sync(&priv->fsync_work); + schedule_delayed_work(&priv->fsync_work, + msecs_to_jiffies(priv->ieee80211->fsync_time_interval));
write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd); } diff --git a/drivers/staging/rtl8192u/r8192U_dm.h b/drivers/staging/rtl8192u/r8192U_dm.h index 0b2a1c688597..2159018b4e38 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.h +++ b/drivers/staging/rtl8192u/r8192U_dm.h @@ -166,7 +166,7 @@ void dm_force_tx_fw_info(struct net_device *dev, void dm_init_edca_turbo(struct net_device *dev); void dm_rf_operation_test_callback(unsigned long data); void dm_rf_pathcheck_workitemcallback(struct work_struct *work); -void dm_fsync_timer_callback(struct timer_list *t); +void dm_fsync_work_callback(struct work_struct *work); void dm_cck_txpower_adjust(struct net_device *dev, bool binch14); void dm_shadow_init(struct net_device *dev); void dm_initialize_txpower_tracking(struct net_device *dev);
From: jianchunfu jianchunfu@cmss.chinamobile.com
[ Upstream commit b5f37a0b6f667f5c72340ca9dcd7703f261cb981 ]
Replace malloc with calloc and add memory allocating check of mon_cpus before used.
Link: https://lkml.kernel.org/r/20220615073348.6891-1-jianchunfu@cmss.chinamobile....
Fixes: 7d0dc9576dc3 ("rtla/timerlat: Add --dma-latency option") Signed-off-by: jianchunfu jianchunfu@cmss.chinamobile.com Acked-by: Daniel Bristot de Oliveira bristot@kernel.org Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/tracing/rtla/src/utils.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c index 5352167a1e75..5ae2fa96fde1 100644 --- a/tools/tracing/rtla/src/utils.c +++ b/tools/tracing/rtla/src/utils.c @@ -106,8 +106,9 @@ int parse_cpu_list(char *cpu_list, char **monitored_cpus)
nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
- mon_cpus = malloc(nr_cpus * sizeof(char)); - memset(mon_cpus, 0, (nr_cpus * sizeof(char))); + mon_cpus = calloc(nr_cpus, sizeof(char)); + if (!mon_cpus) + goto err;
for (p = cpu_list; *p; ) { cpu = atoi(p);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit a43a9f67774adbd575d10ec88824016fbe034777 ]
If hl_mmu_prefetch_cache_range() fails then this code calls mutex_unlock(&ctx->mmu_lock) when it's no longer holding the mutex.
Fixes: 9e495e24003e ("habanalabs: do MMU prefetch as deferred work") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Oded Gabbay ogabbay@kernel.org Signed-off-by: Oded Gabbay ogabbay@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/misc/habanalabs/common/memory.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c index 663dd7e589d4..d5e6500f8a1f 100644 --- a/drivers/misc/habanalabs/common/memory.c +++ b/drivers/misc/habanalabs/common/memory.c @@ -1245,16 +1245,16 @@ static int map_device_va(struct hl_ctx *ctx, struct hl_mem_in *args, u64 *device rc = map_phys_pg_pack(ctx, ret_vaddr, phys_pg_pack); if (rc) { dev_err(hdev->dev, "mapping page pack failed for handle %u\n", handle); + mutex_unlock(&ctx->mmu_lock); goto map_err; }
rc = hl_mmu_invalidate_cache_range(hdev, false, *vm_type | MMU_OP_SKIP_LOW_CACHE_INV, ctx->asid, ret_vaddr, phys_pg_pack->total_size); + mutex_unlock(&ctx->mmu_lock); if (rc) goto map_err;
- mutex_unlock(&ctx->mmu_lock); - /* * prefetch is done upon user's request. it is performed in WQ as and so can * be outside the MMU lock. the operation itself is already protected by the mmu lock @@ -1283,8 +1283,6 @@ static int map_device_va(struct hl_ctx *ctx, struct hl_mem_in *args, u64 *device return rc;
map_err: - mutex_unlock(&ctx->mmu_lock); - if (add_va_block(hdev, va_range, ret_vaddr, ret_vaddr + phys_pg_pack->total_size - 1)) dev_warn(hdev->dev,
From: Bhupesh Sharma bhupesh.sharma@linaro.org
[ Upstream commit 8574adf5222d786b747022c6edcbcdddf409a139 ]
Rob pointed some remaining issues in the sdhci-msm yaml bindings (via [1]).
Fix the same by first using the 'mmc-controller.yaml' as 'ref' and thereafter also fix the issues reported by 'make dtbs_check' check.
[1]. https://lore.kernel.org/linux-arm-msm/YnLmNCwNfoqZln12@robh.at.kernel.org/
Fixes: a45537723f4b ("dt-bindings: mmc: sdhci-msm: Convert bindings to yaml") Cc: Bjorn Andersson bjorn.andersson@linaro.org Cc: Rob Herring robh@kernel.org Cc: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Bhupesh Sharma bhupesh.sharma@linaro.org Link: https://lore.kernel.org/r/20220514220116.1008254-1-bhupesh.sharma@linaro.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../devicetree/bindings/mmc/sdhci-msm.yaml | 52 ++++++++++++++++--- 1 file changed, 44 insertions(+), 8 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml index e4236334e748..31a3ce208e1a 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml @@ -17,6 +17,9 @@ description: properties: compatible: oneOf: + - enum: + - qcom,sdhci-msm-v4 + deprecated: true - items: - enum: - qcom,apq8084-sdhci @@ -27,6 +30,9 @@ properties: - qcom,msm8992-sdhci - qcom,msm8994-sdhci - qcom,msm8996-sdhci + - const: qcom,sdhci-msm-v4 # for sdcc versions less than 5.0 + - items: + - enum: - qcom,qcs404-sdhci - qcom,sc7180-sdhci - qcom,sc7280-sdhci @@ -38,12 +44,7 @@ properties: - qcom,sm6350-sdhci - qcom,sm8150-sdhci - qcom,sm8250-sdhci - - enum: - - qcom,sdhci-msm-v4 # for sdcc versions less than 5.0 - - qcom,sdhci-msm-v5 # for sdcc version 5.0 - - items: - - const: qcom,sdhci-msm-v4 # Deprecated (only for backward compatibility) - # for sdcc versions less than 5.0 + - const: qcom,sdhci-msm-v5 # for sdcc version 5.0
reg: minItems: 1 @@ -53,6 +54,28 @@ properties: - description: CQE register map - description: Inline Crypto Engine register map
+ reg-names: + minItems: 1 + maxItems: 4 + oneOf: + - items: + - const: hc_mem + - items: + - const: hc_mem + - const: core_mem + - items: + - const: hc_mem + - const: cqe_mem + - items: + - const: hc_mem + - const: cqe_mem + - const: ice_mem + - items: + - const: hc_mem + - const: core_mem + - const: cqe_mem + - const: ice_mem + clocks: minItems: 3 items: @@ -121,6 +144,16 @@ properties: description: A phandle to sdhci power domain node maxItems: 1
+ mmc-ddr-1_8v: true + + mmc-hs200-1_8v: true + + mmc-hs400-1_8v: true + + bus-width: true + + max-frequency: true + patternProperties: '^opp-table(-[a-z0-9]+)?$': if: @@ -140,7 +173,10 @@ required: - clock-names - interrupts
-additionalProperties: true +allOf: + - $ref: mmc-controller.yaml# + +unevaluatedProperties: false
examples: - | @@ -149,7 +185,7 @@ examples: #include <dt-bindings/clock/qcom,rpmh.h> #include <dt-bindings/power/qcom-rpmpd.h>
- sdhc_2: sdhci@8804000 { + sdhc_2: mmc@8804000 { compatible = "qcom,sm8250-sdhci", "qcom,sdhci-msm-v5"; reg = <0 0x08804000 0 0x1000>;
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit b5899a3e2f783a27b268e38d37f9b24c71bddf45 ]
of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak. of_node_put() checks null pointer.
Fixes: ea35645a3c66 ("mmc: sdhci-of-esdhc: add support for signal voltage switch") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220523144255.10310-1-linmq006@gmail.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-of-esdhc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index d9dc41143bb3..8b3d8119f388 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -904,6 +904,7 @@ static int esdhc_signal_voltage_switch(struct mmc_host *mmc, scfg_node = of_find_matching_node(NULL, scfg_device_ids); if (scfg_node) scfg_base = of_iomap(scfg_node, 0); + of_node_put(scfg_node); if (scfg_base) { sdhciovselcr = SDHCIOVSELCR_TGLEN | SDHCIOVSELCR_VSELVAL;
From: Fabio Estevam festevam@gmail.com
[ Upstream commit 7dc65e3c0ef4b746a583b7c58f99873fddf5ccfa ]
Change the of_device_get_match_data() cast to (uintptr_t) to silence the following clang warning:
drivers/mmc/host/mxcmmc.c:1028:18: warning: cast to smaller integer type 'enum mxcmci_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
Reported-by: kernel test robot lkp@intel.com Fixes: 8223e885e74b ("mmc: mxc: Convert the driver to DT-only") Signed-off-by: Fabio Estevam festevam@gmail.com Link: https://lore.kernel.org/r/20220526010022.1163483-1-festevam@gmail.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/mxcmmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index de04b5afef2e..613f13306433 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -1025,7 +1025,7 @@ static int mxcmci_probe(struct platform_device *pdev) mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; mmc->max_seg_size = mmc->max_req_size;
- host->devtype = (enum mxcmci_type)of_device_get_match_data(&pdev->dev); + host->devtype = (uintptr_t)of_device_get_match_data(&pdev->dev);
/* adjust max_segs after devtype detection */ if (!is_mpc512x_mmc(host))
From: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com
[ Upstream commit 0dac1e498f8130fdacfdd5289e3a7ac87ec1b9ad ]
In case of devm_reset_control_get_optional_exclusive() failure we returned directly instead of jumping to the error path to roll back initialization.
This patch moves devm_reset_control_get_optional_exclusive() early in the probe so that we have the reset handle prior to initialization of the hardware.
Fixes: b4d86f37eacb7 ("mmc: renesas_sdhi: do hard reset if possible") Reported-by: Pavel Machek pavel@denx.de Signed-off-by: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Wolfram Sang wsa+renesas@sang-engineering.com Link: https://lore.kernel.org/r/20220624181438.4355-2-prabhakar.mahadev-lad.rj@bp.... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/renesas_sdhi_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index 4404ca1f98d8..0d258b6e1a43 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -938,6 +938,10 @@ int renesas_sdhi_probe(struct platform_device *pdev, if (IS_ERR(priv->clk_cd)) return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cd), "cannot get cd clock");
+ priv->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); + if (IS_ERR(priv->rstc)) + return PTR_ERR(priv->rstc); + priv->pinctrl = devm_pinctrl_get(&pdev->dev); if (!IS_ERR(priv->pinctrl)) { priv->pins_default = pinctrl_lookup_state(priv->pinctrl, @@ -1030,10 +1034,6 @@ int renesas_sdhi_probe(struct platform_device *pdev, if (ret) goto efree;
- priv->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); - if (IS_ERR(priv->rstc)) - return PTR_ERR(priv->rstc); - ver = sd_ctrl_read16(host, CTL_VERSION); /* GEN2_SDR104 is first known SDHI to use 32bit block count */ if (ver < SDHI_VER_GEN2_SDR104 && mmc_data->max_blk_count > U16_MAX)
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 2e531bc3e0d86362fcd8a577b3278d9ef3cc2ba0 ]
Some functions of the bitmap API take advantage of the fact that a bitmap is an array of long.
So, to make sure this assertion is correct, allocate bitmaps with bitmap_zalloc() instead of kzalloc()+hand-computed number of bytes.
While at it, also use bitmap_free() instead of kfree() to keep the semantic.
Fixes: 0ab30494bc4f ("memstick: add support for legacy memorysticks") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/dbf633c48c24ae6d95f852557e8d8b3bbdef65fe.165615571... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memstick/core/ms_block.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c index 3993bdd4b519..f8f151163667 100644 --- a/drivers/memstick/core/ms_block.c +++ b/drivers/memstick/core/ms_block.c @@ -1341,17 +1341,17 @@ static int msb_ftl_initialize(struct msb_data *msb) msb->zone_count = msb->block_count / MS_BLOCKS_IN_ZONE; msb->logical_block_count = msb->zone_count * 496 - 2;
- msb->used_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL); - msb->erased_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL); + msb->used_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL); + msb->erased_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL); msb->lba_to_pba_table = kmalloc_array(msb->logical_block_count, sizeof(u16), GFP_KERNEL);
if (!msb->used_blocks_bitmap || !msb->lba_to_pba_table || !msb->erased_blocks_bitmap) { - kfree(msb->used_blocks_bitmap); + bitmap_free(msb->used_blocks_bitmap); + bitmap_free(msb->erased_blocks_bitmap); kfree(msb->lba_to_pba_table); - kfree(msb->erased_blocks_bitmap); return -ENOMEM; }
@@ -1946,7 +1946,7 @@ static DEFINE_MUTEX(msb_disk_lock); /* protects against races in open/release */ static void msb_data_clear(struct msb_data *msb) { kfree(msb->boot_page); - kfree(msb->used_blocks_bitmap); + bitmap_free(msb->used_blocks_bitmap); kfree(msb->lba_to_pba_table); kfree(msb->cache); msb->card = NULL;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 54eb7a55be6779c4d0c25eaf5056498a28595049 ]
'erased_blocks_bitmap' is never freed. As it is allocated at the same time as 'used_blocks_bitmap', it is likely that it should be freed also at the same time.
Add the corresponding bitmap_free() in msb_data_clear().
Fixes: 0ab30494bc4f ("memstick: add support for legacy memorysticks") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/b3b78926569445962ea5c3b6e9102418a9effb88.165615571... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memstick/core/ms_block.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c index f8f151163667..f8fdf88fb240 100644 --- a/drivers/memstick/core/ms_block.c +++ b/drivers/memstick/core/ms_block.c @@ -1947,6 +1947,7 @@ static void msb_data_clear(struct msb_data *msb) { kfree(msb->boot_page); bitmap_free(msb->used_blocks_bitmap); + bitmap_free(msb->erased_blocks_bitmap); kfree(msb->lba_to_pba_table); kfree(msb->cache); msb->card = NULL;
From: Eugen Hristev eugen.hristev@microchip.com
[ Upstream commit 5987e6ded29d52e42fc7b06aa575c60a25eee38e ]
In set_uhs_signaling, the DDR bit is being set by fully writing the MC1R register. This can lead to accidental erase of certain bits in this register. Avoid this by doing a read-modify-write operation.
Fixes: d0918764c17b ("mmc: sdhci-of-at91: fix MMC_DDR_52 timing selection") Signed-off-by: Eugen Hristev eugen.hristev@microchip.com Tested-by: Karl Olsen karl@micro-technic.com Acked-by: Adrian Hunter adrian.hunter@intel.com Link: https://lore.kernel.org/r/20220630090926.15061-1-eugen.hristev@microchip.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-of-at91.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c index 10fb4cb2c731..cd0134580a90 100644 --- a/drivers/mmc/host/sdhci-of-at91.c +++ b/drivers/mmc/host/sdhci-of-at91.c @@ -100,8 +100,13 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock) static void sdhci_at91_set_uhs_signaling(struct sdhci_host *host, unsigned int timing) { - if (timing == MMC_TIMING_MMC_DDR52) - sdhci_writeb(host, SDMMC_MC1R_DDR, SDMMC_MC1R); + u8 mc1r; + + if (timing == MMC_TIMING_MMC_DDR52) { + mc1r = sdhci_readb(host, SDMMC_MC1R); + mc1r |= SDMMC_MC1R_DDR; + sdhci_writeb(host, mc1r, SDMMC_MC1R); + } sdhci_set_uhs_signaling(host, timing); }
From: Liang He windhl@126.com
[ Upstream commit d17e37c41b7ed38459957a5d2968ba61516fd5c2 ]
We should use of_node_put() for the reference 'node' returned by of_parse_phandle() which will increase the refcount.
Fixes: fec9b625095f ("of: Add plumbing for restricted DMA pool") Co-authored-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Liang He windhl@126.com Signed-off-by: Rob Herring robh@kernel.org Link: https://lore.kernel.org/r/20220702014449.263772-1-windhl@126.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/of/device.c b/drivers/of/device.c index 874f031442dc..75b6cbffa755 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -81,8 +81,11 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np) * restricted-dma-pool region is allowed. */ if (of_device_is_compatible(node, "restricted-dma-pool") && - of_device_is_available(node)) + of_device_is_available(node)) { + of_node_put(node); break; + } + of_node_put(node); }
/*
From: Christian Loehle CLoehle@hyperstone.com
[ Upstream commit b3fa3e6dccc465969721b8bd2824213bd235efeb ]
Cards with 4k native sector size may only be read 4k-aligned, accommodate for this in the single read recovery and use it.
Fixes: 81196976ed946 (mmc: block: Add blk-mq support) Signed-off-by: Christian Loehle cloehle@hyperstone.com Acked-by: Adrian Hunter adrian.hunter@intel.com Reviewed-by: Avri Altman avri.altman@wdc.com Link: https://lore.kernel.org/r/cf4f316274c5474586d0d99b17db4a4c@hyperstone.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/core/block.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index f4a1281658db..912a398a9a76 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -176,7 +176,7 @@ static inline int mmc_blk_part_switch(struct mmc_card *card, unsigned int part_type); static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, struct mmc_card *card, - int disable_multi, + int recovery_mode, struct mmc_queue *mq); static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
@@ -1302,7 +1302,7 @@ static void mmc_blk_eval_resp_error(struct mmc_blk_request *brq) }
static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, - int disable_multi, bool *do_rel_wr_p, + int recovery_mode, bool *do_rel_wr_p, bool *do_data_tag_p) { struct mmc_blk_data *md = mq->blkdata; @@ -1368,12 +1368,12 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, brq->data.blocks--;
/* - * After a read error, we redo the request one sector + * After a read error, we redo the request one (native) sector * at a time in order to accurately determine which * sectors can be read successfully. */ - if (disable_multi) - brq->data.blocks = 1; + if (recovery_mode) + brq->data.blocks = queue_physical_block_size(mq->queue) >> 9;
/* * Some controllers have HW issues while operating @@ -1590,7 +1590,7 @@ static int mmc_blk_cqe_issue_rw_rq(struct mmc_queue *mq, struct request *req)
static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, struct mmc_card *card, - int disable_multi, + int recovery_mode, struct mmc_queue *mq) { u32 readcmd, writecmd; @@ -1599,7 +1599,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, struct mmc_blk_data *md = mq->blkdata; bool do_rel_wr, do_data_tag;
- mmc_blk_data_prep(mq, mqrq, disable_multi, &do_rel_wr, &do_data_tag); + mmc_blk_data_prep(mq, mqrq, recovery_mode, &do_rel_wr, &do_data_tag);
brq->mrq.cmd = &brq->cmd;
@@ -1690,7 +1690,7 @@ static int mmc_blk_fix_state(struct mmc_card *card, struct request *req)
#define MMC_READ_SINGLE_RETRIES 2
-/* Single sector read during recovery */ +/* Single (native) sector read during recovery */ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req) { struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req); @@ -1698,6 +1698,7 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req) struct mmc_card *card = mq->card; struct mmc_host *host = card->host; blk_status_t error = BLK_STS_OK; + size_t bytes_per_read = queue_physical_block_size(mq->queue);
do { u32 status; @@ -1732,13 +1733,13 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req) else error = BLK_STS_OK;
- } while (blk_update_request(req, error, 512)); + } while (blk_update_request(req, error, bytes_per_read));
return;
error_exit: mrq->data->bytes_xfered = 0; - blk_update_request(req, BLK_STS_IOERR, 512); + blk_update_request(req, BLK_STS_IOERR, bytes_per_read); /* Let it try the remaining request again */ if (mqrq->retries > MMC_MAX_RETRIES - 1) mqrq->retries = MMC_MAX_RETRIES - 1; @@ -1879,10 +1880,9 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req) return; }
- /* FIXME: Missing single sector read for large sector size */ - if (!mmc_large_sector(card) && rq_data_dir(req) == READ && - brq->data.blocks > 1) { - /* Read one sector at a time */ + if (rq_data_dir(req) == READ && brq->data.blocks > + queue_physical_block_size(mq->queue) >> 9) { + /* Read one (native) sector at a time */ mmc_blk_read_single(mq, req); return; }
From: Claudio Imbrenda imbrenda@linux.ibm.com
[ Upstream commit faa2f72cb3569256480c5540d242c84e99965160 ]
Each secure guest must have a unique ASCE (address space control element); we must avoid that new guests use the same page for their ASCE, to avoid errors.
Since the ASCE mostly consists of the address of the topmost page table (plus some flags), we must not return that memory to the pool unless the ASCE is no longer in use.
Only a successful Destroy Secure Configuration UVC will make the ASCE reusable again.
If the Destroy Configuration UVC fails, the ASCE cannot be reused for a secure guest (either for the ASCE or for other memory areas). To avoid a collision, it must not be used again. This is a permanent error and the page becomes in practice unusable, so we set it aside and leak it. On failure we already leak other memory that belongs to the ultravisor (i.e. the variable and base storage for a guest) and not leaking the topmost page table was an oversight.
This error (and thus the leakage) should not happen unless the hardware is broken or KVM has some unknown serious bug.
Signed-off-by: Claudio Imbrenda imbrenda@linux.ibm.com Fixes: 29b40f105ec8d55 ("KVM: s390: protvirt: Add initial vm and cpu lifecycle handling") Reviewed-by: Janosch Frank frankja@linux.ibm.com Link: https://lore.kernel.org/r/20220628135619.32410-2-imbrenda@linux.ibm.com Message-Id: 20220628135619.32410-2-imbrenda@linux.ibm.com Signed-off-by: Janosch Frank frankja@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/include/asm/gmap.h | 2 + arch/s390/kvm/pv.c | 9 ++-- arch/s390/mm/gmap.c | 86 ++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 3 deletions(-)
diff --git a/arch/s390/include/asm/gmap.h b/arch/s390/include/asm/gmap.h index 40264f60b0da..f4073106e1f3 100644 --- a/arch/s390/include/asm/gmap.h +++ b/arch/s390/include/asm/gmap.h @@ -148,4 +148,6 @@ void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long dirty_bitmap[4], unsigned long gaddr, unsigned long vmaddr); int gmap_mark_unmergeable(void); void s390_reset_acc(struct mm_struct *mm); +void s390_unlist_old_asce(struct gmap *gmap); +int s390_replace_asce(struct gmap *gmap); #endif /* _ASM_S390_GMAP_H */ diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c index cc7c9599f43e..8eee3fc414e5 100644 --- a/arch/s390/kvm/pv.c +++ b/arch/s390/kvm/pv.c @@ -161,10 +161,13 @@ int kvm_s390_pv_deinit_vm(struct kvm *kvm, u16 *rc, u16 *rrc) atomic_set(&kvm->mm->context.is_protected, 0); KVM_UV_EVENT(kvm, 3, "PROTVIRT DESTROY VM: rc %x rrc %x", *rc, *rrc); WARN_ONCE(cc, "protvirt destroy vm failed rc %x rrc %x", *rc, *rrc); - /* Inteded memory leak on "impossible" error */ - if (!cc) + /* Intended memory leak on "impossible" error */ + if (!cc) { kvm_s390_pv_dealloc_vm(kvm); - return cc ? -EIO : 0; + return 0; + } + s390_replace_asce(kvm->arch.gmap); + return -EIO; }
int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc) diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index b8ae4a4aa2ba..85cab61d87a9 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -2735,3 +2735,89 @@ void s390_reset_acc(struct mm_struct *mm) mmput(mm); } EXPORT_SYMBOL_GPL(s390_reset_acc); + +/** + * s390_unlist_old_asce - Remove the topmost level of page tables from the + * list of page tables of the gmap. + * @gmap: the gmap whose table is to be removed + * + * On s390x, KVM keeps a list of all pages containing the page tables of the + * gmap (the CRST list). This list is used at tear down time to free all + * pages that are now not needed anymore. + * + * This function removes the topmost page of the tree (the one pointed to by + * the ASCE) from the CRST list. + * + * This means that it will not be freed when the VM is torn down, and needs + * to be handled separately by the caller, unless a leak is actually + * intended. Notice that this function will only remove the page from the + * list, the page will still be used as a top level page table (and ASCE). + */ +void s390_unlist_old_asce(struct gmap *gmap) +{ + struct page *old; + + old = virt_to_page(gmap->table); + spin_lock(&gmap->guest_table_lock); + list_del(&old->lru); + /* + * Sometimes the topmost page might need to be "removed" multiple + * times, for example if the VM is rebooted into secure mode several + * times concurrently, or if s390_replace_asce fails after calling + * s390_remove_old_asce and is attempted again later. In that case + * the old asce has been removed from the list, and therefore it + * will not be freed when the VM terminates, but the ASCE is still + * in use and still pointed to. + * A subsequent call to replace_asce will follow the pointer and try + * to remove the same page from the list again. + * Therefore it's necessary that the page of the ASCE has valid + * pointers, so list_del can work (and do nothing) without + * dereferencing stale or invalid pointers. + */ + INIT_LIST_HEAD(&old->lru); + spin_unlock(&gmap->guest_table_lock); +} +EXPORT_SYMBOL_GPL(s390_unlist_old_asce); + +/** + * s390_replace_asce - Try to replace the current ASCE of a gmap with a copy + * @gmap: the gmap whose ASCE needs to be replaced + * + * If the allocation of the new top level page table fails, the ASCE is not + * replaced. + * In any case, the old ASCE is always removed from the gmap CRST list. + * Therefore the caller has to make sure to save a pointer to it + * beforehand, unless a leak is actually intended. + */ +int s390_replace_asce(struct gmap *gmap) +{ + unsigned long asce; + struct page *page; + void *table; + + s390_unlist_old_asce(gmap); + + page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER); + if (!page) + return -ENOMEM; + table = page_to_virt(page); + memcpy(table, gmap->table, 1UL << (CRST_ALLOC_ORDER + PAGE_SHIFT)); + + /* + * The caller has to deal with the old ASCE, but here we make sure + * the new one is properly added to the CRST list, so that + * it will be freed when the VM is torn down. + */ + spin_lock(&gmap->guest_table_lock); + list_add(&page->lru, &gmap->crst_list); + spin_unlock(&gmap->guest_table_lock); + + /* Set new table origin while preserving existing ASCE control bits */ + asce = (gmap->asce & ~_ASCE_ORIGIN) | __pa(table); + WRITE_ONCE(gmap->asce, asce); + WRITE_ONCE(gmap->mm->context.gmap_asce, asce); + WRITE_ONCE(gmap->table, table); + + return 0; +} +EXPORT_SYMBOL_GPL(s390_replace_asce);
From: Stefan Roese sr@denx.de
[ Upstream commit 8795e182b02dc87e343c79e73af6b8b7f9c5e635 ]
AER reporting is currently disabled in the DevCtl registers of all non Root Port PCIe devices on systems using pcie_ports_native || host->native_aer, disabling AER completely in such systems. This is because 2bd50dd800b5 ("PCI: PCIe: Disable PCIe port services during port initialization"), added a call to pci_disable_pcie_error_reporting() *after* the AER setup was completed for the PCIe device tree.
Here a longer analysis about the current status of AER enabling / disabling upon bootup provided by Bjorn:
pcie_portdrv_probe pcie_port_device_register get_port_device_capability pci_disable_pcie_error_reporting clear CERE NFERE FERE URRE # <-- disable for RP USP DSP pcie_device_init device_register # new AER service device aer_probe aer_enable_rootport # RP only set_downstream_devices_error_reporting set_device_error_reporting # self (RP) if (RP || USP || DSP) pci_enable_pcie_error_reporting set CERE NFERE FERE URRE # <-- enable for RP pci_walk_bus set_device_error_reporting if (RP || USP || DSP) pci_enable_pcie_error_reporting set CERE NFERE FERE URRE # <-- enable for USP DSP
In a typical Root Port -> Endpoint hierarchy, the above: - Disables Error Reporting for the Root Port, - Enables Error Reporting for the Root Port, - Does NOT enable Error Reporting for the Endpoint because it is not a Root Port or Switch Port.
In a deeper Root Port -> Upstream Switch Port -> Downstream Switch Port -> Endpoint hierarchy: - Disables Error Reporting for the Root Port, - Enables Error Reporting for the Root Port, - Enables Error Reporting for both Switch Ports, - Does NOT enable Error Reporting for the Endpoint because it is not a Root Port or Switch Port, - Disables Error Reporting for the Switch Ports when pcie_portdrv_probe() claims them. AER does not re-enable it because these are not Root Ports.
Remove this call to pci_disable_pcie_error_reporting() from get_port_device_capability(), leaving the already enabled AER configuration intact. With this change, AER is enabled in the Root Port and the PCIe switch upstream and downstream ports. Only the PCIe Endpoints don't have AER enabled yet. A follow-up patch will take care of this Endpoint enabling.
Fixes: 2bd50dd800b5 ("PCI: PCIe: Disable PCIe port services during port initialization") Link: https://lore.kernel.org/r/20220125071820.2247260-3-sr@denx.de Signed-off-by: Stefan Roese sr@denx.de Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Pali Rohár pali@kernel.org Cc: Rafael J. Wysocki rjw@rjwysocki.net Cc: Bharat Kumar Gogada bharat.kumar.gogada@xilinx.com Cc: Michal Simek michal.simek@xilinx.com Cc: Yao Hongbo yaohongbo@linux.alibaba.com Cc: Naveen Naidu naveennaidu479@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pcie/portdrv_core.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 604feeb84ee4..1ac7fec47d6f 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -222,15 +222,8 @@ static int get_port_device_capability(struct pci_dev *dev)
#ifdef CONFIG_PCIEAER if (dev->aer_cap && pci_aer_available() && - (pcie_ports_native || host->native_aer)) { + (pcie_ports_native || host->native_aer)) services |= PCIE_PORT_SERVICE_AER; - - /* - * Disable AER on this port in case it's been enabled by the - * BIOS (the AER service driver will enable it when necessary). - */ - pci_disable_pcie_error_reporting(dev); - } #endif
/* Root Ports and Root Complex Event Collectors may generate PMEs */
From: Christian Marangi ansuelsmth@gmail.com
[ Upstream commit 38f897ae3d44900f627cad708a15db498ce2ca31 ]
We currently enable clocks BEFORE we write to PARF_PHY_CTRL reg to enable clocks and resets. This causes the driver to never set to a ready state with the error 'Phy link never came up'.
This is caused by the PHY clock getting enabled before setting the required bits in the PARF regs.
A workaround for this was set but with this new discovery we can drop the workaround and use a proper solution to the problem by just enabling the clock only AFTER the PARF_PHY_CTRL bit is set.
This correctly sets up the PCIe link and makes it usable even when a bootloader leaves the PCIe link in an undefined state.
Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver") Link: https://lore.kernel.org/r/20220708222743.27019-1-ansuelsmth@gmail.com Signed-off-by: Christian Marangi ansuelsmth@gmail.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-qcom.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 2ea13750b492..da13a66ced14 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -337,8 +337,6 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) reset_control_assert(res->ext_reset); reset_control_assert(res->phy_reset);
- writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL); - ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies); if (ret < 0) { dev_err(dev, "cannot enable regulators\n"); @@ -381,15 +379,15 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) goto err_deassert_axi; }
- ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks); - if (ret) - goto err_clks; - /* enable PCIe clocks and resets */ val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); val &= ~BIT(0); writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks); + if (ret) + goto err_clks; + if (of_device_is_compatible(node, "qcom,pcie-ipq8064") || of_device_is_compatible(node, "qcom,pcie-ipq8064-v2")) { writel(PCS_DEEMPH_TX_DEEMPH_GEN1(24) |
From: Mahesh Rajashekhara Mahesh.Rajashekhara@microchip.com
[ Upstream commit 69695aeaa6621bc49cdd7a8e5a8d1042461e496e ]
Correct a SOP READ and WRITE DMA flags for some requests.
This update corrects DMA direction issues with SCSI commands removed from the controller's internal lookup table.
Currently, SCSI READ BLOCK LIMITS (0x5) was removed from the controller lookup table and exposed a DMA direction flag issue.
SCSI READ BLOCK LIMITS was recently removed from our controller lookup table so the controller uses the respective IU flag field to set the DMA data direction. Since the DMA direction is incorrect the FW never completes the request causing a hang.
Some SCSI commands which use SCSI READ BLOCK LIMITS
* sg_map * mt -f /dev/stX status
After updating controller firmware, users may notice their tape units failing. This patch resolves the issue.
Also, the AIO path DMA direction is correct.
The DMA direction flag is a day-one bug with no reported BZ.
Fixes: 6c223761eb54 ("smartpqi: initial commit of Microsemi smartpqi driver") Link: https://lore.kernel.org/r/165730605618.177165.9054223644512926624.stgit@brun... Reviewed-by: Scott Benesh scott.benesh@microchip.com Reviewed-by: Scott Teel scott.teel@microchip.com Reviewed-by: Mike McGowen mike.mcgowen@microchip.com Reviewed-by: Kevin Barnett kevin.barnett@microchip.com Signed-off-by: Mahesh Rajashekhara Mahesh.Rajashekhara@microchip.com Signed-off-by: Don Brace don.brace@microchip.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/smartpqi/smartpqi_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 7c0d069a3158..e1fc6f5b9612 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -5484,10 +5484,10 @@ static int pqi_raid_submit_scsi_cmd_with_io_request( }
switch (scmd->sc_data_direction) { - case DMA_TO_DEVICE: + case DMA_FROM_DEVICE: request->data_direction = SOP_READ_FLAG; break; - case DMA_FROM_DEVICE: + case DMA_TO_DEVICE: request->data_direction = SOP_WRITE_FLAG; break; case DMA_NONE:
From: Max Filippov jcmvbkbc@gmail.com
[ Upstream commit 8864fb8359682912ee99235db7db916733a1fd7b ]
Provide release() callback for the platform device embedded into struct iss_net_private and registered in the iss_net_configure so that platform_device_unregister could be called for it.
Signed-off-by: Max Filippov jcmvbkbc@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/xtensa/platforms/iss/network.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c index fd84d4891758..f0c652c1b438 100644 --- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c @@ -472,6 +472,15 @@ static const struct net_device_ops iss_netdev_ops = { .ndo_set_rx_mode = iss_net_set_multicast_list, };
+static void iss_net_pdev_release(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct iss_net_private *lp = + container_of(pdev, struct iss_net_private, pdev); + + free_netdev(lp->dev); +} + static int iss_net_configure(int index, char *init) { struct net_device *dev; @@ -527,6 +536,7 @@ static int iss_net_configure(int index, char *init)
lp->pdev.id = index; lp->pdev.name = DRIVER_NAME; + lp->pdev.dev.release = iss_net_pdev_release; platform_device_register(&lp->pdev); SET_NETDEV_DEV(dev, &lp->pdev.dev);
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 628ccfc8f5f79dd548319408fcc53949fe97b258 ]
The 'pdev' and 'netdev' need to be released in error cases of iss_net_configure().
Change the return type of iss_net_configure() to void, because it's not used.
Fixes: 7282bee78798 ("[PATCH] xtensa: Architecture support for Tensilica Xtensa Part 8") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Max Filippov jcmvbkbc@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/xtensa/platforms/iss/network.c | 32 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c index f0c652c1b438..3805dc2c259c 100644 --- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c @@ -481,16 +481,15 @@ static void iss_net_pdev_release(struct device *dev) free_netdev(lp->dev); }
-static int iss_net_configure(int index, char *init) +static void iss_net_configure(int index, char *init) { struct net_device *dev; struct iss_net_private *lp; - int err;
dev = alloc_etherdev(sizeof(*lp)); if (dev == NULL) { pr_err("eth_configure: failed to allocate device\n"); - return 1; + return; }
/* Initialize private element. */ @@ -518,7 +517,7 @@ static int iss_net_configure(int index, char *init) if (!tuntap_probe(lp, index, init)) { pr_err("%s: invalid arguments. Skipping device!\n", dev->name); - goto errout; + goto err_free_netdev; }
pr_info("Netdevice %d (%pM)\n", index, dev->dev_addr); @@ -526,7 +525,8 @@ static int iss_net_configure(int index, char *init) /* sysfs register */
if (!driver_registered) { - platform_driver_register(&iss_net_driver); + if (platform_driver_register(&iss_net_driver)) + goto err_free_netdev; driver_registered = 1; }
@@ -537,7 +537,8 @@ static int iss_net_configure(int index, char *init) lp->pdev.id = index; lp->pdev.name = DRIVER_NAME; lp->pdev.dev.release = iss_net_pdev_release; - platform_device_register(&lp->pdev); + if (platform_device_register(&lp->pdev)) + goto err_free_netdev; SET_NETDEV_DEV(dev, &lp->pdev.dev);
dev->netdev_ops = &iss_netdev_ops; @@ -546,23 +547,20 @@ static int iss_net_configure(int index, char *init) dev->irq = -1;
rtnl_lock(); - err = register_netdevice(dev); - rtnl_unlock(); - - if (err) { + if (register_netdevice(dev)) { + rtnl_unlock(); pr_err("%s: error registering net device!\n", dev->name); - /* XXX: should we call ->remove() here? */ - free_netdev(dev); - return 1; + platform_device_unregister(&lp->pdev); + return; } + rtnl_unlock();
timer_setup(&lp->tl, iss_net_user_timer_expire, 0);
- return 0; + return;
-errout: - /* FIXME: unregister; free, etc.. */ - return -EIO; +err_free_netdev: + free_netdev(dev); }
/* ------------------------------------------------------------------------- */
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 8097cf2fb3b2205257f1c76f4808e3398d66b6d9 ]
USB_AMD5536UDC should depend on HAS_DMA since it selects USB_SNP_CORE, which depends on HAS_DMA and since 'select' does not follow any dependency chains.
Fixes this kconfig warning:
WARNING: unmet direct dependencies detected for USB_SNP_CORE Depends on [n]: USB_SUPPORT [=y] && USB_GADGET [=y] && (USB_AMD5536UDC [=y] || USB_SNP_UDC_PLAT [=n]) && HAS_DMA [=n] Selected by [y]: - USB_AMD5536UDC [=y] && USB_SUPPORT [=y] && USB_GADGET [=y] && USB_PCI [=y]
Fixes: 97b3ffa233b9 ("usb: gadget: udc: amd5536: split core and PCI layer") Cc: Raviteja Garimella raviteja.garimella@broadcom.com Cc: Felipe Balbi balbi@kernel.org Cc: linux-usb@vger.kernel.org Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Randy Dunlap rdunlap@infradead.org Link: https://lore.kernel.org/r/20220709013601.7536-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/udc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 69394dc1cdfb..2cdd37be165a 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -311,7 +311,7 @@ source "drivers/usb/gadget/udc/bdc/Kconfig"
config USB_AMD5536UDC tristate "AMD5536 UDC" - depends on USB_PCI + depends on USB_PCI && HAS_DMA select USB_SNP_CORE help The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge.
From: Liang He windhl@126.com
[ Upstream commit 220fafb4ed04187e9c17be4152da5a7f2ffbdd8c ]
We should call of_node_put() for the reference returned by of_get_child_by_name() which has increased the refcount.
Fixes: 30d2617fd7ed ("usb: gadget: aspeed: allow to set usb strings in device tree") Signed-off-by: Liang He windhl@126.com Link: https://lore.kernel.org/r/20220713120528.368168-1-windhl@126.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/udc/aspeed-vhub/hub.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/hub.c b/drivers/usb/gadget/udc/aspeed-vhub/hub.c index 65cd4e46f031..e2207d014620 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c @@ -1059,8 +1059,10 @@ static int ast_vhub_init_desc(struct ast_vhub *vhub) /* Initialize vhub String Descriptors. */ INIT_LIST_HEAD(&vhub->vhub_str_desc); desc_np = of_get_child_by_name(vhub_np, "vhub-strings"); - if (desc_np) + if (desc_np) { ret = ast_vhub_of_parse_str_desc(vhub, desc_np); + of_node_put(desc_np); + } else ret = ast_vhub_str_alloc_add(vhub, &ast_vhub_strings);
From: Thinh Nguyen Thinh.Nguyen@synopsys.com
[ Upstream commit afbd04e66e5d16ca3c7ea2e3c56eca25558eacf3 ]
Synopsys IP DWC_usb32 and DWC_usb31 version 1.90a and above deprecated GCTL.CORESOFTRESET. The DRD mode switching flow is updated to remove the GCTL soft reset. Add version checks to prevent using deprecated setting in mode switching flow.
Signed-off-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Link: https://lore.kernel.org/r/9df529fde6e55f5508321b6bc26e92848044ef2b.165533896... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 573421984948..4c753cc0fa61 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -159,7 +159,8 @@ static void __dwc3_set_mode(struct work_struct *work) }
/* For DRD host or device mode only */ - if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { + if ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) && + dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg);
From: Rohith Kollalsi quic_rkollals@quicinc.com
[ Upstream commit 07903626d98853e605fe63e5ce149f1b7314bbea ]
According to the programming guide, it is recommended to perform a GCTL_CORE_SOFTRESET only when switching the mode from device to host or host to device. However, it is found that during bootup when __dwc3_set_mode() is called for the first time, GCTL_CORESOFTRESET is done with suspendable bit(BIT 17) of DWC3_GUSB3PIPECTL set. This some times leads to issues like controller going into bad state and controller registers reading value zero. Until GCTL_CORESOFTRESET is done and run/stop bit is set core initialization is not complete. Setting suspendable bit of DWC3_GUSB3PIPECTL and then performing GCTL_CORESOFTRESET is therefore not recommended. Avoid this by only performing the reset if current_dr_role is set, that is, when doing subsequent role switching.
Fixes: f88359e1588b ("usb: dwc3: core: Do core softreset when switch mode") Signed-off-by: Rohith Kollalsi quic_rkollals@quicinc.com Link: https://lore.kernel.org/r/20220714045625.20377-1-quic_rkollals@quicinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 4c753cc0fa61..ba2fa91be1d6 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -158,9 +158,13 @@ static void __dwc3_set_mode(struct work_struct *work) break; }
- /* For DRD host or device mode only */ - if ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) && - dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { + /* + * When current_dr_role is not set, there's no role switching. + * Only perform GCTL.CoreSoftReset when there's DRD role switching. + */ + if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) || + DWC3_VER_IS_PRIOR(DWC31, 190A)) && + dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) { reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg);
From: Johan Hovold johan+linaro@kernel.org
[ Upstream commit 69bb3520db7cecbccc9e497fc568fa5465c9d43f ]
Not all platforms have all of the four currently supported wakeup interrupts so use the optional irq helpers when looking up interrupts to avoid printing error messages when an optional interrupt is not found:
dwc3-qcom a6f8800.usb: error -ENXIO: IRQ hs_phy_irq not found
Fixes: a4333c3a6ba9 ("usb: dwc3: Add Qualcomm DWC3 glue driver") Reviewed-by: Andrew Halaney ahalaney@redhat.com Signed-off-by: Johan Hovold johan+linaro@kernel.org Link: https://lore.kernel.org/r/20220713131340.29401-4-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/dwc3-qcom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index 6cba990da32e..3582fd6dfa14 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -443,9 +443,9 @@ static int dwc3_qcom_get_irq(struct platform_device *pdev, int ret;
if (np) - ret = platform_get_irq_byname(pdev_irq, name); + ret = platform_get_irq_byname_optional(pdev_irq, name); else - ret = platform_get_irq(pdev_irq, num); + ret = platform_get_irq_optional(pdev_irq, num);
return ret; }
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 71d46f1ff2212ced4852c7e77c5176382a1bdcec ]
The simple_write_to_buffer() function will return positive/success if it is able to write a single byte anywhere within the buffer. However that potentially leaves a lot of the buffer uninitialized.
In this code it's better to return 0 if the offset is non-zero. This code is not written to support partial writes. And then return -EFAULT if the buffer is not completely initialized.
Fixes: cfad6425382e ("eeprom: Add IDT 89HPESx EEPROM/CSR driver") Reviewed-by: Serge Semin fancer.lancer@gmail.com Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/Ysg1Pu/nzSMe3r1q@kili Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/misc/eeprom/idt_89hpesx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c index b0cff4b152da..7f430742ce2b 100644 --- a/drivers/misc/eeprom/idt_89hpesx.c +++ b/drivers/misc/eeprom/idt_89hpesx.c @@ -909,14 +909,18 @@ static ssize_t idt_dbgfs_csr_write(struct file *filep, const char __user *ubuf, u32 csraddr, csrval; char *buf;
+ if (*offp) + return 0; + /* Copy data from User-space */ buf = kmalloc(count + 1, GFP_KERNEL); if (!buf) return -ENOMEM;
- ret = simple_write_to_buffer(buf, count, offp, ubuf, count); - if (ret < 0) + if (copy_from_user(buf, ubuf, count)) { + ret = -EFAULT; goto free_buf; + } buf[count] = 0;
/* Find position of colon in the buffer */
From: Fabrice Gasnier fabrice.gasnier@foss.st.com
[ Upstream commit 32b378a9179ae4db61cfc5d502717214e6cd1e1c ]
Error code is overridden, in case the PLL doesn't lock. So, the USB initialization can continue. This leads to a platform freeze. This can be avoided by returning proper error code to avoid USB probe freezing the platform. It also displays proper errors in log.
Fixes: 5b1af71280ab ("phy: stm32: rework PLL Lock detection") Signed-off-by: Fabrice Gasnier fabrice.gasnier@foss.st.com Link: https://lore.kernel.org/r/20220713133953.595134-1-fabrice.gasnier@foss.st.co... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/st/phy-stm32-usbphyc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c index 007a23c78d56..a98c911cc37a 100644 --- a/drivers/phy/st/phy-stm32-usbphyc.c +++ b/drivers/phy/st/phy-stm32-usbphyc.c @@ -358,7 +358,9 @@ static int stm32_usbphyc_phy_init(struct phy *phy) return 0;
pll_disable: - return stm32_usbphyc_pll_disable(usbphyc); + stm32_usbphyc_pll_disable(usbphyc); + + return ret; }
static int stm32_usbphyc_phy_exit(struct phy *phy)
From: Samuel Holland samuel@sholland.org
[ Upstream commit fd7d47484125c7d04578de9294faa7fec6e5df0a ]
When the OTG port is fixed to host mode, the driver does not request its IRQs, nor does it enable those IRQs in hardware. Similarly, the driver should ignore the OTG port IRQs when handling the shared interrupt.
Otherwise, it would update the extcon based on an ID pin which may be in an undefined state, or try to queue a uninitialized work item.
Fixes: 6a98df08ccd5 ("phy: rockchip-inno-usb2: Fix muxed interrupt support") Reported-by: Frank Wunderlich frank-w@public-files.de Signed-off-by: Samuel Holland samuel@sholland.org Tested-by: Peter Geis pgwipeout@gmail.com Tested-by: Frank Wunderlich frank-w@public-files.de Link: https://lore.kernel.org/r/20220708061434.38115-1-samuel@sholland.org Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 6e44069617df..5223d4c9afdf 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -978,7 +978,9 @@ static irqreturn_t rockchip_usb2phy_irq(int irq, void *data)
switch (rport->port_id) { case USB2PHY_PORT_OTG: - ret |= rockchip_usb2phy_otg_mux_irq(irq, rport); + if (rport->mode != USB_DR_MODE_HOST && + rport->mode != USB_DR_MODE_UNKNOWN) + ret |= rockchip_usb2phy_otg_mux_irq(irq, rport); break; case USB2PHY_PORT_HOST: ret |= rockchip_usb2phy_linestate_irq(irq, rport);
From: Peng Fan peng.fan@nxp.com
[ Upstream commit bd734481e172b4827af09c9ab06c51d2ab7201e6 ]
max_node_id not equal to the ARRAY_SIZE of node array, need increase 1, otherwise xlate will fail for the last entry. And rename max_node_id to num_nodes to reflect the reality.
Fixes: f0d8048525d7d ("interconnect: Add imx core driver") Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Peng Fan peng.fan@nxp.com Link: https://lore.kernel.org/r/20220703091132.1412063-5-peng.fan@oss.nxp.com Signed-off-by: Georgi Djakov djakov@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/interconnect/imx/imx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c index 249ca25d1d55..4406ec45fa90 100644 --- a/drivers/interconnect/imx/imx.c +++ b/drivers/interconnect/imx/imx.c @@ -234,16 +234,16 @@ int imx_icc_register(struct platform_device *pdev, struct device *dev = &pdev->dev; struct icc_onecell_data *data; struct icc_provider *provider; - int max_node_id; + int num_nodes; int ret;
/* icc_onecell_data is indexed by node_id, unlike nodes param */ - max_node_id = get_max_node_id(nodes, nodes_count); - data = devm_kzalloc(dev, struct_size(data, nodes, max_node_id), + num_nodes = get_max_node_id(nodes, nodes_count) + 1; + data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes), GFP_KERNEL); if (!data) return -ENOMEM; - data->num_nodes = max_node_id; + data->num_nodes = num_nodes;
provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL); if (!provider)
From: Kalesh Singh kaleshsingh@google.com
[ Upstream commit ed6313a93fd11d2015ad17046f3c418bf6a8dab1 ]
With CONFIG_RANDOMIZE_BASE=y vmlinux addresses will resolve incorrectly from kallsyms. Fix this by adding the KASLR offset before printing the symbols.
Fixes: 6ccf9cb557bd ("KVM: arm64: Symbolize the nVHE HYP addresses") Reported-by: Fuad Tabba tabba@google.com Signed-off-by: Kalesh Singh kaleshsingh@google.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220715235824.2549012-1-kaleshsingh@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kvm/handle_exit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index f66c0142b335..e43926ef2bc2 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -347,10 +347,10 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, kvm_err("nVHE hyp BUG at: %s:%u!\n", file, line); else kvm_err("nVHE hyp BUG at: [<%016llx>] %pB!\n", panic_addr, - (void *)panic_addr); + (void *)(panic_addr + kaslr_offset())); } else { kvm_err("nVHE hyp panic at: [<%016llx>] %pB!\n", panic_addr, - (void *)panic_addr); + (void *)(panic_addr + kaslr_offset())); }
/*
From: Christopher Obbard chris.obbard@collabora.com
[ Upstream commit 9e70cbd11b03889c92462cf52edb2bd023c798fa ]
Initialising the hwrng struct with zeros causes a compile-time sparse warning:
$ ARCH=um make -j10 W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ... CHECK arch/um/drivers/random.c arch/um/drivers/random.c:31:31: sparse: warning: Using plain integer as NULL pointer
Fix the warning by not initialising the hwrng struct with zeros as it is initialised anyway during module init.
Fixes: 72d3e093afae ("um: random: Register random as hwrng-core device") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Christopher Obbard chris.obbard@collabora.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Sasha Levin sashal@kernel.org --- arch/um/drivers/random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index 433a3f8f2ef3..32b3341fe970 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c @@ -28,7 +28,7 @@ * protects against a module being loaded twice at the same time. */ static int random_fd = -1; -static struct hwrng hwrng = { 0, }; +static struct hwrng hwrng; static DECLARE_COMPLETION(have_data);
static int rng_dev_read(struct hwrng *rng, void *buf, size_t max, bool block)
From: Patrick Wang patrick.wang.shcn@gmail.com
[ Upstream commit a317ebccaa3609917a2c021af870cf3fa607ab0c ]
Kmemleak recently added a rbtree to store the objects allocted with physical address. Those objects can't be freed with kmemleak_free().
According to the comments, percpu allocations are tracked by kmemleak separately. Kmemleak_free() was used to avoid the unnecessary tracking. If kmemleak_free() fails, those objects would be scanned by kmemleak, which is unnecessary but shouldn't lead to other effects.
Use kmemleak_ignore_phys() instead of kmemleak_free() for those objects.
Link: https://lkml.kernel.org/r/20220705113158.127600-1-patrick.wang.shcn@gmail.co... Fixes: 0c24e061196c ("mm: kmemleak: add rbtree and store physical address for objects allocated with PA") Signed-off-by: Patrick Wang patrick.wang.shcn@gmail.com Cc: Dennis Zhou dennis@kernel.org Cc: Tejun Heo tj@kernel.org Cc: Christoph Lameter cl@linux.com Cc: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/percpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mm/percpu.c b/mm/percpu.c index 3633eeefaa0d..27697b2429c2 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -3104,7 +3104,7 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size, goto out_free_areas; } /* kmemleak tracks the percpu allocations separately */ - kmemleak_free(ptr); + kmemleak_ignore_phys(__pa(ptr)); areas[group] = ptr;
base = min(ptr, base); @@ -3304,7 +3304,7 @@ int __init pcpu_page_first_chunk(size_t reserved_size, pcpu_fc_cpu_to_node_fn_t goto enomem; } /* kmemleak tracks the percpu allocations separately */ - kmemleak_free(ptr); + kmemleak_ignore_phys(__pa(ptr)); pages[j++] = virt_to_page(ptr); } } @@ -3417,7 +3417,7 @@ void __init setup_per_cpu_areas(void) if (!ai || !fc) panic("Failed to allocate memory for percpu areas."); /* kmemleak tracks the percpu allocations separately */ - kmemleak_free(fc); + kmemleak_ignore_phys(__pa(fc));
ai->dyn_size = unit_size; ai->unit_size = unit_size;
From: Mustafa Ismail mustafa.ismail@intel.com
[ Upstream commit 8ecef7890b3aea78c8bbb501a4b5b8134367b821 ]
During a destroy CQ an interrupt may cause processing of a CQE after CQ resources are freed by irdma_cq_free_rsrc(). Fix this by moving the call to irdma_cq_free_rsrc() after the irdma_sc_cleanup_ceqes(), which is called under the cq_lock.
Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs") Link: https://lore.kernel.org/r/20220705230815.265-6-shiraz.saleem@intel.com Signed-off-by: Bartosz Sobczak bartosz.sobczak@intel.com Signed-off-by: Mustafa Ismail mustafa.ismail@intel.com Signed-off-by: Shiraz Saleem shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/irdma/verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c index 96135a228f26..227a799385d1 100644 --- a/drivers/infiniband/hw/irdma/verbs.c +++ b/drivers/infiniband/hw/irdma/verbs.c @@ -1776,11 +1776,11 @@ static int irdma_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata) spin_unlock_irqrestore(&iwcq->lock, flags);
irdma_cq_wq_destroy(iwdev->rf, cq); - irdma_cq_free_rsrc(iwdev->rf, iwcq);
spin_lock_irqsave(&iwceq->ce_lock, flags); irdma_sc_cleanup_ceqes(cq, ceq); spin_unlock_irqrestore(&iwceq->ce_lock, flags); + irdma_cq_free_rsrc(iwdev->rf, iwcq);
return 0; }
From: Mustafa Ismail mustafa.ismail@intel.com
[ Upstream commit 82ab2b52654c43ba24a3f6603fec40874cc5a7e5 ]
When an application listens on a wildcard address, and there are VLAN and non-VLAN IP addresses, iWARP connection establishemnt can fail if the listen node VLAN ID does not match.
Fix this by checking the vlan_id only if not a wildcard listen node.
Fixes: 146b9756f14c ("RDMA/irdma: Add connection manager") Link: https://lore.kernel.org/r/20220705230815.265-7-shiraz.saleem@intel.com Signed-off-by: Mustafa Ismail mustafa.ismail@intel.com Signed-off-by: Shiraz Saleem shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/irdma/cm.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c index 646fa8677490..7b086fe63a24 100644 --- a/drivers/infiniband/hw/irdma/cm.c +++ b/drivers/infiniband/hw/irdma/cm.c @@ -1477,12 +1477,13 @@ irdma_find_listener(struct irdma_cm_core *cm_core, u32 *dst_addr, u16 dst_port, list_for_each_entry (listen_node, &cm_core->listen_list, list) { memcpy(listen_addr, listen_node->loc_addr, sizeof(listen_addr)); listen_port = listen_node->loc_port; + if (listen_port != dst_port || + !(listener_state & listen_node->listener_state)) + continue; /* compare node pair, return node handle if a match */ - if ((!memcmp(listen_addr, dst_addr, sizeof(listen_addr)) || - !memcmp(listen_addr, ip_zero, sizeof(listen_addr))) && - listen_port == dst_port && - vlan_id == listen_node->vlan_id && - (listener_state & listen_node->listener_state)) { + if (!memcmp(listen_addr, ip_zero, sizeof(listen_addr)) || + (!memcmp(listen_addr, dst_addr, sizeof(listen_addr)) && + vlan_id == listen_node->vlan_id)) { refcount_inc(&listen_node->refcnt); spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
From: Mustafa Ismail mustafa.ismail@intel.com
[ Upstream commit 3a844596ed71b7c12ac602f6f6b7b0f17e4d6a90 ]
Setting err_rq_idx_valid field in QP context when the AE source of the AEQE is not associated with an RQ causes the firmware flush to fail.
Set err_rq_idx_valid field in QP context only if it is associated with an RQ. Additionally, cleanup the redundant setting of this field in irdma_process_aeq.
Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions") Link: https://lore.kernel.org/r/20220705230815.265-8-shiraz.saleem@intel.com Signed-off-by: Mustafa Ismail mustafa.ismail@intel.com Signed-off-by: Shiraz Saleem shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/irdma/hw.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c index dd3943d22dc6..6bba1335993a 100644 --- a/drivers/infiniband/hw/irdma/hw.c +++ b/drivers/infiniband/hw/irdma/hw.c @@ -257,10 +257,6 @@ static void irdma_process_aeq(struct irdma_pci_f *rf) iwqp->last_aeq = info->ae_id; spin_unlock_irqrestore(&iwqp->lock, flags); ctx_info = &iwqp->ctx_info; - if (rdma_protocol_roce(&iwqp->iwdev->ibdev, 1)) - ctx_info->roce_info->err_rq_idx_valid = true; - else - ctx_info->iwarp_info->err_rq_idx_valid = true; } else { if (info->ae_id != IRDMA_AE_CQ_OPERATION_ERROR) continue; @@ -370,16 +366,12 @@ static void irdma_process_aeq(struct irdma_pci_f *rf) case IRDMA_AE_LCE_FUNCTION_CATASTROPHIC: case IRDMA_AE_LCE_CQ_CATASTROPHIC: case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG: - if (rdma_protocol_roce(&iwdev->ibdev, 1)) - ctx_info->roce_info->err_rq_idx_valid = false; - else - ctx_info->iwarp_info->err_rq_idx_valid = false; - fallthrough; default: ibdev_err(&iwdev->ibdev, "abnormal ae_id = 0x%x bool qp=%d qp_id = %d\n", info->ae_id, info->qp, info->qp_cq_id); if (rdma_protocol_roce(&iwdev->ibdev, 1)) { - if (!info->sq && ctx_info->roce_info->err_rq_idx_valid) { + ctx_info->roce_info->err_rq_idx_valid = info->rq; + if (info->rq) { ctx_info->roce_info->err_rq_idx = info->wqe_idx; irdma_sc_qp_setctx_roce(&iwqp->sc_qp, iwqp->host_ctx.va, ctx_info); @@ -388,7 +380,8 @@ static void irdma_process_aeq(struct irdma_pci_f *rf) irdma_cm_disconn(iwqp); break; } - if (!info->sq && ctx_info->iwarp_info->err_rq_idx_valid) { + ctx_info->iwarp_info->err_rq_idx_valid = info->rq; + if (info->rq) { ctx_info->iwarp_info->err_rq_idx = info->wqe_idx; ctx_info->tcp_info_valid = false; ctx_info->iwarp_info_valid = true;
From: Jack Wang jinpu.wang@ionos.com
[ Upstream commit ed6e53820ee4f68ed927de17e5675ff2a07a47e2 ]
stringify works with define, not enum.
Fixes: 91fddedd439c ("RDMA/rtrs: private headers with rtrs protocol structs and helpers") Cc: jinpu.wang@ionos.com Link: https://lore.kernel.org/r/20220712103113.617754-2-haris.iqbal@ionos.com Signed-off-by: Jack Wang jinpu.wang@ionos.com Signed-off-by: Md Haris Iqbal haris.iqbal@ionos.com Reviewed-by: Aleksei Marov aleksei.marov@ionos.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/rtrs/rtrs-pri.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h index 9a1e5c2ae55c..ac0df734eba8 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h +++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h @@ -23,6 +23,17 @@ #define RTRS_PROTO_VER_STRING __stringify(RTRS_PROTO_VER_MAJOR) "." \ __stringify(RTRS_PROTO_VER_MINOR)
+/* + * Max IB immediate data size is 2^28 (MAX_IMM_PAYL_BITS) + * and the minimum chunk size is 4096 (2^12). + * So the maximum sess_queue_depth is 65536 (2^16) in theory. + * But mempool_create, create_qp and ib_post_send fail with + * "cannot allocate memory" error if sess_queue_depth is too big. + * Therefore the pratical max value of sess_queue_depth is + * somewhere between 1 and 65534 and it depends on the system. + */ +#define MAX_SESS_QUEUE_DEPTH 65535 + enum rtrs_imm_const { MAX_IMM_TYPE_BITS = 4, MAX_IMM_TYPE_MASK = ((1 << MAX_IMM_TYPE_BITS) - 1), @@ -46,16 +57,6 @@ enum {
MAX_PATHS_NUM = 128,
- /* - * Max IB immediate data size is 2^28 (MAX_IMM_PAYL_BITS) - * and the minimum chunk size is 4096 (2^12). - * So the maximum sess_queue_depth is 65536 (2^16) in theory. - * But mempool_create, create_qp and ib_post_send fail with - * "cannot allocate memory" error if sess_queue_depth is too big. - * Therefore the pratical max value of sess_queue_depth is - * somewhere between 1 and 65534 and it depends on the system. - */ - MAX_SESS_QUEUE_DEPTH = 65535, MIN_CHUNK_SIZE = 8192,
RTRS_HB_INTERVAL_MS = 5000,
From: Md Haris Iqbal haris.iqbal@ionos.com
[ Upstream commit c14adff285ad1bb8eefc5d8fc202ceb1f7e3a2f1 ]
removes list_next_or_null_rr_rcu macro to fix below warnings. That macro is used only twice. CHECK:MACRO_ARG_REUSE: Macro argument reuse 'head' - possible side-effects? CHECK:MACRO_ARG_REUSE: Macro argument reuse 'ptr' - possible side-effects? CHECK:MACRO_ARG_REUSE: Macro argument reuse 'memb' - possible side-effects?
Replaces that macro with an inline function.
Fixes: 6a98d71daea1 ("RDMA/rtrs: client: main functionality") Cc: jinpu.wang@ionos.com Link: https://lore.kernel.org/r/20220712103113.617754-5-haris.iqbal@ionos.com Signed-off-by: Md Haris Iqbal haris.iqbal@ionos.com Suggested-by: Jason Gunthorpe jgg@ziepe.ca Signed-off-by: Jack Wang jinpu.wang@ionos.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 35 ++++++++++++-------------- 1 file changed, 16 insertions(+), 19 deletions(-)
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c index 9809c3883979..525f083fcaeb 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c @@ -740,25 +740,25 @@ struct path_it { struct rtrs_clt_path *(*next_path)(struct path_it *it); };
-/** - * list_next_or_null_rr_rcu - get next list element in round-robin fashion. +/* + * rtrs_clt_get_next_path_or_null - get clt path from the list or return NULL * @head: the head for the list. - * @ptr: the list head to take the next element from. - * @type: the type of the struct this is embedded in. - * @memb: the name of the list_head within the struct. + * @clt_path: The element to take the next clt_path from. * - * Next element returned in round-robin fashion, i.e. head will be skipped, + * Next clt path returned in round-robin fashion, i.e. head will be skipped, * but if list is observed as empty, NULL will be returned. * - * This primitive may safely run concurrently with the _rcu list-mutation + * This function may safely run concurrently with the _rcu list-mutation * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock(). */ -#define list_next_or_null_rr_rcu(head, ptr, type, memb) \ -({ \ - list_next_or_null_rcu(head, ptr, type, memb) ?: \ - list_next_or_null_rcu(head, READ_ONCE((ptr)->next), \ - type, memb); \ -}) +static inline struct rtrs_clt_path * +rtrs_clt_get_next_path_or_null(struct list_head *head, struct rtrs_clt_path *clt_path) +{ + return list_next_or_null_rcu(head, &clt_path->s.entry, typeof(*clt_path), s.entry) ?: + list_next_or_null_rcu(head, + READ_ONCE((&clt_path->s.entry)->next), + typeof(*clt_path), s.entry); +}
/** * get_next_path_rr() - Returns path in round-robin fashion. @@ -789,10 +789,8 @@ static struct rtrs_clt_path *get_next_path_rr(struct path_it *it) path = list_first_or_null_rcu(&clt->paths_list, typeof(*path), s.entry); else - path = list_next_or_null_rr_rcu(&clt->paths_list, - &path->s.entry, - typeof(*path), - s.entry); + path = rtrs_clt_get_next_path_or_null(&clt->paths_list, path); + rcu_assign_pointer(*ppcpu_path, path);
return path; @@ -2277,8 +2275,7 @@ static void rtrs_clt_remove_path_from_arr(struct rtrs_clt_path *clt_path) * removed. If @sess is the last element, then @next is NULL. */ rcu_read_lock(); - next = list_next_or_null_rr_rcu(&clt->paths_list, &clt_path->s.entry, - typeof(*next), s.entry); + next = rtrs_clt_get_next_path_or_null(&clt->paths_list, clt_path); rcu_read_unlock();
/*
From: Jianglei Nie niejianglei2021@163.com
[ Upstream commit b3236a64ddd125a455ef5b5316c1b9051b732974 ]
__qedr_alloc_mr() allocates a memory chunk for "mr->info.pbl_table" with init_mr_info(). When rdma_alloc_tid() and rdma_register_tid() fail, "mr" is released while "mr->info.pbl_table" is not released, which will lead to a memory leak.
We should release the "mr->info.pbl_table" with qedr_free_pbl() when error occurs to fix the memory leak.
Fixes: e0290cce6ac0 ("qedr: Add support for memory registeration verbs") Link: https://lore.kernel.org/r/20220714061505.2342759-1-niejianglei2021@163.com Signed-off-by: Jianglei Nie niejianglei2021@163.com Acked-by: Michal Kalderon michal.kalderon@marvell.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/qedr/verbs.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c index 03ed7c0fae50..d745ce9dc88a 100644 --- a/drivers/infiniband/hw/qedr/verbs.c +++ b/drivers/infiniband/hw/qedr/verbs.c @@ -3084,7 +3084,7 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd, else DP_ERR(dev, "roce alloc tid returned error %d\n", rc);
- goto err0; + goto err1; }
/* Index only, 18 bit long, lkey = itid << 8 | key */ @@ -3108,7 +3108,7 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd, rc = dev->ops->rdma_register_tid(dev->rdma_ctx, &mr->hw_mr); if (rc) { DP_ERR(dev, "roce register tid returned an error %d\n", rc); - goto err1; + goto err2; }
mr->ibmr.lkey = mr->hw_mr.itid << 8 | mr->hw_mr.key; @@ -3117,8 +3117,10 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd, DP_DEBUG(dev, QEDR_MSG_MR, "alloc frmr: %x\n", mr->ibmr.lkey); return mr;
-err1: +err2: dev->ops->rdma_free_tid(dev->rdma_ctx, mr->hw_mr.itid); +err1: + qedr_free_pbl(dev, &mr->info.pbl_info, mr->info.pbl_table); err0: kfree(mr); return ERR_PTR(rc);
From: Haoyue Xu xuhaoyue1@hisilicon.com
[ Upstream commit ecb4db5c3590aa956b4b2c352081a5b632d1f9f9 ]
The driver will clear all the interrupts in the same area when the driver handles the interrupt of type AEQ overflow. It should only set the interrupt status bit of type AEQ overflow.
Fixes: a5073d6054f7 ("RDMA/hns: Add eq support of hip08") Link: https://lore.kernel.org/r/20220714134353.16700-4-liangwenpeng@huawei.com Signed-off-by: Haoyue Xu xuhaoyue1@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index ba3c742258ef..b354caeaa9b2 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -6000,8 +6000,8 @@ static irqreturn_t hns_roce_v2_msix_interrupt_abn(int irq, void *dev_id)
dev_err(dev, "AEQ overflow!\n");
- int_st |= 1 << HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S; - roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG, int_st); + roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG, + 1 << HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S);
/* Set reset level for reset_event() */ if (ops->set_default_reset_request)
From: Cheng Xu chengyou@linux.alibaba.com
[ Upstream commit 3056fc6c32e613b760422b94c7617ac9a24a4721 ]
If siw_recv_mpa_rr returns -EAGAIN, it means that the MPA reply hasn't been received completely, and should not report IW_CM_EVENT_CONNECT_REPLY in this case. This may trigger a call trace in iw_cm. A simple way to trigger this: server: ib_send_lat client: ib_send_lat -R <server_ip>
The call trace looks like this:
kernel BUG at drivers/infiniband/core/iwcm.c:894! invalid opcode: 0000 [#1] PREEMPT SMP NOPTI <...> Workqueue: iw_cm_wq cm_work_handler [iw_cm] Call Trace: <TASK> cm_work_handler+0x1dd/0x370 [iw_cm] process_one_work+0x1e2/0x3b0 worker_thread+0x49/0x2e0 ? rescuer_thread+0x370/0x370 kthread+0xe5/0x110 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x1f/0x30 </TASK>
Fixes: 6c52fdc244b5 ("rdma/siw: connection management") Link: https://lore.kernel.org/r/dae34b5fd5c2ea2bd9744812c1d2653a34a94c67.165770696... Signed-off-by: Cheng Xu chengyou@linux.alibaba.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/siw/siw_cm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c index 17f34d584cd9..f88d2971c2c6 100644 --- a/drivers/infiniband/sw/siw/siw_cm.c +++ b/drivers/infiniband/sw/siw/siw_cm.c @@ -725,11 +725,11 @@ static int siw_proc_mpareply(struct siw_cep *cep) enum mpa_v2_ctrl mpa_p2p_mode = MPA_V2_RDMA_NO_RTR;
rv = siw_recv_mpa_rr(cep); - if (rv != -EAGAIN) - siw_cancel_mpatimer(cep); if (rv) goto out_err;
+ siw_cancel_mpatimer(cep); + rep = &cep->mpa.hdr;
if (__mpa_rr_revision(rep->params.bits) > MPA_REVISION_2) { @@ -895,7 +895,8 @@ static int siw_proc_mpareply(struct siw_cep *cep) }
out_err: - siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY, -EINVAL); + if (rv != -EAGAIN) + siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY, -EINVAL);
return rv; }
From: Zhu Yanjun yanjun.zhu@linux.dev
[ Upstream commit 37da51efe6eaa0560f46803c8c436a48a2084da7 ]
The function rxe_create_qp calls rxe_qp_from_init. If some error occurs, the error handler of function rxe_qp_from_init will set both scq and rcq to NULL.
Then rxe_create_qp calls rxe_put to handle qp. In the end, rxe_qp_do_cleanup is called by rxe_put. rxe_qp_do_cleanup directly accesses scq and rcq before checking them. This will cause null-ptr-deref error.
The call graph is as below:
rxe_create_qp { ... rxe_qp_from_init { ... err1: ... qp->rcq = NULL; <---rcq is set to NULL qp->scq = NULL; <---scq is set to NULL ... }
qp_init: rxe_put{ ... rxe_qp_do_cleanup { ... atomic_dec(&qp->scq->num_wq); <--- scq is accessed ... atomic_dec(&qp->rcq->num_wq); <--- rcq is accessed } }
Fixes: 4703b4f0d94a ("RDMA/rxe: Enforce IBA C11-17") Link: https://lore.kernel.org/r/20220705225414.315478-1-yanjun.zhu@linux.dev Signed-off-by: Zhu Yanjun yanjun.zhu@linux.dev Reviewed-by: Bob Pearson rpearsonhpe@gmail.com Reviewed-by: Md Haris Iqbal haris.iqbal@ionos.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_qp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c index 22e9b85344c3..b79e1b43454e 100644 --- a/drivers/infiniband/sw/rxe/rxe_qp.c +++ b/drivers/infiniband/sw/rxe/rxe_qp.c @@ -804,13 +804,15 @@ static void rxe_qp_do_cleanup(struct work_struct *work) if (qp->rq.queue) rxe_queue_cleanup(qp->rq.queue);
- atomic_dec(&qp->scq->num_wq); - if (qp->scq) + if (qp->scq) { + atomic_dec(&qp->scq->num_wq); rxe_put(qp->scq); + }
- atomic_dec(&qp->rcq->num_wq); - if (qp->rcq) + if (qp->rcq) { + atomic_dec(&qp->rcq->num_wq); rxe_put(qp->rcq); + }
if (qp->pd) rxe_put(qp->pd);
From: Gwendal Grignou gwendal@chromium.org
[ Upstream commit 0b4ae3f6d1210c11f9baf159009c7227eacf90f2 ]
Instead of registering callback to process sensor events right at initialization time, wait for the sensor to be register in the iio subsystem.
Events can come at probe time (in case the kernel rebooted abruptly without switching the sensor off for instance), and be sent to IIO core before the sensor is fully registered.
Fixes: aa984f1ba4a4 ("iio: cros_ec: Register to cros_ec_sensorhub when EC supports FIFO") Reported-by: Douglas Anderson dianders@chromium.org Signed-off-by: Gwendal Grignou gwendal@chromium.org Reviewed-by: Douglas Anderson dianders@chromium.org Link: https://lore.kernel.org/r/20220711144716.642617-1-gwendal@chromium.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/cros_ec_accel_legacy.c | 4 +- .../cros_ec_sensors/cros_ec_lid_angle.c | 4 +- .../common/cros_ec_sensors/cros_ec_sensors.c | 6 +- .../cros_ec_sensors/cros_ec_sensors_core.c | 58 ++++++++++++++----- drivers/iio/light/cros_ec_light_prox.c | 6 +- drivers/iio/pressure/cros_ec_baro.c | 6 +- .../linux/iio/common/cros_ec_sensors_core.h | 7 ++- 7 files changed, 60 insertions(+), 31 deletions(-)
diff --git a/drivers/iio/accel/cros_ec_accel_legacy.c b/drivers/iio/accel/cros_ec_accel_legacy.c index b6f3471b62dc..3b77fded2dc0 100644 --- a/drivers/iio/accel/cros_ec_accel_legacy.c +++ b/drivers/iio/accel/cros_ec_accel_legacy.c @@ -215,7 +215,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev) return -ENOMEM;
ret = cros_ec_sensors_core_init(pdev, indio_dev, true, - cros_ec_sensors_capture, NULL); + cros_ec_sensors_capture); if (ret) return ret;
@@ -235,7 +235,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev) state->sign[CROS_EC_SENSOR_Z] = -1; }
- return devm_iio_device_register(dev, indio_dev); + return cros_ec_sensors_core_register(dev, indio_dev, NULL); }
static struct platform_driver cros_ec_accel_platform_driver = { diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c index af801e203623..02d3cf36acb0 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c @@ -97,7 +97,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev) if (!indio_dev) return -ENOMEM;
- ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, NULL); + ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL); if (ret) return ret;
@@ -113,7 +113,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev) if (ret) return ret;
- return devm_iio_device_register(dev, indio_dev); + return cros_ec_sensors_core_register(dev, indio_dev, NULL); }
static const struct platform_device_id cros_ec_lid_angle_ids[] = { diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c index 376a5b30010a..5cce34fdff02 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c @@ -235,8 +235,7 @@ static int cros_ec_sensors_probe(struct platform_device *pdev) return -ENOMEM;
ret = cros_ec_sensors_core_init(pdev, indio_dev, true, - cros_ec_sensors_capture, - cros_ec_sensors_push_data); + cros_ec_sensors_capture); if (ret) return ret;
@@ -297,7 +296,8 @@ static int cros_ec_sensors_probe(struct platform_device *pdev) else state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
- return devm_iio_device_register(dev, indio_dev); + return cros_ec_sensors_core_register(dev, indio_dev, + cros_ec_sensors_push_data); }
static const struct platform_device_id cros_ec_sensors_ids[] = { diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c index 5976aca48e3b..310d1511f376 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c @@ -234,21 +234,18 @@ static void cros_ec_sensors_core_clean(void *arg)
/** * cros_ec_sensors_core_init() - basic initialization of the core structure - * @pdev: platform device created for the sensors + * @pdev: platform device created for the sensor * @indio_dev: iio device structure of the device * @physical_device: true if the device refers to a physical device * @trigger_capture: function pointer to call buffer is triggered, * for backward compatibility. - * @push_data: function to call when cros_ec_sensorhub receives - * a sample for that sensor. * * Return: 0 on success, -errno on failure. */ int cros_ec_sensors_core_init(struct platform_device *pdev, struct iio_dev *indio_dev, bool physical_device, - cros_ec_sensors_capture_t trigger_capture, - cros_ec_sensorhub_push_data_cb_t push_data) + cros_ec_sensors_capture_t trigger_capture) { struct device *dev = &pdev->dev; struct cros_ec_sensors_core_state *state = iio_priv(indio_dev); @@ -338,17 +335,6 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, if (ret) return ret;
- ret = cros_ec_sensorhub_register_push_data( - sensor_hub, sensor_platform->sensor_num, - indio_dev, push_data); - if (ret) - return ret; - - ret = devm_add_action_or_reset( - dev, cros_ec_sensors_core_clean, pdev); - if (ret) - return ret; - /* Timestamp coming from FIFO are in ns since boot. */ ret = iio_device_set_clock(indio_dev, CLOCK_BOOTTIME); if (ret) @@ -370,6 +356,46 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, } EXPORT_SYMBOL_GPL(cros_ec_sensors_core_init);
+/** + * cros_ec_sensors_core_register() - Register callback to FIFO and IIO when + * sensor is ready. + * It must be called at the end of the sensor probe routine. + * @dev: device created for the sensor + * @indio_dev: iio device structure of the device + * @push_data: function to call when cros_ec_sensorhub receives + * a sample for that sensor. + * + * Return: 0 on success, -errno on failure. + */ +int cros_ec_sensors_core_register(struct device *dev, + struct iio_dev *indio_dev, + cros_ec_sensorhub_push_data_cb_t push_data) +{ + struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev); + struct cros_ec_sensorhub *sensor_hub = dev_get_drvdata(dev->parent); + struct platform_device *pdev = to_platform_device(dev); + struct cros_ec_dev *ec = sensor_hub->ec; + int ret; + + ret = devm_iio_device_register(dev, indio_dev); + if (ret) + return ret; + + if (!push_data || + !cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) + return 0; + + ret = cros_ec_sensorhub_register_push_data( + sensor_hub, sensor_platform->sensor_num, + indio_dev, push_data); + if (ret) + return ret; + + return devm_add_action_or_reset( + dev, cros_ec_sensors_core_clean, pdev); +} +EXPORT_SYMBOL_GPL(cros_ec_sensors_core_register); + /** * cros_ec_motion_send_host_cmd() - send motion sense host command * @state: pointer to state information for device diff --git a/drivers/iio/light/cros_ec_light_prox.c b/drivers/iio/light/cros_ec_light_prox.c index de472f23d1cb..16b893bae388 100644 --- a/drivers/iio/light/cros_ec_light_prox.c +++ b/drivers/iio/light/cros_ec_light_prox.c @@ -181,8 +181,7 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) return -ENOMEM;
ret = cros_ec_sensors_core_init(pdev, indio_dev, true, - cros_ec_sensors_capture, - cros_ec_sensors_push_data); + cros_ec_sensors_capture); if (ret) return ret;
@@ -240,7 +239,8 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
- return devm_iio_device_register(dev, indio_dev); + return cros_ec_sensors_core_register(dev, indio_dev, + cros_ec_sensors_push_data); }
static const struct platform_device_id cros_ec_light_prox_ids[] = { diff --git a/drivers/iio/pressure/cros_ec_baro.c b/drivers/iio/pressure/cros_ec_baro.c index 2f882e109423..0511edbf868d 100644 --- a/drivers/iio/pressure/cros_ec_baro.c +++ b/drivers/iio/pressure/cros_ec_baro.c @@ -138,8 +138,7 @@ static int cros_ec_baro_probe(struct platform_device *pdev) return -ENOMEM;
ret = cros_ec_sensors_core_init(pdev, indio_dev, true, - cros_ec_sensors_capture, - cros_ec_sensors_push_data); + cros_ec_sensors_capture); if (ret) return ret;
@@ -186,7 +185,8 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
- return devm_iio_device_register(dev, indio_dev); + return cros_ec_sensors_core_register(dev, indio_dev, + cros_ec_sensors_push_data); }
static const struct platform_device_id cros_ec_baro_ids[] = { diff --git a/include/linux/iio/common/cros_ec_sensors_core.h b/include/linux/iio/common/cros_ec_sensors_core.h index c582e1a14232..7b5dbd749995 100644 --- a/include/linux/iio/common/cros_ec_sensors_core.h +++ b/include/linux/iio/common/cros_ec_sensors_core.h @@ -95,8 +95,11 @@ int cros_ec_sensors_read_cmd(struct iio_dev *indio_dev, unsigned long scan_mask, struct platform_device; int cros_ec_sensors_core_init(struct platform_device *pdev, struct iio_dev *indio_dev, bool physical_device, - cros_ec_sensors_capture_t trigger_capture, - cros_ec_sensorhub_push_data_cb_t push_data); + cros_ec_sensors_capture_t trigger_capture); + +int cros_ec_sensors_core_register(struct device *dev, + struct iio_dev *indio_dev, + cros_ec_sensorhub_push_data_cb_t push_data);
irqreturn_t cros_ec_sensors_capture(int irq, void *p); int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
From: Abel Vesa abel.vesa@linaro.org
[ Upstream commit b1ec8b53c9ae5fae33d60e9638d39ca5346b941b ]
Both dispcc and videocc use mmcx power domain now. Lets drop the supply mmcx from every gdsc.
Cc: Dmitry Baryshkov dmitry.baryshkov@linaro.org Fixes: 266e5cf39a0f ("arm64: dts: qcom: sm8250: remove mmcx regulator") Signed-off-by: Abel Vesa abel.vesa@linaro.org Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220713143200.3686765-1-abel.vesa@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/dispcc-sm8250.c | 1 - drivers/clk/qcom/videocc-sm8250.c | 4 ---- 2 files changed, 5 deletions(-)
diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c index db9379634fb2..f646fdfe6f15 100644 --- a/drivers/clk/qcom/dispcc-sm8250.c +++ b/drivers/clk/qcom/dispcc-sm8250.c @@ -1134,7 +1134,6 @@ static struct gdsc mdss_gdsc = { }, .pwrsts = PWRSTS_OFF_ON, .flags = HW_CTRL, - .supply = "mmcx", };
static struct clk_regmap *disp_cc_sm8250_clocks[] = { diff --git a/drivers/clk/qcom/videocc-sm8250.c b/drivers/clk/qcom/videocc-sm8250.c index 8617454e4a77..f28f2cb051d7 100644 --- a/drivers/clk/qcom/videocc-sm8250.c +++ b/drivers/clk/qcom/videocc-sm8250.c @@ -277,7 +277,6 @@ static struct gdsc mvs0c_gdsc = { }, .flags = 0, .pwrsts = PWRSTS_OFF_ON, - .supply = "mmcx", };
static struct gdsc mvs1c_gdsc = { @@ -287,7 +286,6 @@ static struct gdsc mvs1c_gdsc = { }, .flags = 0, .pwrsts = PWRSTS_OFF_ON, - .supply = "mmcx", };
static struct gdsc mvs0_gdsc = { @@ -297,7 +295,6 @@ static struct gdsc mvs0_gdsc = { }, .flags = HW_CTRL, .pwrsts = PWRSTS_OFF_ON, - .supply = "mmcx", };
static struct gdsc mvs1_gdsc = { @@ -307,7 +304,6 @@ static struct gdsc mvs1_gdsc = { }, .flags = HW_CTRL, .pwrsts = PWRSTS_OFF_ON, - .supply = "mmcx", };
static struct clk_regmap *video_cc_sm8250_clocks[] = {
From: Bjorn Andersson bjorn.andersson@linaro.org
[ Upstream commit 41fff779d7948147f2440c4bb134cdf8b45b22d7 ]
When a GDSC is found to be enabled at boot the pm_runtime state will be unbalanced as the GDSC is later turned off. Fix this by increasing the usage counter on the power-domain, in line with how we handled the regulator state.
Fixes: 1b771839de05 ("clk: qcom: gdsc: enable optional power domain support") Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Acked-by: Stephen Boyd sboyd@kernel.org Link: https://lore.kernel.org/r/20220713212818.130277-1-bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gdsc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 44520efc6c72..2db0938f8dd3 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -420,6 +420,14 @@ static int gdsc_init(struct gdsc *sc) return ret; }
+ /* ...and the power-domain */ + ret = gdsc_pm_runtime_get(sc); + if (ret) { + if (sc->rsupply) + regulator_disable(sc->rsupply); + return ret; + } + /* * Votable GDSCs can be ON due to Vote from other masters. * If a Votable GDSC is ON, make sure we have a Vote.
From: Bryan O'Donoghue bryan.odonoghue@linaro.org
[ Upstream commit 2bc308ebc453ba22f3f120f777b9ac48f973ee80 ]
Adding a new item to this frequency table I see the existing indentation is incorrect.
Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller") Signed-off-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220712125922.3461675-2-bryan.odonoghue@linaro.or... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gcc-msm8939.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c index c7377ec0f423..de0022e5450d 100644 --- a/drivers/clk/qcom/gcc-msm8939.c +++ b/drivers/clk/qcom/gcc-msm8939.c @@ -1014,7 +1014,7 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = { };
static const struct freq_tbl ftbl_gcc_camss_cci_clk[] = { - F(19200000, P_XO, 1, 0, 0), + F(19200000, P_XO, 1, 0, 0), { } };
From: Jianglei Nie niejianglei2021@163.com
[ Upstream commit aa2a1df3a2c85f855af7d54466ac10bd48645d63 ]
setup_base_ctxt() allocates a memory chunk for uctxt->groups with hfi1_alloc_ctxt_rcv_groups(). When init_user_ctxt() fails, uctxt->groups is not released, which will lead to a memory leak.
We should release the uctxt->groups with hfi1_free_ctxt_rcv_groups() when init_user_ctxt() fails.
Fixes: e87473bc1b6c ("IB/hfi1: Only set fd pointer when base context is completely initialized") Link: https://lore.kernel.org/r/20220711070718.2318320-1-niejianglei2021@163.com Signed-off-by: Jianglei Nie niejianglei2021@163.com Acked-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/file_ops.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c index 2e4cf2b11653..629beff053ad 100644 --- a/drivers/infiniband/hw/hfi1/file_ops.c +++ b/drivers/infiniband/hw/hfi1/file_ops.c @@ -1179,8 +1179,10 @@ static int setup_base_ctxt(struct hfi1_filedata *fd, goto done;
ret = init_user_ctxt(fd, uctxt); - if (ret) + if (ret) { + hfi1_free_ctxt_rcv_groups(uctxt); goto done; + }
user_init(uctxt);
From: Liang He windhl@126.com
[ Upstream commit 5d07a692f9562f9c06e62cce369e9dd108173a0f ]
We should use of_node_get() when a new reference of device_node is created. It is noted that the old reference stored in 'mm_gc->gc.of_node' should also be decreased.
This patch is based on the fact that there is a call site in function 'qe_add_gpiochips()' of src file 'drivers\soc\fsl\qe\gpio.c'. In this function, of_mm_gpiochip_add_data() is contained in an iteration of for_each_compatible_node() which will automatically increase and decrease the refcount. So we need additional of_node_get() for the reference escape in of_mm_gpiochip_add_data().
Fixes: a19e3da5bc5f ("of/gpio: Kill of_gpio_chip and add members directly to gpio_chip") Signed-off-by: Liang He windhl@126.com Signed-off-by: Bartosz Golaszewski brgl@bgdev.pl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpio/gpiolib-of.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 3d6c3ffd5576..de100b0217da 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -860,7 +860,8 @@ int of_mm_gpiochip_add_data(struct device_node *np, if (mm_gc->save_regs) mm_gc->save_regs(mm_gc);
- mm_gc->gc.of_node = np; + of_node_put(mm_gc->gc.of_node); + mm_gc->gc.of_node = of_node_get(np);
ret = gpiochip_add_data(gc, data); if (ret) @@ -868,6 +869,7 @@ int of_mm_gpiochip_add_data(struct device_node *np,
return 0; err2: + of_node_put(np); iounmap(mm_gc->regs); err1: kfree(gc->label);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 06ee60eb507f00fb3643876ec05318c63332dc88 ]
If max1027_wait_eoc() fails then call iio_device_release_direct_mode() before returning.
Fixes: a0e831653ef9 ("iio: adc: max1027: Introduce an end of conversion helper") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/YsbztVuAXnau2cIZ@kili Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/max1027.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c index b725d012625c..136fcf753837 100644 --- a/drivers/iio/adc/max1027.c +++ b/drivers/iio/adc/max1027.c @@ -349,8 +349,7 @@ static int max1027_read_single_value(struct iio_dev *indio_dev, if (ret < 0) { dev_err(&indio_dev->dev, "Failed to configure conversion register\n"); - iio_device_release_direct_mode(indio_dev); - return ret; + goto release; }
/* @@ -360,11 +359,12 @@ static int max1027_read_single_value(struct iio_dev *indio_dev, */ ret = max1027_wait_eoc(indio_dev); if (ret) - return ret; + goto release;
/* Read result */ ret = spi_read(st->spi, st->buffer, (chan->type == IIO_TEMP) ? 4 : 2);
+release: iio_device_release_direct_mode(indio_dev);
if (ret < 0)
From: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
[ Upstream commit 62ac2473553a00229e67bdf3cb023b62cf7f5a9a ]
Smatch Warning: drivers/hid/hid-mcp2221.c:388 mcp_smbus_write() error: __memcpy() '&mcp->txbuf[5]' too small (59 vs 255) drivers/hid/hid-mcp2221.c:388 mcp_smbus_write() error: __memcpy() 'buf' too small (34 vs 255)
The 'len' variable can take a value between 0-255 as it can come from data->block[0] and it is user data. So add an bound check to prevent a buffer overflow in memcpy().
Fixes: 67a95c21463d ("HID: mcp2221: add usb to i2c-smbus host bridge") Signed-off-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-mcp2221.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c index 4211b9839209..de52e9f7bb8c 100644 --- a/drivers/hid/hid-mcp2221.c +++ b/drivers/hid/hid-mcp2221.c @@ -385,6 +385,9 @@ static int mcp_smbus_write(struct mcp2221 *mcp, u16 addr, data_len = 7; break; default: + if (len > I2C_SMBUS_BLOCK_MAX) + return -EINVAL; + memcpy(&mcp->txbuf[5], buf, len); data_len = len + 5; }
From: Basavaraj Natikar Basavaraj.Natikar@amd.com
[ Upstream commit 06aa2a43c307cf4096f422dcb575e5d2913e528f ]
On removal of hid device during SFH set report may cause NULL pointer exception. Hence add NULL check for hid device before accessing.
Fixes: 4b2c53d93a4b ("SFH:Transport Driver to add support of AMD Sensor Fusion Hub (SFH)") Signed-off-by: Basavaraj Natikar Basavaraj.Natikar@amd.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/amd-sfh-hid/amd_sfh_hid.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c index 1089134030b0..1b18291fc5af 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c @@ -101,11 +101,15 @@ static int amdtp_wait_for_response(struct hid_device *hid)
void amdtp_hid_wakeup(struct hid_device *hid) { - struct amdtp_hid_data *hid_data = hid->driver_data; - struct amdtp_cl_data *cli_data = hid_data->cli_data; + struct amdtp_hid_data *hid_data; + struct amdtp_cl_data *cli_data;
- cli_data->request_done[cli_data->cur_hid_dev] = true; - wake_up_interruptible(&hid_data->hid_wait); + if (hid) { + hid_data = hid->driver_data; + cli_data = hid_data->cli_data; + cli_data->request_done[cli_data->cur_hid_dev] = true; + wake_up_interruptible(&hid_data->hid_wait); + } }
static struct hid_ll_driver amdtp_hid_ll_driver = {
From: Fabio Estevam festevam@denx.de
[ Upstream commit c3266ee185b59e5aab3e0f982e5b7f95d31555a7 ]
Change the of_device_get_match_data() cast to (uintptr_t) to silence the following clang warning:
drivers/dma/imx-dma.c:1048:20: warning: cast to smaller integer type 'enum imx_dma_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
Reported-by: kernel test robot lkp@intel.com Fixes: 0ab785c894e6 ("dmaengine: imx-dma: Remove unused .id_table") Signed-off-by: Fabio Estevam festevam@denx.de Link: https://lore.kernel.org/r/20220706111327.940764-1-festevam@gmail.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/imx-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 3bffe3ecbd1b..65c6094ce063 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -1047,7 +1047,7 @@ static int __init imxdma_probe(struct platform_device *pdev) return -ENOMEM;
imxdma->dev = &pdev->dev; - imxdma->devtype = (enum imx_dma_type)of_device_get_match_data(&pdev->dev); + imxdma->devtype = (uintptr_t)of_device_get_match_data(&pdev->dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); imxdma->base = devm_ioremap_resource(&pdev->dev, res);
From: Antonio Borneo antonio.borneo@foss.st.com
[ Upstream commit e3c8d33e0d62175c31ca7ab7ab01b18f0b6318d3 ]
The type atomic_long_t can have size 4 or 8 bytes, depending on CONFIG_64BIT; it's only content, the field 'counter', is either an int or a s64 value.
Current code incorrectly uses the fixed size utils.read_u64() to read the field 'counter' inside atomic_long_t.
On 32 bits architectures reading the last element 'tail_id' of the struct prb_desc_ring: struct prb_desc_ring { ... atomic_long_t tail_id; }; causes the utils.read_u64() to access outside the boundary of the struct and the gdb command 'lx-dmesg' exits with error: Python Exception <class 'IndexError'>: index out of range Error occurred in Python: index out of range
Query the really used atomic_long_t counter type size.
Link: https://lore.kernel.org/r/20220617143758.137307-1-antonio.borneo@foss.st.com Fixes: e60768311af8 ("scripts/gdb: update for lockless printk ringbuffer") Signed-off-by: Antonio Borneo antonio.borneo@foss.st.com [pmladek@suse.com: Query the really used atomic_long_t counter type size] Tested-by: Antonio Borneo antonio.borneo@foss.st.com Reviewed-by: John Ogness john.ogness@linutronix.de Signed-off-by: Petr Mladek pmladek@suse.com Link: https://lore.kernel.org/r/20220719122831.19890-1-pmladek@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/gdb/linux/dmesg.py | 9 +++------ scripts/gdb/linux/utils.py | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py index d5983cf3db7d..c771831eb077 100644 --- a/scripts/gdb/linux/dmesg.py +++ b/scripts/gdb/linux/dmesg.py @@ -22,7 +22,6 @@ prb_desc_type = utils.CachedType("struct prb_desc") prb_desc_ring_type = utils.CachedType("struct prb_desc_ring") prb_data_ring_type = utils.CachedType("struct prb_data_ring") printk_ringbuffer_type = utils.CachedType("struct printk_ringbuffer") -atomic_long_type = utils.CachedType("atomic_long_t")
class LxDmesg(gdb.Command): """Print Linux kernel log buffer.""" @@ -68,8 +67,6 @@ class LxDmesg(gdb.Command): off = prb_data_ring_type.get_type()['data'].bitpos // 8 text_data_addr = utils.read_ulong(text_data_ring, off)
- counter_off = atomic_long_type.get_type()['counter'].bitpos // 8 - sv_off = prb_desc_type.get_type()['state_var'].bitpos // 8
off = prb_desc_type.get_type()['text_blk_lpos'].bitpos // 8 @@ -89,9 +86,9 @@ class LxDmesg(gdb.Command):
# read in tail and head descriptor ids off = prb_desc_ring_type.get_type()['tail_id'].bitpos // 8 - tail_id = utils.read_u64(desc_ring, off + counter_off) + tail_id = utils.read_atomic_long(desc_ring, off) off = prb_desc_ring_type.get_type()['head_id'].bitpos // 8 - head_id = utils.read_u64(desc_ring, off + counter_off) + head_id = utils.read_atomic_long(desc_ring, off)
did = tail_id while True: @@ -102,7 +99,7 @@ class LxDmesg(gdb.Command): desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes()
# skip non-committed record - state = 3 & (utils.read_u64(desc, sv_off + counter_off) >> desc_flags_shift) + state = 3 & (utils.read_atomic_long(desc, sv_off) >> desc_flags_shift) if state != desc_committed and state != desc_finalized: if did == head_id: break diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index ff7c1799d588..1553f68716cc 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py @@ -35,13 +35,12 @@ class CachedType:
long_type = CachedType("long") - +atomic_long_type = CachedType("atomic_long_t")
def get_long_type(): global long_type return long_type.get_type()
- def offset_of(typeobj, field): element = gdb.Value(0).cast(typeobj) return int(str(element[field].address).split()[0], 16) @@ -129,6 +128,17 @@ def read_ulong(buffer, offset): else: return read_u32(buffer, offset)
+atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos +atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof + +def read_atomic_long(buffer, offset): + global atomic_long_counter_offset + global atomic_long_counter_sizeof + + if atomic_long_counter_sizeof == 8: + return read_u64(buffer, offset + atomic_long_counter_offset) + else: + return read_u32(buffer, offset + atomic_long_counter_offset)
target_arch = None
From: Bob Pearson rpearsonhpe@gmail.com
[ Upstream commit 1603f89935ec86d40a7667e1250392626976ccc2 ]
The current implementation of rxe_check_bind_mw() in rxe_mw.c is incorrect since it requires the new key portion provided by the mw consumer to be different than the previous key portion. This is not required by the IBA. Remove the test.
Link: https://lore.kernel.org/linux-rdma/fb4614e7-4cac-0dc7-3ef7-766dfd10e8f2@gmai... Fixes: 32a577b4c3a9 ("Add support for bind MW work requests") Link: https://lore.kernel.org/r/20220714204619.13396-1-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson rpearsonhpe@gmail.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_mw.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c index 2e1fa844fabf..824739008d5b 100644 --- a/drivers/infiniband/sw/rxe/rxe_mw.c +++ b/drivers/infiniband/sw/rxe/rxe_mw.c @@ -48,8 +48,6 @@ int rxe_dealloc_mw(struct ib_mw *ibmw) static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, struct rxe_mw *mw, struct rxe_mr *mr) { - u32 key = wqe->wr.wr.mw.rkey & 0xff; - if (mw->ibmw.type == IB_MW_TYPE_1) { if (unlikely(mw->state != RXE_MW_STATE_VALID)) { pr_err_once( @@ -87,11 +85,6 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, } }
- if (unlikely(key == (mw->rkey & 0xff))) { - pr_err_once("attempt to bind MW with same key\n"); - return -EINVAL; - } - /* remaining checks only apply to a nonzero MR */ if (!mr) return 0;
From: Liang He windhl@126.com
[ Upstream commit 883c1d6fa4368a63cae2d6ae2d9c91141c60e233 ]
In mmc_fixup_of_compatible_match(), we should call of_node_put() when breaking out of for_each_child_of_node() which will increase and decrease the refcount during one iteration.
Fixes: b360b1102670 ("mmc: core: allow to match the device tree to apply quirks") Signed-off-by: Liang He windhl@126.com Link: https://lore.kernel.org/r/20220719091051.1210806-1-windhl@126.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/core/quirks.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index f879dc63d936..be4393988086 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -163,8 +163,10 @@ static inline bool mmc_fixup_of_compatible_match(struct mmc_card *card, struct device_node *np;
for_each_child_of_node(mmc_dev(card->host)->of_node, np) { - if (of_device_is_compatible(np, compatible)) + if (of_device_is_compatible(np, compatible)) { + of_node_put(np); return true; + } }
return false;
From: Liang He windhl@126.com
[ Upstream commit 19bbb49acf8d7a03cb83e05624363741a4c3ec6f ]
In octeon_mmc_probe(), we should call of_node_put() when breaking out of for_each_child_of_node() which has increased and decreased the refcount during each iteration.
Fixes: 01d95843335c ("mmc: cavium: Add MMC support for Octeon SOCs.") Signed-off-by: Liang He windhl@126.com Acked-by: Robert Richter rric@kernel.org Link: https://lore.kernel.org/r/20220719095216.1241601-1-windhl@126.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/cavium-octeon.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mmc/host/cavium-octeon.c b/drivers/mmc/host/cavium-octeon.c index 2c4b2df52adb..12dca91a8ef6 100644 --- a/drivers/mmc/host/cavium-octeon.c +++ b/drivers/mmc/host/cavium-octeon.c @@ -277,6 +277,7 @@ static int octeon_mmc_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Error populating slots\n"); octeon_mmc_set_shared_power(host, 0); + of_node_put(cn); goto error; } i++;
From: Liang He windhl@126.com
[ Upstream commit 7ee480795e41db314f2c445c65ed854a5d6e8e32 ]
In thunder_mmc_probe(), we should call of_node_put() when breaking out of for_each_child_of_node() which has increased and decreased the refcount during each iteration.
Fixes: 166bac38c3c5 ("mmc: cavium: Add MMC PCI driver for ThunderX SOCs") Signed-off-by: Liang He windhl@126.com Acked-by: Robert Richter rric@kernel.org Link: https://lore.kernel.org/r/20220719095216.1241601-2-windhl@126.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/cavium-thunderx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/cavium-thunderx.c b/drivers/mmc/host/cavium-thunderx.c index 76013bbbcff3..202b1d6da678 100644 --- a/drivers/mmc/host/cavium-thunderx.c +++ b/drivers/mmc/host/cavium-thunderx.c @@ -142,8 +142,10 @@ static int thunder_mmc_probe(struct pci_dev *pdev, continue;
ret = cvm_mmc_of_slot_probe(&host->slot_pdev[i]->dev, host); - if (ret) + if (ret) { + of_node_put(child_node); goto error; + } } i++; }
From: Artem Borisov dedsa2002@gmail.com
[ Upstream commit 1117d182c5d72abd7eb8b7d5e7b8c3373181c3ab ]
U1_UNICORN_LEGACY id was added to the driver, but was not declared in the device id table, making it impossible to use.
Fixes: 640e403 ("HID: alps: Add AUI1657 device ID") Signed-off-by: Artem Borisov dedsa2002@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-alps.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c index 2b986d0dbde4..db146d0f7937 100644 --- a/drivers/hid/hid-alps.c +++ b/drivers/hid/hid-alps.c @@ -830,6 +830,8 @@ static const struct hid_device_id alps_id[] = { USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) }, { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1) }, + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, + USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY) }, { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_T4_BTNLESS) }, { }
From: Md Haris Iqbal haris.phnx@gmail.com
[ Upstream commit 174e7b137042f19b5ce88beb4fc0ff4ec6b0c72a ]
The 'rkey' input can be an lkey or rkey, and in rxe the lkey or rkey have the same value, including the variant bits.
So, if mr->rkey is set, compare the invalidate key with it, otherwise compare with the mr->lkey.
Since we already did a lookup on the non-varient bits to get this far, the check's only purpose is to confirm that the wqe has the correct variant bits.
Fixes: 001345339f4c ("RDMA/rxe: Separate HW and SW l/rkeys") Link: https://lore.kernel.org/r/20220707073006.328737-1-haris.phnx@gmail.com Signed-off-by: Md Haris Iqbal haris.phnx@gmail.com Reviewed-by: Bob Pearson rpearsonhpe@gmail.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_loc.h | 2 +- drivers/infiniband/sw/rxe/rxe_mr.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h index 0e022ae1b8a5..37484a559d20 100644 --- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -77,7 +77,7 @@ struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key, enum rxe_mr_lookup_type type); int mr_check_range(struct rxe_mr *mr, u64 iova, size_t length); int advance_dma_data(struct rxe_dma_info *dma, unsigned int length); -int rxe_invalidate_mr(struct rxe_qp *qp, u32 rkey); +int rxe_invalidate_mr(struct rxe_qp *qp, u32 key); int rxe_reg_fast_mr(struct rxe_qp *qp, struct rxe_send_wqe *wqe); int rxe_mr_set_page(struct ib_mr *ibmr, u64 addr); int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata); diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c index fc3942e04a1f..3add52129006 100644 --- a/drivers/infiniband/sw/rxe/rxe_mr.c +++ b/drivers/infiniband/sw/rxe/rxe_mr.c @@ -576,22 +576,22 @@ struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key, return mr; }
-int rxe_invalidate_mr(struct rxe_qp *qp, u32 rkey) +int rxe_invalidate_mr(struct rxe_qp *qp, u32 key) { struct rxe_dev *rxe = to_rdev(qp->ibqp.device); struct rxe_mr *mr; int ret;
- mr = rxe_pool_get_index(&rxe->mr_pool, rkey >> 8); + mr = rxe_pool_get_index(&rxe->mr_pool, key >> 8); if (!mr) { - pr_err("%s: No MR for rkey %#x\n", __func__, rkey); + pr_err("%s: No MR for key %#x\n", __func__, key); ret = -EINVAL; goto err; }
- if (rkey != mr->rkey) { - pr_err("%s: rkey (%#x) doesn't match mr->rkey (%#x)\n", - __func__, rkey, mr->rkey); + if (mr->rkey ? (key != mr->rkey) : (key != mr->lkey)) { + pr_err("%s: wr key (%#x) doesn't match mr key (%#x)\n", + __func__, key, (mr->rkey ? mr->rkey : mr->lkey)); ret = -EINVAL; goto err_drop_ref; }
From: Bob Pearson rpearsonhpe@gmail.com
[ Upstream commit 445fd4f4fb76d513de6b05b08b3a4d0bb980fc80 ]
Currently the completer tasklet when retransmit timer or the rnr timer fires the same flag (qp->req.need_retry) is set so that if either timer fires it will attempt to perform a retry flow on the send queue. This has the effect of responding to an RNR NAK at the first retransmit timer event which might not allow the requested rnr timeout.
This patch adds a new flag (qp->req.wait_for_rnr_timer) which, if set, prevents a retry flow until the rnr nak timer fires.
This patch fixes rnr retry errors which can be observed by running the pyverbs test_rdmacm_async_traffic_external_qp multiple times. With this patch applied they do not occur.
Link: https://lore.kernel.org/linux-rdma/a8287823-1408-4273-bc22-99a0678db640@gmai... Link: https://lore.kernel.org/linux-rdma/2bafda9e-2bb6-186d-12a1-179e8f6a2678@talp... Fixes: 8700e3e7c485 ("Soft RoCE driver") Link: https://lore.kernel.org/r/20220630190425.2251-6-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson rpearsonhpe@gmail.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_comp.c | 8 +++++++- drivers/infiniband/sw/rxe/rxe_qp.c | 1 + drivers/infiniband/sw/rxe/rxe_req.c | 15 +++++++++++++-- drivers/infiniband/sw/rxe/rxe_verbs.h | 1 + 4 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c index da3a398053b8..4fc31bb7eee6 100644 --- a/drivers/infiniband/sw/rxe/rxe_comp.c +++ b/drivers/infiniband/sw/rxe/rxe_comp.c @@ -114,6 +114,8 @@ void retransmit_timer(struct timer_list *t) { struct rxe_qp *qp = from_timer(qp, t, retrans_timer);
+ pr_debug("%s: fired for qp#%d\n", __func__, qp->elem.index); + if (qp->valid) { qp->comp.timeout = 1; rxe_run_task(&qp->comp.task, 1); @@ -730,11 +732,15 @@ int rxe_completer(void *arg) break;
case COMPST_RNR_RETRY: + /* we come here if we received an RNR NAK */ if (qp->comp.rnr_retry > 0) { if (qp->comp.rnr_retry != 7) qp->comp.rnr_retry--;
- qp->req.need_retry = 1; + /* don't start a retry flow until the + * rnr timer has fired + */ + qp->req.wait_for_rnr_timer = 1; pr_debug("qp#%d set rnr nak timer\n", qp_num(qp)); mod_timer(&qp->rnr_nak_timer, diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c index b79e1b43454e..834f40ad00af 100644 --- a/drivers/infiniband/sw/rxe/rxe_qp.c +++ b/drivers/infiniband/sw/rxe/rxe_qp.c @@ -507,6 +507,7 @@ static void rxe_qp_reset(struct rxe_qp *qp) atomic_set(&qp->ssn, 0); qp->req.opcode = -1; qp->req.need_retry = 0; + qp->req.wait_for_rnr_timer = 0; qp->req.noack_pkts = 0; qp->resp.msn = 0; qp->resp.opcode = -1; diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c index 15fefc689ca3..9f8e3db179cc 100644 --- a/drivers/infiniband/sw/rxe/rxe_req.c +++ b/drivers/infiniband/sw/rxe/rxe_req.c @@ -101,7 +101,11 @@ void rnr_nak_timer(struct timer_list *t) { struct rxe_qp *qp = from_timer(qp, t, rnr_nak_timer);
- pr_debug("qp#%d rnr nak timer fired\n", qp_num(qp)); + pr_debug("%s: fired for qp#%d\n", __func__, qp_num(qp)); + + /* request a send queue retry */ + qp->req.need_retry = 1; + qp->req.wait_for_rnr_timer = 0; rxe_run_task(&qp->req.task, 1); }
@@ -622,10 +626,17 @@ int rxe_requester(void *arg) qp->req.need_rd_atomic = 0; qp->req.wait_psn = 0; qp->req.need_retry = 0; + qp->req.wait_for_rnr_timer = 0; goto exit; }
- if (unlikely(qp->req.need_retry)) { + /* we come here if the retransmot timer has fired + * or if the rnr timer has fired. If the retransmit + * timer fires while we are processing an RNR NAK wait + * until the rnr timer has fired before starting the + * retry flow + */ + if (unlikely(qp->req.need_retry && !qp->req.wait_for_rnr_timer)) { req_retry(qp); qp->req.need_retry = 0; } diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index ac464e68c923..9bdf33346511 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -124,6 +124,7 @@ struct rxe_req_info { int need_rd_atomic; int wait_psn; int need_retry; + int wait_for_rnr_timer; int noack_pkts; struct rxe_task task; };
From: Vidya Sagar vidyas@nvidia.com
[ Upstream commit 6646e99bcec627e866bc84365af37942c72b4b76 ]
As part of Root Port interrupt handling, level-0 register is read first and based on the bits set in that, corresponding level-1 registers are read for further interrupt processing. Since both these values are currently read into the same 'val' variable, checking level-0 bits the second time around is happening on the 'val' variable value of level-1 register contents instead of freshly reading the level-0 value again.
Fix by using different variables to store level-0 and level-1 registers contents.
Link: https://lore.kernel.org/r/20220721142052.25971-11-vidyas@nvidia.com Fixes: 56e15a238d92 ("PCI: tegra: Add Tegra194 PCIe support") Signed-off-by: Vidya Sagar vidyas@nvidia.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-tegra194.c | 46 +++++++++++----------- 1 file changed, 22 insertions(+), 24 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index d992371a36e6..0bab700086f9 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -350,15 +350,14 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg) struct tegra194_pcie *pcie = arg; struct dw_pcie *pci = &pcie->pci; struct pcie_port *pp = &pci->pp; - u32 val, tmp; + u32 val, status_l0, status_l1; u16 val_w;
- val = appl_readl(pcie, APPL_INTR_STATUS_L0); - if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) { - val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0); - if (val & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) { - appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0); - + status_l0 = appl_readl(pcie, APPL_INTR_STATUS_L0); + if (status_l0 & APPL_INTR_STATUS_L0_LINK_STATE_INT) { + status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0); + appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_0_0); + if (status_l1 & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) { /* SBR & Surprise Link Down WAR */ val = appl_readl(pcie, APPL_CAR_RESET_OVRD); val &= ~APPL_CAR_RESET_OVRD_CYA_OVERRIDE_CORE_RST_N; @@ -374,15 +373,15 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg) } }
- if (val & APPL_INTR_STATUS_L0_INT_INT) { - val = appl_readl(pcie, APPL_INTR_STATUS_L1_8_0); - if (val & APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS) { + if (status_l0 & APPL_INTR_STATUS_L0_INT_INT) { + status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_8_0); + if (status_l1 & APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS) { appl_writel(pcie, APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS, APPL_INTR_STATUS_L1_8_0); apply_bad_link_workaround(pp); } - if (val & APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS) { + if (status_l1 & APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS) { appl_writel(pcie, APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS, APPL_INTR_STATUS_L1_8_0); @@ -394,25 +393,24 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg) } }
- val = appl_readl(pcie, APPL_INTR_STATUS_L0); - if (val & APPL_INTR_STATUS_L0_CDM_REG_CHK_INT) { - val = appl_readl(pcie, APPL_INTR_STATUS_L1_18); - tmp = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS); - if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT) { + if (status_l0 & APPL_INTR_STATUS_L0_CDM_REG_CHK_INT) { + status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_18); + val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS); + if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT) { dev_info(pci->dev, "CDM check complete\n"); - tmp |= PCIE_PL_CHK_REG_CHK_REG_COMPLETE; + val |= PCIE_PL_CHK_REG_CHK_REG_COMPLETE; } - if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR) { + if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR) { dev_err(pci->dev, "CDM comparison mismatch\n"); - tmp |= PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR; + val |= PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR; } - if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR) { + if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR) { dev_err(pci->dev, "CDM Logic error\n"); - tmp |= PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR; + val |= PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR; } - dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, tmp); - tmp = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_ERR_ADDR); - dev_err(pci->dev, "CDM Error Address Offset = 0x%08X\n", tmp); + dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val); + val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_ERR_ADDR); + dev_err(pci->dev, "CDM Error Address Offset = 0x%08X\n", val); }
return IRQ_HANDLED;
From: Vidya Sagar vidyas@nvidia.com
[ Upstream commit e05fd6ae77c3e2cc0dba283005d24b6d56d2b1fa ]
Add the missing DLF capability offset while clearing DL_FEATURE_EXCHANGE_EN bit during link up retry.
Link: https://lore.kernel.org/r/20220721142052.25971-15-vidyas@nvidia.com Fixes: 56e15a238d92 ("PCI: tegra: Add Tegra194 PCIe support") Signed-off-by: Vidya Sagar vidyas@nvidia.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-tegra194.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index 0bab700086f9..67e8372a3243 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -976,7 +976,7 @@ static int tegra194_pcie_start_link(struct dw_pcie *pci) offset = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_DLF); val = dw_pcie_readl_dbi(pci, offset + PCI_DLF_CAP); val &= ~PCI_DLF_EXCHANGE_ENABLE; - dw_pcie_writel_dbi(pci, offset, val); + dw_pcie_writel_dbi(pci, offset + PCI_DLF_CAP, val);
tegra194_pcie_host_init(pp); dw_pcie_setup_rc(pp);
From: Basavaraj Natikar Basavaraj.Natikar@amd.com
[ Upstream commit 5d4d0f15657535f6a122ab26d47230b5c2b944af ]
Add a check for num_hid_devices to handle special case the situation of "no sensors".
Fixes: 4b2c53d93a4b ("SFH:Transport Driver to add support of AMD Sensor Fusion Hub (SFH)") Signed-off-by: Basavaraj Natikar Basavaraj.Natikar@amd.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/amd-sfh-hid/amd_sfh_client.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c index 0f770a2b47ff..e27ee1871066 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c @@ -173,6 +173,8 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) dev = &privdata->pdev->dev;
cl_data->num_hid_devices = amd_mp2_get_sensor_num(privdata, &cl_data->sensor_idx[0]); + if (cl_data->num_hid_devices == 0) + return -ENODEV;
INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work); INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer);
From: Johan Hovold johan@kernel.org
[ Upstream commit 688ee1d1785c1359f9040f615dd8e6054962bce2 ]
Fix up the tty-port initialized comments which got truncated and obfuscated when replacing the old ASYNCB_INITIALIZED flag.
Fixes: d41861ca19c9 ("tty: Replace ASYNC_INITIALIZED bit and update atomically") Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/serial/sierra.c | 3 ++- drivers/usb/serial/usb-serial.c | 2 +- drivers/usb/serial/usb_wwan.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 9d56138133a9..ef6a2891f290 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -737,7 +737,8 @@ static void sierra_close(struct usb_serial_port *port)
/* * Need to take susp_lock to make sure port is not already being - * resumed, but no need to hold it due to initialized + * resumed, but no need to hold it due to the tty-port initialized + * flag. */ spin_lock_irq(&intfdata->susp_lock); if (--intfdata->open_ports == 0) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 24101bd7fcad..e35bea2235c1 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -295,7 +295,7 @@ static int serial_open(struct tty_struct *tty, struct file *filp) * * Shut down a USB serial port. Serialized against activate by the * tport mutex and kept to matching open/close pairs - * of calls by the initialized flag. + * of calls by the tty-port initialized flag. * * Not called if tty is console. */ diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index dab38b63eaf7..cc81ab7ef4da 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -388,7 +388,8 @@ void usb_wwan_close(struct usb_serial_port *port)
/* * Need to take susp_lock to make sure port is not already being - * resumed, but no need to hold it due to initialized + * resumed, but no need to hold it due to the tty-port initialized + * flag. */ spin_lock_irq(&intfdata->susp_lock); if (--intfdata->open_ports == 0)
From: Alexey Sheplyakov asheplyakov@basealt.ru
[ Upstream commit d7de14d74d6551f0d097430f9893ce82ad17e5b8 ]
Since commit 4736ebd7fcaff1eb8481c140ba494962847d6e0a ("usb: host: xhci-plat: omit shared hcd if either root hub has no ports") xhci->shared_hcd can be NULL, which causes the following Oops on reboot:
[ 710.124450] systemd-shutdown[1]: Rebooting. [ 710.298861] xhci-hcd xhci-hcd.2.auto: remove, state 4 [ 710.304217] usb usb3: USB disconnect, device number 1 [ 710.317441] xhci-hcd xhci-hcd.2.auto: USB bus 3 deregistered [ 710.323280] xhci-hcd xhci-hcd.2.auto: remove, state 1 [ 710.328401] usb usb2: USB disconnect, device number 1 [ 710.333515] usb 2-3: USB disconnect, device number 2 [ 710.467649] xhci-hcd xhci-hcd.2.auto: USB bus 2 deregistered [ 710.475450] Unable to handle kernel NULL pointer dereference at virtual address 00000000000003b8 [ 710.484425] Mem abort info: [ 710.487265] ESR = 0x0000000096000004 [ 710.491060] EC = 0x25: DABT (current EL), IL = 32 bits [ 710.496427] SET = 0, FnV = 0 [ 710.499525] EA = 0, S1PTW = 0 [ 710.502716] FSC = 0x04: level 0 translation fault [ 710.507648] Data abort info: [ 710.510577] ISV = 0, ISS = 0x00000004 [ 710.514462] CM = 0, WnR = 0 [ 710.517480] user pgtable: 4k pages, 48-bit VAs, pgdp=00000008b0050000 [ 710.523976] [00000000000003b8] pgd=0000000000000000, p4d=0000000000000000 [ 710.530961] Internal error: Oops: 96000004 [#1] PREEMPT SMP [ 710.536551] Modules linked in: rfkill input_leds snd_soc_simple_card snd_soc_simple_card_utils snd_soc_nau8822 designware_i2s snd_soc_core dw_hdmi_ahb_audio snd_pcm_dmaengine arm_ccn panfrost ac97_bus gpu_sched snd_pcm at24 fuse configfs sdhci_of_dwcmshc sdhci_pltfm sdhci nvme led_class mmc_core nvme_core bt1_pvt polynomial tp_serio snd_seq_midi snd_seq_midi_event snd_seq snd_timer snd_rawmidi snd_seq_device snd soundcore efivarfs ipv6 [ 710.575286] CPU: 7 PID: 1 Comm: systemd-shutdow Not tainted 5.19.0-rc7-00043-gfd8619f4fd54 #1 [ 710.583822] Hardware name: T-Platforms TF307-MB/BM1BM1-A, BIOS 5.6 07/06/2022 [ 710.590972] pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 710.597949] pc : usb_remove_hcd+0x34/0x1e4 [ 710.602067] lr : xhci_plat_remove+0x74/0x140 [ 710.606351] sp : ffff800009f3b7c0 [ 710.609674] x29: ffff800009f3b7c0 x28: ffff000800960040 x27: 0000000000000000 [ 710.616833] x26: ffff800008dc22a0 x25: 0000000000000000 x24: 0000000000000000 [ 710.623992] x23: 0000000000000000 x22: ffff000805465810 x21: ffff000805465800 [ 710.631149] x20: ffff000800f80000 x19: 0000000000000000 x18: ffffffffffffffff [ 710.638307] x17: ffff000805096000 x16: ffff00080633b800 x15: ffff000806537a1c [ 710.645465] x14: 0000000000000001 x13: 0000000000000000 x12: ffff00080378d6f0 [ 710.652621] x11: ffff00080041a900 x10: ffff800009b204e8 x9 : ffff8000088abaa4 [ 710.659779] x8 : ffff000800960040 x7 : ffff800009409000 x6 : 0000000000000001 [ 710.666936] x5 : ffff800009241000 x4 : ffff800009241440 x3 : 0000000000000000 [ 710.674094] x2 : ffff000800960040 x1 : ffff000800960040 x0 : 0000000000000000 [ 710.681251] Call trace: [ 710.683704] usb_remove_hcd+0x34/0x1e4 [ 710.687467] xhci_plat_remove+0x74/0x140 [ 710.691400] platform_remove+0x34/0x70 [ 710.695165] device_remove+0x54/0x90 [ 710.698753] device_release_driver_internal+0x200/0x270 [ 710.703992] device_release_driver+0x24/0x30 [ 710.708273] bus_remove_device+0xe0/0x16c [ 710.712293] device_del+0x178/0x390 [ 710.715797] platform_device_del.part.0+0x24/0x90 [ 710.720514] platform_device_unregister+0x30/0x50 [ 710.725232] dwc3_host_exit+0x20/0x30 [ 710.728907] dwc3_remove+0x174/0x1b0 [ 710.732494] platform_remove+0x34/0x70 [ 710.736254] device_remove+0x54/0x90 [ 710.739840] device_release_driver_internal+0x200/0x270 [ 710.745078] device_release_driver+0x24/0x30 [ 710.749359] bus_remove_device+0xe0/0x16c [ 710.753380] device_del+0x178/0x390 [ 710.756881] platform_device_del.part.0+0x24/0x90 [ 710.761598] platform_device_unregister+0x30/0x50 [ 710.766314] of_platform_device_destroy+0xe8/0x100 [ 710.771119] device_for_each_child_reverse+0x70/0xc0 [ 710.776099] of_platform_depopulate+0x48/0x90 [ 710.780468] __dwc3_of_simple_teardown+0x28/0xe0 [ 710.785099] dwc3_of_simple_shutdown+0x20/0x30 [ 710.789555] platform_shutdown+0x30/0x40 [ 710.793490] device_shutdown+0x138/0x32c [ 710.797425] __do_sys_reboot+0x1c4/0x2ac [ 710.801362] __arm64_sys_reboot+0x30/0x40 [ 710.805383] invoke_syscall+0x50/0x120 [ 710.809146] el0_svc_common.constprop.0+0x68/0x124 [ 710.813950] do_el0_svc+0x3c/0xcc [ 710.817275] el0_svc+0x60/0x12c [ 710.820428] el0t_64_sync_handler+0xc0/0x13c [ 710.824710] el0t_64_sync+0x18c/0x190 [ 710.828386] Code: a9025bf5 f942c420 f9001fe0 d2800000 (b943ba62) [ 710.834498] ---[ end trace 0000000000000000 ]--- [ 710.875958] pstore: crypto_comp_compress failed, ret = -22! [ 710.895047] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b [ 710.902757] Kernel Offset: disabled [ 710.906255] CPU features: 0x800,00004811,00001082 [ 710.910971] Memory Limit: none [ 710.927474] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
To avoid the problem check for NULL in usb_remove_hcd.
Fixes: 4736ebd7fcaf ("usb: host: xhci-plat: omit shared hcd if either root hub has no ports") Signed-off-by: Alexey Sheplyakov asheplyakov@basealt.ru Link: https://lore.kernel.org/r/20220722141700.1271439-1-asheplyakov@basealt.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/core/hcd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 11c8ea0cccc8..a6a87c5d1b05 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -3037,9 +3037,15 @@ EXPORT_SYMBOL_GPL(usb_add_hcd); */ void usb_remove_hcd(struct usb_hcd *hcd) { - struct usb_device *rhdev = hcd->self.root_hub; + struct usb_device *rhdev; bool rh_registered;
+ if (!hcd) { + pr_debug("%s: hcd is NULL\n", __func__); + return; + } + rhdev = hcd->self.root_hub; + dev_info(hcd->self.controller, "remove, state %x\n", hcd->state);
usb_get_dev(rhdev);
From: Andrey Strachuk strochuk@ispras.ru
[ Upstream commit c3ffc9c4ca44bfe9562166793d133e1fb0630ea6 ]
If 'ep' is NULL, result of ep_to_cdns3_ep(ep) is invalid pointer and its dereference with priv_ep->cdns3_dev may cause panic.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") Acked-by: Peter Chen peter.chen@kernel.org Signed-off-by: Andrey Strachuk strochuk@ispras.ru Link: https://lore.kernel.org/r/20220718160052.4188-1-strochuk@ispras.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/cdns3/cdns3-gadget.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c index f5f5fbbefec0..1f38ccd637d0 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -2285,14 +2285,15 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep, int val;
priv_ep = ep_to_cdns3_ep(ep); - priv_dev = priv_ep->cdns3_dev; - comp_desc = priv_ep->endpoint.comp_desc;
if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) { dev_dbg(priv_dev->dev, "usbss: invalid parameters\n"); return -EINVAL; }
+ comp_desc = priv_ep->endpoint.comp_desc; + priv_dev = priv_ep->cdns3_dev; + if (!desc->wMaxPacketSize) { dev_err(priv_dev->dev, "usbss: missing wMaxPacketSize\n"); return -EINVAL; @@ -2600,7 +2601,7 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep, struct usb_request *request) { struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); - struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + struct cdns3_device *priv_dev; struct usb_request *req, *req_temp; struct cdns3_request *priv_req; struct cdns3_trb *link_trb; @@ -2611,6 +2612,8 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep, if (!ep || !request || !ep->desc) return -EINVAL;
+ priv_dev = priv_ep->cdns3_dev; + spin_lock_irqsave(&priv_dev->lock, flags);
priv_req = to_cdns3_request(request);
From: Patrice Chotard patrice.chotard@foss.st.com
[ Upstream commit f8cd9f632f4415b1e8838bdca8ab42cfb37a6584 ]
For erase operations, reg_proto must be used as indicated in struct spi_nor description in spi-nor.h.
This issue was found when DT property spi-tx-bus-width is set to 4. In this case the spi_mem_op->addr.buswidth is set to 4 for erase command which is not correct.
Tested on stm32mp157c-ev1 board with mx66l51235f spi-nor.
Fixes: 0e30f47232ab ("mtd: spi-nor: add support for DTR protocol") Signed-off-by: Patrice Chotard patrice.chotard@foss.st.com [ta: use nor->reg_proto in spi_nor_controller_ops_erase()] Signed-off-by: Tudor Ambarus tudor.ambarus@microchip.com Tested-by: Alexander Sverdlin alexander.sverdlin@nokia.com Reviewed-by: Pratyush Yadav p.yadav@ti.com Link: https://lore.kernel.org/r/20220629133013.3382393-1-patrice.chotard@foss.st.c... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/spi-nor/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 502967c76c5f..e758ebfe1a9f 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -177,7 +177,7 @@ int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode,
static int spi_nor_controller_ops_erase(struct spi_nor *nor, loff_t offs) { - if (spi_nor_protocol_is_dtr(nor->write_proto)) + if (spi_nor_protocol_is_dtr(nor->reg_proto)) return -EOPNOTSUPP;
return nor->controller_ops->erase(nor, offs); @@ -972,7 +972,7 @@ static int spi_nor_erase_chip(struct spi_nor *nor) if (nor->spimem) { struct spi_mem_op op = SPI_NOR_CHIP_ERASE_OP;
- spi_nor_spimem_setup_op(nor, &op, nor->write_proto); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
ret = spi_mem_exec_op(nor->spimem, &op); } else { @@ -1115,7 +1115,7 @@ int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) SPI_NOR_SECTOR_ERASE_OP(nor->erase_opcode, nor->addr_width, addr);
- spi_nor_spimem_setup_op(nor, &op, nor->write_proto); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
return spi_mem_exec_op(nor->spimem, &op); } else if (nor->controller_ops->erase) {
From: Peter Suti peter.suti@streamunlimited.com
[ Upstream commit 81e878887ff82a7dd42f22951391069a5d520627 ]
The fbtft_framebuffer_alloc() calls fb_deferred_io_init() before initializing info->fix.smem_len. It is set to zero by the framebuffer_alloc() function. It will trigger a WARN_ON() at the start of fb_deferred_io_init() and the function will not do anything.
Fixes: 856082f021a2 ("fbdev: defio: fix the pagelist corruption") Signed-off-by: Peter Suti peter.suti@streamunlimited.com Link: https://lore.kernel.org/r/20220727073550.1491126-1-peter.suti@streamunlimite... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/fbtft/fbtft-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index 60b2278d8b16..ebf4e8ce4de9 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -655,7 +655,6 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, fbdefio->delay = HZ / fps; fbdefio->sort_pagereflist = true; fbdefio->deferred_io = fbtft_deferred_io; - fb_deferred_io_init(info);
snprintf(info->fix.id, sizeof(info->fix.id), "%s", dev->driver->name); info->fix.type = FB_TYPE_PACKED_PIXELS; @@ -666,6 +665,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, info->fix.line_length = width * bpp / 8; info->fix.accel = FB_ACCEL_NONE; info->fix.smem_len = vmem_size; + fb_deferred_io_init(info);
info->var.rotate = pdata->rotate; info->var.xres = width;
From: Sean Christopherson seanjc@google.com
[ Upstream commit a910b5ab6b250a88fff1866bf708642d83317466 ]
Make UMIP an "allowed-1" bit CR4_FIXED1 MSR when KVM is emulating UMIP. KVM emulates UMIP for both L1 and L2, and so should enumerate that L2 is allowed to have CR4.UMIP=1. Not setting the bit doesn't immediately break nVMX, as KVM does set/clear the bit in CR4_FIXED1 in response to a guest CPUID update, i.e. KVM will correctly (dis)allow nested VM-Entry based on whether or not UMIP is exposed to L1. That said, KVM should enumerate the bit as being allowed from time zero, e.g. userspace will see the wrong value if the MSR is read before CPUID is written.
Fixes: 0367f205a3b7 ("KVM: vmx: add support for emulating UMIP") Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220607213604.3346000-12-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kvm/vmx/nested.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 66735fbb791d..1b9e5bd2f941 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -6786,6 +6786,9 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps) rdmsrl(MSR_IA32_VMX_CR0_FIXED1, msrs->cr0_fixed1); rdmsrl(MSR_IA32_VMX_CR4_FIXED1, msrs->cr4_fixed1);
+ if (vmx_umip_emulated()) + msrs->cr4_fixed1 |= X86_CR4_UMIP; + msrs->vmcs_enum = nested_vmx_calc_vmcs_enum_msr(); }
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit d9f74d98bbec978edbf860f729b531281ba0d8ff ]
Change > MAX_DIE_PER_PACKAGE to >= MAX_DIE_PER_PACKAGE to prevent accessing one element beyond the end of the array.
Fixes: 7fd786dfbd2c ("tools/power/x86/intel-speed-select: OOB daemon mode") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/power/x86/intel-speed-select/isst-daemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/power/x86/intel-speed-select/isst-daemon.c b/tools/power/x86/intel-speed-select/isst-daemon.c index dd372924bc82..d0400c6684ba 100644 --- a/tools/power/x86/intel-speed-select/isst-daemon.c +++ b/tools/power/x86/intel-speed-select/isst-daemon.c @@ -41,7 +41,7 @@ void process_level_change(int cpu) time_t tm; int ret;
- if (pkg_id >= MAX_PACKAGE_COUNT || die_id > MAX_DIE_PER_PACKAGE) { + if (pkg_id >= MAX_PACKAGE_COUNT || die_id >= MAX_DIE_PER_PACKAGE) { debug_printf("Invalid package/die info for cpu:%d\n", cpu); return; }
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit c9d959fc32a5f9312282817052d8986614f2dc08 ]
The critclk_systems[] DMI match table already contains 2 Lex BayTrail boards and patches were just submitted to add 3 more entries for the following models: 3I380NX, 3I380A, 3I380CW.
Looking at: https://www.lex.com.tw/products/embedded-ipc-board/ we can see that Lex BayTrail makes many embedded boards with multiple ethernet boards and none of their products are battery powered so we don't need to worry (too much) about power consumption when suspended.
Add a new DMI match which simply matches all Lex BayTrail boards and drop the 2 existing board specific quirks.
Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Reported-by: Michael Schöne michael.schoene@rhebo.com Reported-by: Paul Spooren paul.spooren@rhebo.com Reported-by: Matwey V. Kornilov matwey@sai.msu.ru Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/pmc_atom.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c index b8b1ed1406de..154317e9910d 100644 --- a/drivers/platform/x86/pmc_atom.c +++ b/drivers/platform/x86/pmc_atom.c @@ -389,21 +389,16 @@ static const struct dmi_system_id critclk_systems[] = { }, }, { - /* pmc_plt_clk0 - 3 are used for the 4 ethernet controllers */ - .ident = "Lex 3I380D", + /* + * Lex System / Lex Computech Co. makes a lot of Bay Trail + * based embedded boards which often come with multiple + * ethernet controllers using multiple pmc_plt_clks. See: + * https://www.lex.com.tw/products/embedded-ipc-board/ + */ + .ident = "Lex BayTrail", .callback = dmi_callback, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Lex BayTrail"), - DMI_MATCH(DMI_PRODUCT_NAME, "3I380D"), - }, - }, - { - /* pmc_plt_clk* - are used for ethernet controllers */ - .ident = "Lex 2I385SW", - .callback = dmi_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Lex BayTrail"), - DMI_MATCH(DMI_PRODUCT_NAME, "2I385SW"), }, }, {
From: Vadim Pasternak vadimp@nvidia.com
[ Upstream commit b4b830a34d8046633231b7fe87f6f2cb6240dc9f ]
Fix error flow: - Clean-up client object in case of probing failure. - Prevent running remove routine in case of probing failure. Probing and removing are invoked by hotplug events raised upon line card insertion and removing. If probing procedure failed all data is cleared and there is nothing to do in remove routine.
Fixes: 62f9529b8d5c ("platform/mellanox: mlxreg-lc: Add initial support for Nvidia line card devices") Signed-off-by: Vadim Pasternak vadimp@nvidia.com Link: https://lore.kernel.org/r/20220719153540.61304-1-vadimp@nvidia.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/mellanox/mlxreg-lc.c | 82 ++++++++++++++++++++------- 1 file changed, 63 insertions(+), 19 deletions(-)
diff --git a/drivers/platform/mellanox/mlxreg-lc.c b/drivers/platform/mellanox/mlxreg-lc.c index c897a2f15840..55834ccb4ac7 100644 --- a/drivers/platform/mellanox/mlxreg-lc.c +++ b/drivers/platform/mellanox/mlxreg-lc.c @@ -716,8 +716,12 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap, switch (regval) { case MLXREG_LC_SN4800_C16: err = mlxreg_lc_sn4800_c16_config_init(mlxreg_lc, regmap, data); - if (err) + if (err) { + dev_err(dev, "Failed to config client %s at bus %d at addr 0x%02x\n", + data->hpdev.brdinfo->type, data->hpdev.nr, + data->hpdev.brdinfo->addr); return err; + } break; default: return -ENODEV; @@ -730,8 +734,11 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap, mlxreg_lc->mux = platform_device_register_resndata(dev, "i2c-mux-mlxcpld", data->hpdev.nr, NULL, 0, mlxreg_lc->mux_data, sizeof(*mlxreg_lc->mux_data)); - if (IS_ERR(mlxreg_lc->mux)) + if (IS_ERR(mlxreg_lc->mux)) { + dev_err(dev, "Failed to create mux infra for client %s at bus %d at addr 0x%02x\n", + data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr); return PTR_ERR(mlxreg_lc->mux); + }
/* Register IO access driver. */ if (mlxreg_lc->io_data) { @@ -740,6 +747,9 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap, platform_device_register_resndata(dev, "mlxreg-io", data->hpdev.nr, NULL, 0, mlxreg_lc->io_data, sizeof(*mlxreg_lc->io_data)); if (IS_ERR(mlxreg_lc->io_regs)) { + dev_err(dev, "Failed to create regio for client %s at bus %d at addr 0x%02x\n", + data->hpdev.brdinfo->type, data->hpdev.nr, + data->hpdev.brdinfo->addr); err = PTR_ERR(mlxreg_lc->io_regs); goto fail_register_io; } @@ -753,6 +763,9 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap, mlxreg_lc->led_data, sizeof(*mlxreg_lc->led_data)); if (IS_ERR(mlxreg_lc->led)) { + dev_err(dev, "Failed to create LED objects for client %s at bus %d at addr 0x%02x\n", + data->hpdev.brdinfo->type, data->hpdev.nr, + data->hpdev.brdinfo->addr); err = PTR_ERR(mlxreg_lc->led); goto fail_register_led; } @@ -809,7 +822,8 @@ static int mlxreg_lc_probe(struct platform_device *pdev) if (!data->hpdev.adapter) { dev_err(&pdev->dev, "Failed to get adapter for bus %d\n", data->hpdev.nr); - return -EFAULT; + err = -EFAULT; + goto i2c_get_adapter_fail; }
/* Create device at the top of line card I2C tree.*/ @@ -818,32 +832,40 @@ static int mlxreg_lc_probe(struct platform_device *pdev) if (IS_ERR(data->hpdev.client)) { dev_err(&pdev->dev, "Failed to create client %s at bus %d at addr 0x%02x\n", data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr); - - i2c_put_adapter(data->hpdev.adapter); - data->hpdev.adapter = NULL; - return PTR_ERR(data->hpdev.client); + err = PTR_ERR(data->hpdev.client); + goto i2c_new_device_fail; }
regmap = devm_regmap_init_i2c(data->hpdev.client, &mlxreg_lc_regmap_conf); if (IS_ERR(regmap)) { + dev_err(&pdev->dev, "Failed to create regmap for client %s at bus %d at addr 0x%02x\n", + data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr); err = PTR_ERR(regmap); - goto mlxreg_lc_probe_fail; + goto devm_regmap_init_i2c_fail; }
/* Set default registers. */ for (i = 0; i < mlxreg_lc_regmap_conf.num_reg_defaults; i++) { err = regmap_write(regmap, mlxreg_lc_regmap_default[i].reg, mlxreg_lc_regmap_default[i].def); - if (err) - goto mlxreg_lc_probe_fail; + if (err) { + dev_err(&pdev->dev, "Failed to set default regmap %d for client %s at bus %d at addr 0x%02x\n", + i, data->hpdev.brdinfo->type, data->hpdev.nr, + data->hpdev.brdinfo->addr); + goto regmap_write_fail; + } }
/* Sync registers with hardware. */ regcache_mark_dirty(regmap); err = regcache_sync(regmap); - if (err) - goto mlxreg_lc_probe_fail; + if (err) { + dev_err(&pdev->dev, "Failed to sync regmap for client %s at bus %d at addr 0x%02x\n", + data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr); + err = PTR_ERR(regmap); + goto regcache_sync_fail; + }
par_pdata = data->hpdev.brdinfo->platform_data; mlxreg_lc->par_regmap = par_pdata->regmap; @@ -854,12 +876,27 @@ static int mlxreg_lc_probe(struct platform_device *pdev) /* Configure line card. */ err = mlxreg_lc_config_init(mlxreg_lc, regmap, data); if (err) - goto mlxreg_lc_probe_fail; + goto mlxreg_lc_config_init_fail;
return err;
-mlxreg_lc_probe_fail: +mlxreg_lc_config_init_fail: +regcache_sync_fail: +regmap_write_fail: +devm_regmap_init_i2c_fail: + if (data->hpdev.client) { + i2c_unregister_device(data->hpdev.client); + data->hpdev.client = NULL; + } +i2c_new_device_fail: i2c_put_adapter(data->hpdev.adapter); + data->hpdev.adapter = NULL; +i2c_get_adapter_fail: + /* Clear event notification callback and handle. */ + if (data->notifier) { + data->notifier->user_handler = NULL; + data->notifier->handle = NULL; + } return err; }
@@ -868,11 +905,18 @@ static int mlxreg_lc_remove(struct platform_device *pdev) struct mlxreg_core_data *data = dev_get_platdata(&pdev->dev); struct mlxreg_lc *mlxreg_lc = platform_get_drvdata(pdev);
- /* Clear event notification callback. */ - if (data->notifier) { - data->notifier->user_handler = NULL; - data->notifier->handle = NULL; - } + /* + * Probing and removing are invoked by hotplug events raised upon line card insertion and + * removing. If probing procedure fails all data is cleared. However, hotplug event still + * will be raised on line card removing and activate removing procedure. In this case there + * is nothing to remove. + */ + if (!data->notifier || !data->notifier->handle) + return 0; + + /* Clear event notification callback and handle. */ + data->notifier->user_handler = NULL; + data->notifier->handle = NULL;
/* Destroy static I2C device feeding by main power. */ mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 40ec787e1adf302c11668d4cc69838f4d584187d ]
The call to:
size = simple_write_to_buffer(cmdbuf, sizeof(cmdbuf), ppos, buf, size);
will succeed if at least one byte is written to the "cmdbuf" buffer. The "*ppos" value controls which byte is written. Another problem is that this code does not check for errors so it's possible for the entire buffer to be uninitialized.
Inintialize the struct to zero to prevent reading uninitialized stack data.
Debugfs is normally only writable by root so the impact of this bug is very minimal.
Fixes: 6cca83d498bd ("Platform: OLPC: move debugfs support from x86 EC driver") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/YthIKn+TfZSZMEcM@kili 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/olpc/olpc-ec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/platform/olpc/olpc-ec.c b/drivers/platform/olpc/olpc-ec.c index 4ff5c3a12991..921520475ff6 100644 --- a/drivers/platform/olpc/olpc-ec.c +++ b/drivers/platform/olpc/olpc-ec.c @@ -264,7 +264,7 @@ static ssize_t ec_dbgfs_cmd_write(struct file *file, const char __user *buf, int i, m; unsigned char ec_cmd[EC_MAX_CMD_ARGS]; unsigned int ec_cmd_int[EC_MAX_CMD_ARGS]; - char cmdbuf[64]; + char cmdbuf[64] = ""; int ec_cmd_bytes;
mutex_lock(&ec_dbgfs_lock);
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit b03b1ae2a3125d4475452e4f19f5d3a6e910ff6e ]
Prepare for decoupling the lifetimes of struct srpt_port and struct srpt_port_id by duplicating the port name into struct srpt_port.
Link: https://lore.kernel.org/r/20220727193415.1583860-2-bvanassche@acm.org Signed-off-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/srpt/ib_srpt.c | 9 ++++++--- drivers/infiniband/ulp/srpt/ib_srpt.h | 10 +++++++--- 2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index f86ee1c4b970..8253d55b9c26 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -566,14 +566,17 @@ static int srpt_refresh_port(struct srpt_port *sport) return ret;
sport->port_guid_id.wwn.priv = sport; - srpt_format_guid(sport->port_guid_id.name, - sizeof(sport->port_guid_id.name), + srpt_format_guid(sport->guid_name, ARRAY_SIZE(sport->guid_name), &sport->gid.global.interface_id); + memcpy(sport->port_guid_id.name, sport->guid_name, + ARRAY_SIZE(sport->guid_name)); sport->port_gid_id.wwn.priv = sport; - snprintf(sport->port_gid_id.name, sizeof(sport->port_gid_id.name), + snprintf(sport->gid_name, ARRAY_SIZE(sport->gid_name), "0x%016llx%016llx", be64_to_cpu(sport->gid.global.subnet_prefix), be64_to_cpu(sport->gid.global.interface_id)); + memcpy(sport->port_gid_id.name, sport->gid_name, + ARRAY_SIZE(sport->gid_name));
if (rdma_protocol_iwarp(sport->sdev->device, sport->port)) return 0; diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h index 76e66f630c17..3844a7058559 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.h +++ b/drivers/infiniband/ulp/srpt/ib_srpt.h @@ -376,7 +376,7 @@ struct srpt_tpg { };
/** - * struct srpt_port_id - information about an RDMA port name + * struct srpt_port_id - LIO RDMA port information * @mutex: Protects @tpg_list changes. * @tpg_list: TPGs associated with the RDMA port name. * @wwn: WWN associated with the RDMA port name. @@ -402,8 +402,10 @@ struct srpt_port_id { * @lid: cached value of the port's lid. * @gid: cached value of the port's gid. * @work: work structure for refreshing the aforementioned cached values. - * @port_guid_id: target port GUID - * @port_gid_id: target port GID + * @guid_name: port name in GUID format. + * @port_guid_id: LIO target port information for the port name in GUID format. + * @gid_name: port name in GID format. + * @port_gid_id: LIO target port information for the port name in GID format. * @port_attrib: Port attributes that can be accessed through configfs. * @refcount: Number of objects associated with this port. * @freed_channels: Completion that will be signaled once @refcount becomes 0. @@ -419,7 +421,9 @@ struct srpt_port { u32 lid; union ib_gid gid; struct work_struct work; + char guid_name[64]; struct srpt_port_id port_guid_id; + char gid_name[64]; struct srpt_port_id port_gid_id; struct srpt_port_attrib port_attrib; atomic_t refcount;
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit aa7dfbb41b5a60ab90e244d6f586b8cb5c791c3e ]
This will be used to keep struct srpt_device around as long as either the RDMA port exists or a LIO target port is associated with the struct srpt_device.
Link: https://lore.kernel.org/r/20220727193415.1583860-3-bvanassche@acm.org Signed-off-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/srpt/ib_srpt.c | 17 +++++++++++++++-- drivers/infiniband/ulp/srpt/ib_srpt.h | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 8253d55b9c26..1fbce9225424 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3104,6 +3104,18 @@ static int srpt_use_srq(struct srpt_device *sdev, bool use_srq) return ret; }
+static void srpt_free_sdev(struct kref *refcnt) +{ + struct srpt_device *sdev = container_of(refcnt, typeof(*sdev), refcnt); + + kfree(sdev); +} + +static void srpt_sdev_put(struct srpt_device *sdev) +{ + kref_put(&sdev->refcnt, srpt_free_sdev); +} + /** * srpt_add_one - InfiniBand device addition callback function * @device: Describes a HCA. @@ -3122,6 +3134,7 @@ static int srpt_add_one(struct ib_device *device) if (!sdev) return -ENOMEM;
+ kref_init(&sdev->refcnt); sdev->device = device; mutex_init(&sdev->sdev_mutex);
@@ -3217,7 +3230,7 @@ static int srpt_add_one(struct ib_device *device) srpt_free_srq(sdev); ib_dealloc_pd(sdev->pd); free_dev: - kfree(sdev); + srpt_sdev_put(sdev); pr_info("%s(%s) failed.\n", __func__, dev_name(&device->dev)); return ret; } @@ -3261,7 +3274,7 @@ static void srpt_remove_one(struct ib_device *device, void *client_data)
ib_dealloc_pd(sdev->pd);
- kfree(sdev); + srpt_sdev_put(sdev); }
static struct ib_client srpt_client = { diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h index 3844a7058559..0cb867d580f1 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.h +++ b/drivers/infiniband/ulp/srpt/ib_srpt.h @@ -434,6 +434,7 @@ struct srpt_port {
/** * struct srpt_device - information associated by SRPT with a single HCA + * @refcnt: Reference count for this device. * @device: Backpointer to the struct ib_device managed by the IB core. * @pd: IB protection domain. * @lkey: L_Key (local key) with write access to all local memory. @@ -449,6 +450,7 @@ struct srpt_port { * @port: Information about the ports owned by this HCA. */ struct srpt_device { + struct kref refcnt; struct ib_device *device; struct ib_pd *pd; u32 lkey;
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit b5605148e6ce36bb21020d49010b617693933128 ]
Change the LIO port members inside struct srpt_port from regular members into pointers. Allocate the LIO port data structures from inside srpt_make_tport() and free these from inside srpt_make_tport(). Keep struct srpt_device as long as either an RDMA port or a LIO target port is associated with it. This patch decouples the lifetime of struct srpt_port (controlled by the RDMA core) and struct srpt_port_id (controlled by LIO). This patch fixes the following KASAN complaint:
BUG: KASAN: use-after-free in srpt_enable_tpg+0x31/0x70 [ib_srpt] Read of size 8 at addr ffff888141cc34b8 by task check/5093
Call Trace: <TASK> show_stack+0x4e/0x53 dump_stack_lvl+0x51/0x66 print_address_description.constprop.0.cold+0xea/0x41e print_report.cold+0x90/0x205 kasan_report+0xb9/0xf0 __asan_load8+0x69/0x90 srpt_enable_tpg+0x31/0x70 [ib_srpt] target_fabric_tpg_base_enable_store+0xe2/0x140 [target_core_mod] configfs_write_iter+0x18b/0x210 new_sync_write+0x1f2/0x2f0 vfs_write+0x3e3/0x540 ksys_write+0xbb/0x140 __x64_sys_write+0x42/0x50 do_syscall_64+0x34/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 </TASK>
Link: https://lore.kernel.org/r/20220727193415.1583860-4-bvanassche@acm.org Reported-by: Li Zhijian lizhijian@fujitsu.com Tested-by: Li Zhijian lizhijian@fujitsu.com Fixes: a42d985bd5b2 ("ib_srpt: Initial SRP Target merge for v3.3-rc1") Signed-off-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/srpt/ib_srpt.c | 130 ++++++++++++++++++-------- drivers/infiniband/ulp/srpt/ib_srpt.h | 10 +- 2 files changed, 94 insertions(+), 46 deletions(-)
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 1fbce9225424..c3036aeac89e 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -565,18 +565,12 @@ static int srpt_refresh_port(struct srpt_port *sport) if (ret) return ret;
- sport->port_guid_id.wwn.priv = sport; srpt_format_guid(sport->guid_name, ARRAY_SIZE(sport->guid_name), &sport->gid.global.interface_id); - memcpy(sport->port_guid_id.name, sport->guid_name, - ARRAY_SIZE(sport->guid_name)); - sport->port_gid_id.wwn.priv = sport; snprintf(sport->gid_name, ARRAY_SIZE(sport->gid_name), "0x%016llx%016llx", be64_to_cpu(sport->gid.global.subnet_prefix), be64_to_cpu(sport->gid.global.interface_id)); - memcpy(sport->port_gid_id.name, sport->gid_name, - ARRAY_SIZE(sport->gid_name));
if (rdma_protocol_iwarp(sport->sdev->device, sport->port)) return 0; @@ -2317,31 +2311,35 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, tag_num = ch->rq_size; tag_size = 1; /* ib_srpt does not use se_sess->sess_cmd_map */
- mutex_lock(&sport->port_guid_id.mutex); - list_for_each_entry(stpg, &sport->port_guid_id.tpg_list, entry) { - if (!IS_ERR_OR_NULL(ch->sess)) - break; - ch->sess = target_setup_session(&stpg->tpg, tag_num, + if (sport->guid_id) { + mutex_lock(&sport->guid_id->mutex); + list_for_each_entry(stpg, &sport->guid_id->tpg_list, entry) { + if (!IS_ERR_OR_NULL(ch->sess)) + break; + ch->sess = target_setup_session(&stpg->tpg, tag_num, tag_size, TARGET_PROT_NORMAL, ch->sess_name, ch, NULL); + } + mutex_unlock(&sport->guid_id->mutex); } - mutex_unlock(&sport->port_guid_id.mutex);
- mutex_lock(&sport->port_gid_id.mutex); - list_for_each_entry(stpg, &sport->port_gid_id.tpg_list, entry) { - if (!IS_ERR_OR_NULL(ch->sess)) - break; - ch->sess = target_setup_session(&stpg->tpg, tag_num, + if (sport->gid_id) { + mutex_lock(&sport->gid_id->mutex); + list_for_each_entry(stpg, &sport->gid_id->tpg_list, entry) { + if (!IS_ERR_OR_NULL(ch->sess)) + break; + ch->sess = target_setup_session(&stpg->tpg, tag_num, tag_size, TARGET_PROT_NORMAL, i_port_id, ch, NULL); - if (!IS_ERR_OR_NULL(ch->sess)) - break; - /* Retry without leading "0x" */ - ch->sess = target_setup_session(&stpg->tpg, tag_num, + if (!IS_ERR_OR_NULL(ch->sess)) + break; + /* Retry without leading "0x" */ + ch->sess = target_setup_session(&stpg->tpg, tag_num, tag_size, TARGET_PROT_NORMAL, i_port_id + 2, ch, NULL); + } + mutex_unlock(&sport->gid_id->mutex); } - mutex_unlock(&sport->port_gid_id.mutex);
if (IS_ERR_OR_NULL(ch->sess)) { WARN_ON_ONCE(ch->sess == NULL); @@ -2986,7 +2984,12 @@ static int srpt_release_sport(struct srpt_port *sport) return 0; }
-static struct se_wwn *__srpt_lookup_wwn(const char *name) +struct port_and_port_id { + struct srpt_port *sport; + struct srpt_port_id **port_id; +}; + +static struct port_and_port_id __srpt_lookup_port(const char *name) { struct ib_device *dev; struct srpt_device *sdev; @@ -3001,25 +3004,38 @@ static struct se_wwn *__srpt_lookup_wwn(const char *name) for (i = 0; i < dev->phys_port_cnt; i++) { sport = &sdev->port[i];
- if (strcmp(sport->port_guid_id.name, name) == 0) - return &sport->port_guid_id.wwn; - if (strcmp(sport->port_gid_id.name, name) == 0) - return &sport->port_gid_id.wwn; + if (strcmp(sport->guid_name, name) == 0) { + kref_get(&sdev->refcnt); + return (struct port_and_port_id){ + sport, &sport->guid_id}; + } + if (strcmp(sport->gid_name, name) == 0) { + kref_get(&sdev->refcnt); + return (struct port_and_port_id){ + sport, &sport->gid_id}; + } } }
- return NULL; + return (struct port_and_port_id){}; }
-static struct se_wwn *srpt_lookup_wwn(const char *name) +/** + * srpt_lookup_port() - Look up an RDMA port by name + * @name: ASCII port name + * + * Increments the RDMA port reference count if an RDMA port pointer is returned. + * The caller must drop that reference count by calling srpt_port_put_ref(). + */ +static struct port_and_port_id srpt_lookup_port(const char *name) { - struct se_wwn *wwn; + struct port_and_port_id papi;
spin_lock(&srpt_dev_lock); - wwn = __srpt_lookup_wwn(name); + papi = __srpt_lookup_port(name); spin_unlock(&srpt_dev_lock);
- return wwn; + return papi; }
static void srpt_free_srq(struct srpt_device *sdev) @@ -3198,10 +3214,6 @@ static int srpt_add_one(struct ib_device *device) sport->port_attrib.srp_sq_size = DEF_SRPT_SQ_SIZE; sport->port_attrib.use_srq = false; INIT_WORK(&sport->work, srpt_refresh_port_work); - mutex_init(&sport->port_guid_id.mutex); - INIT_LIST_HEAD(&sport->port_guid_id.tpg_list); - mutex_init(&sport->port_gid_id.mutex); - INIT_LIST_HEAD(&sport->port_gid_id.tpg_list);
ret = srpt_refresh_port(sport); if (ret) { @@ -3302,10 +3314,10 @@ static struct srpt_port_id *srpt_wwn_to_sport_id(struct se_wwn *wwn) { struct srpt_port *sport = wwn->priv;
- if (wwn == &sport->port_guid_id.wwn) - return &sport->port_guid_id; - if (wwn == &sport->port_gid_id.wwn) - return &sport->port_gid_id; + if (sport->guid_id && &sport->guid_id->wwn == wwn) + return sport->guid_id; + if (sport->gid_id && &sport->gid_id->wwn == wwn) + return sport->gid_id; WARN_ON_ONCE(true); return NULL; } @@ -3790,7 +3802,31 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf, struct config_group *group, const char *name) { - return srpt_lookup_wwn(name) ? : ERR_PTR(-EINVAL); + struct port_and_port_id papi = srpt_lookup_port(name); + struct srpt_port *sport = papi.sport; + struct srpt_port_id *port_id; + + if (!papi.port_id) + return ERR_PTR(-EINVAL); + if (*papi.port_id) { + /* Attempt to create a directory that already exists. */ + WARN_ON_ONCE(true); + return &(*papi.port_id)->wwn; + } + port_id = kzalloc(sizeof(*port_id), GFP_KERNEL); + if (!port_id) { + srpt_sdev_put(sport->sdev); + return ERR_PTR(-ENOMEM); + } + mutex_init(&port_id->mutex); + INIT_LIST_HEAD(&port_id->tpg_list); + port_id->wwn.priv = sport; + memcpy(port_id->name, port_id == sport->guid_id ? sport->guid_name : + sport->gid_name, ARRAY_SIZE(port_id->name)); + + *papi.port_id = port_id; + + return &port_id->wwn; }
/** @@ -3799,6 +3835,18 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf, */ static void srpt_drop_tport(struct se_wwn *wwn) { + struct srpt_port_id *port_id = container_of(wwn, typeof(*port_id), wwn); + struct srpt_port *sport = wwn->priv; + + if (sport->guid_id == port_id) + sport->guid_id = NULL; + else if (sport->gid_id == port_id) + sport->gid_id = NULL; + else + WARN_ON_ONCE(true); + + srpt_sdev_put(sport->sdev); + kfree(port_id); }
static ssize_t srpt_wwn_version_show(struct config_item *item, char *buf) diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h index 0cb867d580f1..4c46b301eea1 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.h +++ b/drivers/infiniband/ulp/srpt/ib_srpt.h @@ -393,7 +393,7 @@ struct srpt_port_id { };
/** - * struct srpt_port - information associated by SRPT with a single IB port + * struct srpt_port - SRPT RDMA port information * @sdev: backpointer to the HCA information. * @mad_agent: per-port management datagram processing information. * @enabled: Whether or not this target port is enabled. @@ -403,9 +403,9 @@ struct srpt_port_id { * @gid: cached value of the port's gid. * @work: work structure for refreshing the aforementioned cached values. * @guid_name: port name in GUID format. - * @port_guid_id: LIO target port information for the port name in GUID format. + * @guid_id: LIO target port information for the port name in GUID format. * @gid_name: port name in GID format. - * @port_gid_id: LIO target port information for the port name in GID format. + * @gid_id: LIO target port information for the port name in GID format. * @port_attrib: Port attributes that can be accessed through configfs. * @refcount: Number of objects associated with this port. * @freed_channels: Completion that will be signaled once @refcount becomes 0. @@ -422,9 +422,9 @@ struct srpt_port { union ib_gid gid; struct work_struct work; char guid_name[64]; - struct srpt_port_id port_guid_id; + struct srpt_port_id *guid_id; char gid_name[64]; - struct srpt_port_id port_gid_id; + struct srpt_port_id *gid_id; struct srpt_port_attrib port_attrib; atomic_t refcount; struct completion *freed_channels;
From: Liam R. Howlett Liam.Howlett@oracle.com
[ Upstream commit a43cfc87caaf46710c8027a8c23b8a55f1078f19 ]
Do not record a pointer to a VMA outside of the mmap_lock for later use. This is unsafe and there are a number of failure paths *after* the recorded VMA pointer may be freed during setup. There is no callback to the driver to clear the saved pointer from generic mm code. Furthermore, the VMA pointer may become stale if any number of VMA operations end up freeing the VMA so saving it was fragile to being with.
Instead, change the binder_alloc struct to record the start address of the VMA and use vma_lookup() to get the vma when needed. Add lockdep mmap_lock checks on updates to the vma pointer to ensure the lock is held and depend on that lock for synchronization of readers and writers - which was already the case anyways, so the smp_wmb()/smp_rmb() was not necessary.
[akpm@linux-foundation.org: fix drivers/android/binder_alloc_selftest.c] Link: https://lkml.kernel.org/r/20220621140212.vpkio64idahetbyf@revolver Fixes: da1b9564e85b ("android: binder: fix the race mmap and alloc_new_buf_locked") Reported-by: syzbot+58b51ac2b04e388ab7b0@syzkaller.appspotmail.com Signed-off-by: Liam R. Howlett Liam.Howlett@oracle.com Cc: Minchan Kim minchan@kernel.org Cc: Christian Brauner (Microsoft) brauner@kernel.org Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Hridya Valsaraju hridya@google.com Cc: Joel Fernandes joel@joelfernandes.org Cc: Martijn Coenen maco@android.com Cc: Suren Baghdasaryan surenb@google.com Cc: Todd Kjos tkjos@android.com Cc: Matthew Wilcox (Oracle) willy@infradead.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/android/binder_alloc.c | 30 ++++++++++++------------- drivers/android/binder_alloc.h | 2 +- drivers/android/binder_alloc_selftest.c | 2 +- 3 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 5649a0371a1f..d044418294f9 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -213,7 +213,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
if (mm) { mmap_read_lock(mm); - vma = alloc->vma; + vma = vma_lookup(mm, alloc->vma_addr); }
if (!vma && need_mm) { @@ -313,16 +313,15 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, static inline void binder_alloc_set_vma(struct binder_alloc *alloc, struct vm_area_struct *vma) { - if (vma) + unsigned long vm_start = 0; + + if (vma) { + vm_start = vma->vm_start; alloc->vma_vm_mm = vma->vm_mm; - /* - * If we see alloc->vma is not NULL, buffer data structures set up - * completely. Look at smp_rmb side binder_alloc_get_vma. - * We also want to guarantee new alloc->vma_vm_mm is always visible - * if alloc->vma is set. - */ - smp_wmb(); - alloc->vma = vma; + } + + mmap_assert_write_locked(alloc->vma_vm_mm); + alloc->vma_addr = vm_start; }
static inline struct vm_area_struct *binder_alloc_get_vma( @@ -330,11 +329,9 @@ static inline struct vm_area_struct *binder_alloc_get_vma( { struct vm_area_struct *vma = NULL;
- if (alloc->vma) { - /* Look at description in binder_alloc_set_vma */ - smp_rmb(); - vma = alloc->vma; - } + if (alloc->vma_addr) + vma = vma_lookup(alloc->vma_vm_mm, alloc->vma_addr); + return vma; }
@@ -817,7 +814,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)
buffers = 0; mutex_lock(&alloc->mutex); - BUG_ON(alloc->vma); + BUG_ON(alloc->vma_addr && + vma_lookup(alloc->vma_vm_mm, alloc->vma_addr));
while ((n = rb_first(&alloc->allocated_buffers))) { buffer = rb_entry(n, struct binder_buffer, rb_node); diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h index 7dea57a84c79..1e4fd37af5e0 100644 --- a/drivers/android/binder_alloc.h +++ b/drivers/android/binder_alloc.h @@ -100,7 +100,7 @@ struct binder_lru_page { */ struct binder_alloc { struct mutex mutex; - struct vm_area_struct *vma; + unsigned long vma_addr; struct mm_struct *vma_vm_mm; void __user *buffer; struct list_head buffers; diff --git a/drivers/android/binder_alloc_selftest.c b/drivers/android/binder_alloc_selftest.c index c2b323bc3b3a..43a881073a42 100644 --- a/drivers/android/binder_alloc_selftest.c +++ b/drivers/android/binder_alloc_selftest.c @@ -287,7 +287,7 @@ void binder_selftest_alloc(struct binder_alloc *alloc) if (!binder_selftest_run) return; mutex_lock(&binder_selftest_lock); - if (!binder_selftest_run || !alloc->vma) + if (!binder_selftest_run || !alloc->vma_addr) goto done; pr_info("STARTED\n"); binder_selftest_alloc_offset(alloc, end_offset, 0);
From: Miaohe Lin linmiaohe@huawei.com
[ Upstream commit 7f82f922319ede486540e8746769865b9508d2c2 ]
Since the beginning, charged is set to 0 to avoid calling vm_unacct_memory twice because vm_unacct_memory will be called by above unmap_region. But since commit 4f74d2c8e827 ("vm: remove 'nr_accounted' calculations from the unmap_vmas() interfaces"), unmap_region doesn't call vm_unacct_memory anymore. So charged shouldn't be set to 0 now otherwise the calling to paired vm_unacct_memory will be missed and leads to imbalanced account.
Link: https://lkml.kernel.org/r/20220618082027.43391-1-linmiaohe@huawei.com Fixes: 4f74d2c8e827 ("vm: remove 'nr_accounted' calculations from the unmap_vmas() interfaces") Signed-off-by: Miaohe Lin linmiaohe@huawei.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/mmap.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/mm/mmap.c b/mm/mmap.c index 61e6135c54ef..7c59ec73acc3 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1894,7 +1894,6 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
/* Undo any partial mapping done by a device driver. */ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); - charged = 0; if (vm_flags & VM_SHARED) mapping_unmap_writable(file->f_mapping); free_vma:
From: Adam Sindelar adam@wowsignal.io
[ Upstream commit 3b8e7f5c42d1aa44f71fd219717c80e34101361e ]
mrelease_test should return KSFT_SKIP when process_mrelease is not defined, but due to a perror call consuming the errno, it returns KSFT_FAIL.
This patch decides the exit code before calling perror.
[adam@wowsignal.io: fix remaining instances of errno mishandling] Link: https://lkml.kernel.org/r/20220706141602.10159-1-adam@wowsignal.io Link: https://lkml.kernel.org/r/20220704173351.19595-1-adam@wowsignal.io Fixes: 33776141b812 ("selftests: vm: add process_mrelease tests") Signed-off-by: Adam Sindelar adam@wowsignal.io Reviewed-by: David Vernet void@manifault.com Reviewed-by: Suren Baghdasaryan surenb@google.com Cc: Shuah Khan shuah@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/vm/mrelease_test.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/vm/mrelease_test.c b/tools/testing/selftests/vm/mrelease_test.c index 96671c2f7d48..6c62966ab5db 100644 --- a/tools/testing/selftests/vm/mrelease_test.c +++ b/tools/testing/selftests/vm/mrelease_test.c @@ -62,19 +62,22 @@ static int alloc_noexit(unsigned long nr_pages, int pipefd) /* The process_mrelease calls in this test are expected to fail */ static void run_negative_tests(int pidfd) { + int res; /* Test invalid flags. Expect to fail with EINVAL error code. */ if (!syscall(__NR_process_mrelease, pidfd, (unsigned int)-1) || errno != EINVAL) { + res = (errno == ENOSYS ? KSFT_SKIP : KSFT_FAIL); perror("process_mrelease with wrong flags"); - exit(errno == ENOSYS ? KSFT_SKIP : KSFT_FAIL); + exit(res); } /* * Test reaping while process is alive with no pending SIGKILL. * Expect to fail with EINVAL error code. */ if (!syscall(__NR_process_mrelease, pidfd, 0) || errno != EINVAL) { + res = (errno == ENOSYS ? KSFT_SKIP : KSFT_FAIL); perror("process_mrelease on a live process"); - exit(errno == ENOSYS ? KSFT_SKIP : KSFT_FAIL); + exit(res); } }
@@ -100,8 +103,9 @@ int main(void)
/* Test a wrong pidfd */ if (!syscall(__NR_process_mrelease, -1, 0) || errno != EBADF) { + res = (errno == ENOSYS ? KSFT_SKIP : KSFT_FAIL); perror("process_mrelease with wrong pidfd"); - exit(errno == ENOSYS ? KSFT_SKIP : KSFT_FAIL); + exit(res); }
/* Start the test with 1MB child memory allocation */ @@ -156,8 +160,9 @@ int main(void) run_negative_tests(pidfd);
if (kill(pid, SIGKILL)) { + res = (errno == ENOSYS ? KSFT_SKIP : KSFT_FAIL); perror("kill"); - exit(errno == ENOSYS ? KSFT_SKIP : KSFT_FAIL); + exit(res); }
success = (syscall(__NR_process_mrelease, pidfd, 0) == 0); @@ -172,9 +177,10 @@ int main(void) if (errno == ESRCH) { retry = (size <= MAX_SIZE_MB); } else { + res = (errno == ENOSYS ? KSFT_SKIP : KSFT_FAIL); perror("process_mrelease"); waitpid(pid, NULL, 0); - exit(errno == ENOSYS ? KSFT_SKIP : KSFT_FAIL); + exit(res); } }
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 3d5367a0426da61c7cb616cc85b6239467e261dd ]
This code just reads from memory without caring about the data itself. However static checkers complain that "tmp" is never properly initialized. Initialize it to zero and change the name to "dummy" to show that we don't care about the value stored in it.
Link: https://lkml.kernel.org/r/YtZ8mKJmktA2GaHB@kili Fixes: c4b6cb884011 ("selftests/vm: add hugetlb madvise MADV_DONTNEED MADV_REMOVE test") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Souptick Joarder (HPE) jrdr.linux@gmail.com Reviewed-by: Mike Kravetz mike.kravetz@oracle.com Cc: Shuah Khan shuah@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/vm/hugetlb-madvise.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/vm/hugetlb-madvise.c b/tools/testing/selftests/vm/hugetlb-madvise.c index 6c6af40f5747..3c9943131881 100644 --- a/tools/testing/selftests/vm/hugetlb-madvise.c +++ b/tools/testing/selftests/vm/hugetlb-madvise.c @@ -89,10 +89,11 @@ void write_fault_pages(void *addr, unsigned long nr_pages)
void read_fault_pages(void *addr, unsigned long nr_pages) { - unsigned long i, tmp; + unsigned long dummy = 0; + unsigned long i;
for (i = 0; i < nr_pages; i++) - tmp += *((unsigned long *)(addr + (i * huge_page_size))); + dummy += *((unsigned long *)(addr + (i * huge_page_size))); }
int main(int argc, char **argv)
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 360b420dbded8ad5b70a41de98e77354dd9e7d36 ]
Initialize "length" to zero by default.
Link: https://lkml.kernel.org/r/YtZzjvHXVXMXxpXO@kili Fixes: ff712a627f72 ("selftests/vm: cleanup hugetlb file after mremap test") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Mina Almasry almasrymina@google.com Reviewed-by: Muchun Song songmuchun@bytedance.com Cc: Mike Kravetz mike.kravetz@oracle.com Cc: Shuah Khan shuah@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/vm/hugepage-mremap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/vm/hugepage-mremap.c b/tools/testing/selftests/vm/hugepage-mremap.c index 585978f181ed..e63a0214f639 100644 --- a/tools/testing/selftests/vm/hugepage-mremap.c +++ b/tools/testing/selftests/vm/hugepage-mremap.c @@ -107,7 +107,7 @@ static void register_region_with_uffd(char *addr, size_t len)
int main(int argc, char *argv[]) { - size_t length; + size_t length = 0;
if (argc != 2 && argc != 3) { printf("Usage: %s [length_in_MB] <hugetlb_file>\n", argv[0]);
From: Daniel Bristot de Oliveira bristot@kernel.org
[ Upstream commit c7d8a598c5b1e21a0957f5dec2ef4139d2d1a23a ]
Sedat Dilek reported an error on rtla Makefile when running:
$ make -C tools/ clean [...] make[2]: Entering directory '/home/dileks/src/linux-kernel/git/tools/tracing/rtla' [...] '/home/dileks/src/linux-kernel/git/Documentation/tools/rtla' /bin/sh: 1: test: rtla-make[2]:: unexpected operator <------ The problem rm: cannot remove '/home/dileks/src/linux-kernel/git': Is a directory make[2]: *** [Makefile:120: clean] Error 1 make[2]: Leaving directory
This occurred because the rtla calls kernel's Makefile to get the version in silence mode, e.g.,
$ make -sC ../../.. kernelversion 5.19.0-rc4
But the -s is being ignored when rtla's makefile is called indirectly, so the output looks like this:
$ make -C ../../.. kernelversion make: Entering directory '/root/linux' 5.19.0-rc4 make: Leaving directory '/root/linux'
Using 'grep -v make' avoids this problem, e.g.,
$ make -C ../../.. kernelversion | grep -v make 5.19.0-rc4
Thus, add | grep -v make.
Link: https://lkml.kernel.org/r/870c02d4d97a921f02a31fa3b229fc549af61a20.165774776...
Fixes: 8619e32825fd ("rtla: Follow kernel version") Reported-by: Sedat Dilek sedat.dilek@gmail.com Tested-by: Sedat Dilek sedat.dilek@gmail.com Signed-off-by: Daniel Bristot de Oliveira bristot@kernel.org Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/tracing/rtla/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile index 3822f4ea5f49..1bea2d16d4c1 100644 --- a/tools/tracing/rtla/Makefile +++ b/tools/tracing/rtla/Makefile @@ -1,6 +1,6 @@ NAME := rtla # Follow the kernel version -VERSION := $(shell cat VERSION 2> /dev/null || make -sC ../../.. kernelversion) +VERSION := $(shell cat VERSION 2> /dev/null || make -sC ../../.. kernelversion | grep -v make)
# From libtracefs: # Makefiles suck: This macro sets a default value of $(2) for the
From: Andreas Schwab schwab@suse.de
[ Upstream commit 4f753c3be52c1d930afc0fe3169baa605dbaf611 ]
Avoid double free by making trace_instance_destroy indempotent. When trace_instance_init fails, it calls trace_instance_destroy, but its only caller osnoise_destroy_tool calls it again.
Link: https://lkml.kernel.org/r/mvmilnlkyzx.fsf_-_@suse.de
Fixes: 0605bf009f18 ("rtla: Add osnoise tool") Signed-off-by: Andreas Schwab schwab@suse.de Acked-by: Daniel Bristot de Oliveira bristot@kernel.org Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/tracing/rtla/src/trace.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tools/tracing/rtla/src/trace.c b/tools/tracing/rtla/src/trace.c index 5784c9f9e570..e1ba6d9f4265 100644 --- a/tools/tracing/rtla/src/trace.c +++ b/tools/tracing/rtla/src/trace.c @@ -134,13 +134,18 @@ void trace_instance_destroy(struct trace_instance *trace) if (trace->inst) { disable_tracer(trace->inst); destroy_instance(trace->inst); + trace->inst = NULL; }
- if (trace->seq) + if (trace->seq) { free(trace->seq); + trace->seq = NULL; + }
- if (trace->tep) + if (trace->tep) { tep_free(trace->tep); + trace->tep = NULL; + } }
/*
From: Juergen Gross jgross@suse.com
[ Upstream commit a603002eea8213eec5211be5a85db8340aea06d0 ]
Instead of having a global flag to require restricted memory access for all virtio devices, introduce a callback which can select that requirement on a per-device basis.
For convenience add a common function returning always true, which can be used for use cases like SEV.
Per default use a callback always returning false.
As the callback needs to be set in early init code already, add a virtio anchor which is builtin in case virtio is enabled.
Signed-off-by: Juergen Gross jgross@suse.com Tested-by: Oleksandr Tyshchenko oleksandr_tyshchenko@epam.com # Arm64 guest using Xen Reviewed-by: Stefano Stabellini sstabellini@kernel.org Link: https://lore.kernel.org/r/20220622063838.8854-2-jgross@suse.com Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/mm/init.c | 4 ++-- arch/x86/mm/mem_encrypt_amd.c | 4 ++-- drivers/virtio/Kconfig | 4 ++++ drivers/virtio/Makefile | 1 + drivers/virtio/virtio.c | 4 ++-- drivers/virtio/virtio_anchor.c | 18 ++++++++++++++++++ include/linux/platform-feature.h | 6 +----- include/linux/virtio_anchor.h | 19 +++++++++++++++++++ include/xen/xen.h | 4 ++-- 9 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 drivers/virtio/virtio_anchor.c create mode 100644 include/linux/virtio_anchor.h
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 6a0ac00d5a42..4a154a084966 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -31,7 +31,6 @@ #include <linux/cma.h> #include <linux/gfp.h> #include <linux/dma-direct.h> -#include <linux/platform-feature.h> #include <asm/processor.h> #include <linux/uaccess.h> #include <asm/pgalloc.h> @@ -48,6 +47,7 @@ #include <asm/kasan.h> #include <asm/dma-mapping.h> #include <asm/uv.h> +#include <linux/virtio_anchor.h> #include <linux/virtio_config.h>
pgd_t swapper_pg_dir[PTRS_PER_PGD] __section(".bss..swapper_pg_dir"); @@ -175,7 +175,7 @@ static void pv_init(void) if (!is_prot_virt_guest()) return;
- platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS); + virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc);
/* make sure bounce buffers are shared */ swiotlb_init(true, SWIOTLB_FORCE | SWIOTLB_VERBOSE); diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c index f6d038e2cd8e..97452688f99f 100644 --- a/arch/x86/mm/mem_encrypt_amd.c +++ b/arch/x86/mm/mem_encrypt_amd.c @@ -20,8 +20,8 @@ #include <linux/bitops.h> #include <linux/dma-mapping.h> #include <linux/virtio_config.h> +#include <linux/virtio_anchor.h> #include <linux/cc_platform.h> -#include <linux/platform-feature.h>
#include <asm/tlbflush.h> #include <asm/fixmap.h> @@ -245,7 +245,7 @@ void __init sev_setup_arch(void) swiotlb_adjust_size(size);
/* Set restricted memory access for virtio. */ - platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS); + virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc); }
static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot) diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index e1556d2a355a..56c77f63cd22 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -1,6 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-only +config VIRTIO_ANCHOR + bool + config VIRTIO tristate + select VIRTIO_ANCHOR help This option is selected by any driver which implements the virtio bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_RPMSG diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile index 0a82d0873248..8e98d24917cc 100644 --- a/drivers/virtio/Makefile +++ b/drivers/virtio/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_VIRTIO) += virtio.o virtio_ring.o +obj-$(CONFIG_VIRTIO_ANCHOR) += virtio_anchor.o obj-$(CONFIG_VIRTIO_PCI_LIB) += virtio_pci_modern_dev.o obj-$(CONFIG_VIRTIO_PCI_LIB_LEGACY) += virtio_pci_legacy_dev.o obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 7deeed30d1f3..14c142d77fba 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -2,10 +2,10 @@ #include <linux/virtio.h> #include <linux/spinlock.h> #include <linux/virtio_config.h> +#include <linux/virtio_anchor.h> #include <linux/module.h> #include <linux/idr.h> #include <linux/of.h> -#include <linux/platform-feature.h> #include <uapi/linux/virtio_ids.h>
/* Unique numbering for virtio devices. */ @@ -174,7 +174,7 @@ static int virtio_features_ok(struct virtio_device *dev)
might_sleep();
- if (platform_has(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS)) { + if (virtio_check_mem_acc_cb(dev)) { if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1)) { dev_warn(&dev->dev, "device must provide VIRTIO_F_VERSION_1\n"); diff --git a/drivers/virtio/virtio_anchor.c b/drivers/virtio/virtio_anchor.c new file mode 100644 index 000000000000..4d6a5d269b55 --- /dev/null +++ b/drivers/virtio/virtio_anchor.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include <linux/virtio.h> +#include <linux/virtio_anchor.h> + +bool virtio_require_restricted_mem_acc(struct virtio_device *dev) +{ + return true; +} +EXPORT_SYMBOL_GPL(virtio_require_restricted_mem_acc); + +static bool virtio_no_restricted_mem_acc(struct virtio_device *dev) +{ + return false; +} + +bool (*virtio_check_mem_acc_cb)(struct virtio_device *dev) = + virtio_no_restricted_mem_acc; +EXPORT_SYMBOL_GPL(virtio_check_mem_acc_cb); diff --git a/include/linux/platform-feature.h b/include/linux/platform-feature.h index b2f48be999fa..6ed859928b97 100644 --- a/include/linux/platform-feature.h +++ b/include/linux/platform-feature.h @@ -6,11 +6,7 @@ #include <asm/platform-feature.h>
/* The platform features are starting with the architecture specific ones. */ - -/* Used to enable platform specific DMA handling for virtio devices. */ -#define PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS (0 + PLATFORM_ARCH_FEAT_N) - -#define PLATFORM_FEAT_N (1 + PLATFORM_ARCH_FEAT_N) +#define PLATFORM_FEAT_N (0 + PLATFORM_ARCH_FEAT_N)
void platform_set(unsigned int feature); void platform_clear(unsigned int feature); diff --git a/include/linux/virtio_anchor.h b/include/linux/virtio_anchor.h new file mode 100644 index 000000000000..432e6c00b3ca --- /dev/null +++ b/include/linux/virtio_anchor.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_VIRTIO_ANCHOR_H +#define _LINUX_VIRTIO_ANCHOR_H + +#ifdef CONFIG_VIRTIO_ANCHOR +struct virtio_device; + +bool virtio_require_restricted_mem_acc(struct virtio_device *dev); +extern bool (*virtio_check_mem_acc_cb)(struct virtio_device *dev); + +static inline void virtio_set_mem_acc_cb(bool (*func)(struct virtio_device *)) +{ + virtio_check_mem_acc_cb = func; +} +#else +#define virtio_set_mem_acc_cb(func) do { } while (0) +#endif + +#endif /* _LINUX_VIRTIO_ANCHOR_H */ diff --git a/include/xen/xen.h b/include/xen/xen.h index 0780a81e140d..ac5a144c6a65 100644 --- a/include/xen/xen.h +++ b/include/xen/xen.h @@ -52,12 +52,12 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, extern u64 xen_saved_max_mem_size; #endif
-#include <linux/platform-feature.h> +#include <linux/virtio_anchor.h>
static inline void xen_set_restricted_virtio_memory_access(void) { if (IS_ENABLED(CONFIG_XEN_VIRTIO) && xen_domain()) - platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS); + virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc); }
#ifdef CONFIG_XEN_UNPOPULATED_ALLOC
From: Juergen Gross jgross@suse.com
[ Upstream commit 251e90e7e346a23742b90e2c4db19d322e071d99 ]
Commit fa1f57421e0b ("xen/virtio: Enable restricted memory access using Xen grant mappings") introduced a new requirement for using virtio devices: the backend now needs to support the VIRTIO_F_ACCESS_PLATFORM feature.
This is an undue requirement for non-PV guests, as those can be operated with existing backends without any problem, as long as those backends are running in dom0.
Per default allow virtio devices without grant support for non-PV guests.
On Arm require VIRTIO_F_ACCESS_PLATFORM for devices having been listed in the device tree to use grants.
Add a new config item to always force use of grants for virtio.
Fixes: fa1f57421e0b ("xen/virtio: Enable restricted memory access using Xen grant mappings") Reported-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Juergen Gross jgross@suse.com Reviewed-by: Oleksandr Tyshchenko oleksandr_tyshchenko@epam.com Tested-by: Oleksandr Tyshchenko oleksandr_tyshchenko@epam.com # Arm64 guest using Xen Reviewed-by: Stefano Stabellini sstabellini@kernel.org Link: https://lore.kernel.org/r/20220622063838.8854-4-jgross@suse.com Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/xen/enlighten.c | 4 +++- arch/x86/xen/enlighten_hvm.c | 4 +++- arch/x86/xen/enlighten_pv.c | 5 ++++- drivers/xen/Kconfig | 9 +++++++++ drivers/xen/grant-dma-ops.c | 10 ++++++++++ include/xen/xen-ops.h | 9 +++++++++ include/xen/xen.h | 8 -------- 7 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 1f9c3ba32833..93c8ccbf2982 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -34,6 +34,7 @@ #include <linux/timekeeping.h> #include <linux/timekeeper_internal.h> #include <linux/acpi.h> +#include <linux/virtio_anchor.h>
#include <linux/mm.h>
@@ -443,7 +444,8 @@ static int __init xen_guest_init(void) if (!xen_domain()) return 0;
- xen_set_restricted_virtio_memory_access(); + if (IS_ENABLED(CONFIG_XEN_VIRTIO)) + virtio_set_mem_acc_cb(xen_virtio_mem_acc);
if (!acpi_disabled) xen_acpi_guest_init(); diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c index 8b71b1dd7639..28762f800596 100644 --- a/arch/x86/xen/enlighten_hvm.c +++ b/arch/x86/xen/enlighten_hvm.c @@ -4,6 +4,7 @@ #include <linux/cpu.h> #include <linux/kexec.h> #include <linux/memblock.h> +#include <linux/virtio_anchor.h>
#include <xen/features.h> #include <xen/events.h> @@ -195,7 +196,8 @@ static void __init xen_hvm_guest_init(void) if (xen_pv_domain()) return;
- xen_set_restricted_virtio_memory_access(); + if (IS_ENABLED(CONFIG_XEN_VIRTIO_FORCE_GRANT)) + virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc);
init_hvm_pv_info();
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 70fb2ea85e90..0ed2e487a693 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -31,6 +31,7 @@ #include <linux/gfp.h> #include <linux/edd.h> #include <linux/reboot.h> +#include <linux/virtio_anchor.h>
#include <xen/xen.h> #include <xen/events.h> @@ -109,7 +110,9 @@ static DEFINE_PER_CPU(struct tls_descs, shadow_tls_desc);
static void __init xen_pv_init_platform(void) { - xen_set_restricted_virtio_memory_access(); + /* PV guests can't operate virtio devices without grants. */ + if (IS_ENABLED(CONFIG_XEN_VIRTIO)) + virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc);
populate_extra_pte(fix_to_virt(FIX_PARAVIRT_BOOTMAP));
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index bfd5f4f706bc..a65bd92121a5 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -355,4 +355,13 @@ config XEN_VIRTIO
If in doubt, say n.
+config XEN_VIRTIO_FORCE_GRANT + bool "Require Xen virtio support to use grants" + depends on XEN_VIRTIO + help + Require virtio for Xen guests to use grant mappings. + This will avoid the need to give the backend the right to map all + of the guest memory. This will need support on the backend side + (e.g. qemu or kernel, depending on the virtio device types used). + endmenu diff --git a/drivers/xen/grant-dma-ops.c b/drivers/xen/grant-dma-ops.c index fc0142484001..8973fc1e9ccc 100644 --- a/drivers/xen/grant-dma-ops.c +++ b/drivers/xen/grant-dma-ops.c @@ -12,6 +12,8 @@ #include <linux/of.h> #include <linux/pfn.h> #include <linux/xarray.h> +#include <linux/virtio_anchor.h> +#include <linux/virtio.h> #include <xen/xen.h> #include <xen/xen-ops.h> #include <xen/grant_table.h> @@ -287,6 +289,14 @@ bool xen_is_grant_dma_device(struct device *dev) return has_iommu; }
+bool xen_virtio_mem_acc(struct virtio_device *dev) +{ + if (IS_ENABLED(CONFIG_XEN_VIRTIO_FORCE_GRANT)) + return true; + + return xen_is_grant_dma_device(dev->dev.parent); +} + void xen_grant_setup_dma_ops(struct device *dev) { struct xen_grant_dma_data *data; diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index 80546960f8b7..dae0f350c678 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -5,6 +5,7 @@ #include <linux/percpu.h> #include <linux/notifier.h> #include <linux/efi.h> +#include <linux/virtio_anchor.h> #include <xen/features.h> #include <asm/xen/interface.h> #include <xen/interface/vcpu.h> @@ -217,6 +218,7 @@ static inline void xen_preemptible_hcall_end(void) { } #ifdef CONFIG_XEN_GRANT_DMA_OPS void xen_grant_setup_dma_ops(struct device *dev); bool xen_is_grant_dma_device(struct device *dev); +bool xen_virtio_mem_acc(struct virtio_device *dev); #else static inline void xen_grant_setup_dma_ops(struct device *dev) { @@ -225,6 +227,13 @@ static inline bool xen_is_grant_dma_device(struct device *dev) { return false; } + +struct virtio_device; + +static inline bool xen_virtio_mem_acc(struct virtio_device *dev) +{ + return false; +} #endif /* CONFIG_XEN_GRANT_DMA_OPS */
#endif /* INCLUDE_XEN_OPS_H */ diff --git a/include/xen/xen.h b/include/xen/xen.h index ac5a144c6a65..a99bab817523 100644 --- a/include/xen/xen.h +++ b/include/xen/xen.h @@ -52,14 +52,6 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, extern u64 xen_saved_max_mem_size; #endif
-#include <linux/virtio_anchor.h> - -static inline void xen_set_restricted_virtio_memory_access(void) -{ - if (IS_ENABLED(CONFIG_XEN_VIRTIO) && xen_domain()) - virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc); -} - #ifdef CONFIG_XEN_UNPOPULATED_ALLOC int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages); void xen_free_unpopulated_pages(unsigned int nr_pages, struct page **pages);
From: Andrei Vagin avagin@google.com
[ Upstream commit 281106f938d3daaea6f8b6723a8217a2a1ef6936 ]
kvm_hypercall has to place the hypercall number in rax.
Trace events show that kvm_pv_test doesn't work properly: kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0 kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0 kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0
With this change, it starts working as expected: kvm_pv_test-54285: kvm_hypercall: nr 0x5 a0 0x0 a1 0x0 a2 0x0 a3 0x0 kvm_pv_test-54285: kvm_hypercall: nr 0xa a0 0x0 a1 0x0 a2 0x0 a3 0x0 kvm_pv_test-54285: kvm_hypercall: nr 0xb a0 0x0 a1 0x0 a2 0x0 a3 0x0
Signed-off-by: Andrei Vagin avagin@google.com Message-Id: 20220722230241.1944655-5-avagin@google.com Fixes: ac4a4d6de22e ("selftests: kvm: test enforcement of paravirtual cpuid features") Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/kvm/lib/x86_64/processor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index ead7011ee8f6..5d85e1c021da 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -1422,7 +1422,7 @@ uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2,
asm volatile("vmcall" : "=a"(r) - : "b"(a0), "c"(a1), "d"(a2), "S"(a3)); + : "a"(nr), "b"(a0), "c"(a1), "d"(a2), "S"(a3)); return r; }
From: Xu Qiang xuqiang36@huawei.com
[ Upstream commit 7913145afa51bbed9eaf8e5b4ee55fa9884a71e5 ]
The commit 649cab56de8e (“of: properly check for error returned by fdt_get_name()”) changed the return value type from bool to int, but forgot to change the return value simultaneously.
populate_node was only called in unflatten_dt_nodes, and returns with values greater than or equal to 0 were discarded without further processing. Considering that return 0 usually indicates success, return 0 instead of return true.
Fixes: 649cab56de8e (“of: properly check for error returned by fdt_get_name()”) Signed-off-by: Xu Qiang xuqiang36@huawei.com Signed-off-by: Rob Herring robh@kernel.org Link: https://lore.kernel.org/r/20220801120506.11461-2-xuqiang36@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/fdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index a8f5b6532165..520ed965bb7a 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -246,7 +246,7 @@ static int populate_node(const void *blob, }
*pnp = np; - return true; + return 0; }
static void reverse_nodes(struct device_node *parent)
From: Maor Gottlieb maorg@nvidia.com
[ Upstream commit c9776457bd5eaad4ce4ecb17af8d8f3cc6957c0b ]
Add missing check for return value when calling to mlx5_ib_ft_type_to_namespace, even though it can't really fail in this specific call.
Fixes: 52438be44112 ("RDMA/mlx5: Allow inserting a steering rule to the FDB") Link: https://lore.kernel.org/r/7b9ceda217d9368a51dc47a46b769bad4af9ac92.165925606... Reviewed-by: Itay Aveksis itayav@nvidia.com Signed-off-by: Maor Gottlieb maorg@nvidia.com Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/mlx5/fs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/fs.c b/drivers/infiniband/hw/mlx5/fs.c index 39ffb363ba0c..531aa35ba67c 100644 --- a/drivers/infiniband/hw/mlx5/fs.c +++ b/drivers/infiniband/hw/mlx5/fs.c @@ -2050,12 +2050,10 @@ static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs, if (err) return err;
- if (flags) { - mlx5_ib_ft_type_to_namespace( + if (flags) + return mlx5_ib_ft_type_to_namespace( MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX, &obj->ns_type); - return 0; - } }
obj->ns_type = MLX5_FLOW_NAMESPACE_BYPASS;
From: Zhu Yanjun yanjun.zhu@linux.dev
[ Upstream commit fd5382c5805c4bcb50fd25b7246247d3f7114733 ]
In the function rxe_create_qp(), rxe_qp_from_init() is called to initialize qp, internally things like the spin locks are not setup until rxe_qp_init_req().
If an error occures before this point then the unwind will call rxe_cleanup() and eventually to rxe_qp_do_cleanup()/rxe_cleanup_task() which will oops when trying to access the uninitialized spinlock.
Move the spinlock initializations earlier before any failures.
Fixes: 8700e3e7c485 ("Soft RoCE driver") Link: https://lore.kernel.org/r/20220731063621.298405-1-yanjun.zhu@linux.dev Reported-by: syzbot+833061116fa28df97f3b@syzkaller.appspotmail.com Signed-off-by: Zhu Yanjun yanjun.zhu@linux.dev Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_qp.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c index 834f40ad00af..fd706dc3009d 100644 --- a/drivers/infiniband/sw/rxe/rxe_qp.c +++ b/drivers/infiniband/sw/rxe/rxe_qp.c @@ -174,6 +174,14 @@ static void rxe_qp_init_misc(struct rxe_dev *rxe, struct rxe_qp *qp,
spin_lock_init(&qp->state_lock);
+ spin_lock_init(&qp->req.task.state_lock); + spin_lock_init(&qp->resp.task.state_lock); + spin_lock_init(&qp->comp.task.state_lock); + + spin_lock_init(&qp->sq.sq_lock); + spin_lock_init(&qp->rq.producer_lock); + spin_lock_init(&qp->rq.consumer_lock); + atomic_set(&qp->ssn, 0); atomic_set(&qp->skb_out, 0); } @@ -233,7 +241,6 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp, qp->req.opcode = -1; qp->comp.opcode = -1;
- spin_lock_init(&qp->sq.sq_lock); skb_queue_head_init(&qp->req_pkts);
rxe_init_task(rxe, &qp->req.task, qp, @@ -284,9 +291,6 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp, } }
- spin_lock_init(&qp->rq.producer_lock); - spin_lock_init(&qp->rq.consumer_lock); - skb_queue_head_init(&qp->resp_pkts);
rxe_init_task(rxe, &qp->resp.task, qp,
From: Md Haris Iqbal haris.iqbal@ionos.com
[ Upstream commit 4bc14f3101364877dd59085f39e068a2a7ec9f2d ]
After setting keep_id if the mutex trylock fails, the keep_id stays set for the rest of the sess_dev lifetime.
Therefore, set keep_id to true after mutex_trylock succeeds, so that a failure of trylock does'nt touch keep_id.
Fixes: b168e1d85cf3 ("block/rnbd-srv: Prevent a deadlock generated by accessing sysfs in parallel") Cc: gi-oh.kim@ionos.com Signed-off-by: Md Haris Iqbal haris.iqbal@ionos.com Signed-off-by: Jack Wang jinpu.wang@ionos.com Link: https://lore.kernel.org/r/20220707143122.460362-2-haris.iqbal@ionos.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/rnbd/rnbd-srv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c index beaef43a67b9..cf9e29a08db2 100644 --- a/drivers/block/rnbd/rnbd-srv.c +++ b/drivers/block/rnbd/rnbd-srv.c @@ -323,10 +323,11 @@ void rnbd_srv_sess_dev_force_close(struct rnbd_srv_sess_dev *sess_dev, { struct rnbd_srv_session *sess = sess_dev->sess;
- sess_dev->keep_id = true; /* It is already started to close by client's close message. */ if (!mutex_trylock(&sess->lock)) return; + + sess_dev->keep_id = true; /* first remove sysfs itself to avoid deadlock */ sysfs_remove_file_self(&sess_dev->kobj, &attr->attr); rnbd_srv_destroy_dev_session_sysfs(sess_dev);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit ee452a8d984f94fa8e894f003a52e776e4572881 ]
There needs to be some error checking if ida_simple_get() fails. Also call ida_free() if there are errors later.
Fixes: 94bc02e30fb8 ("nullb: use ida to manage index") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/YtEhXsr6vJeoiYhd@kili Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/null_blk/main.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 6b67088f4ea7..c0a0474be574 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -2043,8 +2043,13 @@ static int null_add_dev(struct nullb_device *dev) blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, nullb->q);
mutex_lock(&lock); - nullb->index = ida_simple_get(&nullb_indexes, 0, 0, GFP_KERNEL); - dev->index = nullb->index; + rv = ida_simple_get(&nullb_indexes, 0, 0, GFP_KERNEL); + if (rv < 0) { + mutex_unlock(&lock); + goto out_cleanup_zone; + } + nullb->index = rv; + dev->index = rv; mutex_unlock(&lock);
blk_queue_logical_block_size(nullb->q, dev->blocksize); @@ -2070,7 +2075,7 @@ static int null_add_dev(struct nullb_device *dev)
rv = null_gendisk_register(nullb); if (rv) - goto out_cleanup_zone; + goto out_ida_free;
mutex_lock(&lock); list_add_tail(&nullb->list, &nullb_list); @@ -2079,6 +2084,9 @@ static int null_add_dev(struct nullb_device *dev) pr_info("disk %s created\n", nullb->disk_name);
return 0; + +out_ida_free: + ida_free(&nullb_indexes, nullb->index); out_cleanup_zone: null_free_zoned_dev(dev); out_cleanup_disk:
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit bc9da6dd0630efd81b5c72ff6fa0169aa029a73f ]
commit 1243172d5894 ("nbd: use pr_err to output error message") tries to define pr_fmt and use short pr_err() to output error message, however, the definition is missed.
This patch also remove existing "nbd:" inside pr_err().
Fixes: 1243172d5894 ("nbd: use pr_err to output error message") Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Josef Bacik josef@toxicpanda.com Link: https://lore.kernel.org/r/20220723082427.3890655-1-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/nbd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 07f3c139a3d7..20e9c53eec53 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -11,6 +11,8 @@ * (part of code stolen from loop.c) */
+#define pr_fmt(fmt) "nbd: " fmt + #include <linux/major.h>
#include <linux/blkdev.h> @@ -1951,7 +1953,7 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) test_bit(NBD_DISCONNECT_REQUESTED, &nbd->flags)) || !refcount_inc_not_zero(&nbd->refs)) { mutex_unlock(&nbd_index_mutex); - pr_err("nbd: device at index %d is going down\n", + pr_err("device at index %d is going down\n", index); return -EINVAL; } @@ -1962,7 +1964,7 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) if (!nbd) { nbd = nbd_dev_add(index, 2); if (IS_ERR(nbd)) { - pr_err("nbd: failed to add new device\n"); + pr_err("failed to add new device\n"); return PTR_ERR(nbd); } }
From: Christoph Hellwig hch@lst.de
[ Upstream commit e8b58ef09e84c15cf782b01cfc73cc5b1180d519 ]
Use the proper helper to mark a surpise removal, remove the gendisk as soon as possible when removing the device and implement the ->free_disk callback to ensure the private data is alive as long as the gendisk has references.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Hannes Reinecke hare@suse.de Link: https://lore.kernel.org/r/20220619060552.1850436-3-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/mtip32xx/mtip32xx.c | 157 +++++++++--------------------- drivers/block/mtip32xx/mtip32xx.h | 1 - 2 files changed, 44 insertions(+), 114 deletions(-)
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 27386a572ba4..6699e4b2f7f4 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -146,11 +146,8 @@ static bool mtip_check_surprise_removal(struct driver_data *dd) pci_read_config_word(dd->pdev, 0x00, &vendor_id); if (vendor_id == 0xFFFF) { dd->sr = true; - if (dd->queue) - blk_queue_flag_set(QUEUE_FLAG_DEAD, dd->queue); - else - dev_warn(&dd->pdev->dev, - "%s: dd->queue is NULL\n", __func__); + if (dd->disk) + blk_mark_disk_dead(dd->disk); return true; /* device removed */ }
@@ -3297,26 +3294,12 @@ static int mtip_block_getgeo(struct block_device *dev, return 0; }
-static int mtip_block_open(struct block_device *dev, fmode_t mode) +static void mtip_block_free_disk(struct gendisk *disk) { - struct driver_data *dd; - - if (dev && dev->bd_disk) { - dd = (struct driver_data *) dev->bd_disk->private_data; - - if (dd) { - if (test_bit(MTIP_DDF_REMOVAL_BIT, - &dd->dd_flag)) { - return -ENODEV; - } - return 0; - } - } - return -ENODEV; -} + struct driver_data *dd = disk->private_data;
-static void mtip_block_release(struct gendisk *disk, fmode_t mode) -{ + ida_free(&rssd_index_ida, dd->index); + kfree(dd); }
/* @@ -3326,13 +3309,12 @@ static void mtip_block_release(struct gendisk *disk, fmode_t mode) * layer. */ static const struct block_device_operations mtip_block_ops = { - .open = mtip_block_open, - .release = mtip_block_release, .ioctl = mtip_block_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = mtip_block_compat_ioctl, #endif .getgeo = mtip_block_getgeo, + .free_disk = mtip_block_free_disk, .owner = THIS_MODULE };
@@ -3673,72 +3655,6 @@ static int mtip_block_initialize(struct driver_data *dd) return rv; }
-static bool mtip_no_dev_cleanup(struct request *rq, void *data, bool reserv) -{ - struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); - - cmd->status = BLK_STS_IOERR; - blk_mq_complete_request(rq); - return true; -} - -/* - * Block layer deinitialization function. - * - * Called by the PCI layer as each P320 device is removed. - * - * @dd Pointer to the driver data structure. - * - * return value - * 0 - */ -static int mtip_block_remove(struct driver_data *dd) -{ - mtip_hw_debugfs_exit(dd); - - if (dd->mtip_svc_handler) { - set_bit(MTIP_PF_SVC_THD_STOP_BIT, &dd->port->flags); - wake_up_interruptible(&dd->port->svc_wait); - kthread_stop(dd->mtip_svc_handler); - } - - if (!dd->sr) { - /* - * Explicitly wait here for IOs to quiesce, - * as mtip_standby_drive usually won't wait for IOs. - */ - if (!mtip_quiesce_io(dd->port, MTIP_QUIESCE_IO_TIMEOUT_MS)) - mtip_standby_drive(dd); - } - else - dev_info(&dd->pdev->dev, "device %s surprise removal\n", - dd->disk->disk_name); - - blk_freeze_queue_start(dd->queue); - blk_mq_quiesce_queue(dd->queue); - blk_mq_tagset_busy_iter(&dd->tags, mtip_no_dev_cleanup, dd); - blk_mq_unquiesce_queue(dd->queue); - - if (dd->disk) { - if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) - del_gendisk(dd->disk); - if (dd->disk->queue) { - blk_cleanup_queue(dd->queue); - blk_mq_free_tag_set(&dd->tags); - dd->queue = NULL; - } - put_disk(dd->disk); - } - dd->disk = NULL; - - ida_free(&rssd_index_ida, dd->index); - - /* De-initialize the protocol layer. */ - mtip_hw_exit(dd); - - return 0; -} - /* * Function called by the PCI layer when just before the * machine shuts down. @@ -3755,23 +3671,15 @@ static int mtip_block_shutdown(struct driver_data *dd) { mtip_hw_shutdown(dd);
- /* Delete our gendisk structure, and cleanup the blk queue. */ - if (dd->disk) { - dev_info(&dd->pdev->dev, - "Shutting down %s ...\n", dd->disk->disk_name); + dev_info(&dd->pdev->dev, + "Shutting down %s ...\n", dd->disk->disk_name);
- if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) - del_gendisk(dd->disk); - if (dd->disk->queue) { - blk_cleanup_queue(dd->queue); - blk_mq_free_tag_set(&dd->tags); - } - put_disk(dd->disk); - dd->disk = NULL; - dd->queue = NULL; - } + if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) + del_gendisk(dd->disk);
- ida_free(&rssd_index_ida, dd->index); + blk_cleanup_queue(dd->queue); + blk_mq_free_tag_set(&dd->tags); + put_disk(dd->disk); return 0; }
@@ -4087,8 +3995,6 @@ static void mtip_pci_remove(struct pci_dev *pdev) struct driver_data *dd = pci_get_drvdata(pdev); unsigned long flags, to;
- set_bit(MTIP_DDF_REMOVAL_BIT, &dd->dd_flag); - spin_lock_irqsave(&dev_lock, flags); list_del_init(&dd->online_list); list_add(&dd->remove_list, &removing_list); @@ -4109,11 +4015,36 @@ static void mtip_pci_remove(struct pci_dev *pdev) "Completion workers still active!\n"); }
- blk_mark_disk_dead(dd->disk); set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
- /* Clean up the block layer. */ - mtip_block_remove(dd); + if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) + del_gendisk(dd->disk); + + mtip_hw_debugfs_exit(dd); + + if (dd->mtip_svc_handler) { + set_bit(MTIP_PF_SVC_THD_STOP_BIT, &dd->port->flags); + wake_up_interruptible(&dd->port->svc_wait); + kthread_stop(dd->mtip_svc_handler); + } + + if (!dd->sr) { + /* + * Explicitly wait here for IOs to quiesce, + * as mtip_standby_drive usually won't wait for IOs. + */ + if (!mtip_quiesce_io(dd->port, MTIP_QUIESCE_IO_TIMEOUT_MS)) + mtip_standby_drive(dd); + } + else + dev_info(&dd->pdev->dev, "device %s surprise removal\n", + dd->disk->disk_name); + + blk_cleanup_queue(dd->queue); + blk_mq_free_tag_set(&dd->tags); + + /* De-initialize the protocol layer. */ + mtip_hw_exit(dd);
if (dd->isr_workq) { destroy_workqueue(dd->isr_workq); @@ -4128,10 +4059,10 @@ static void mtip_pci_remove(struct pci_dev *pdev) list_del_init(&dd->remove_list); spin_unlock_irqrestore(&dev_lock, flags);
- kfree(dd); - pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); pci_set_drvdata(pdev, NULL); + + put_disk(dd->disk); }
/* diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 6816beb45352..9c1e45b745dc 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -149,7 +149,6 @@ enum { MTIP_DDF_RESUME_BIT = 6, MTIP_DDF_INIT_DONE_BIT = 7, MTIP_DDF_REBUILD_FAILED_BIT = 8, - MTIP_DDF_REMOVAL_BIT = 9,
MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | (1 << MTIP_DDF_SEC_LOCK_BIT) |
From: Bean Huo beanhuo@micron.com
[ Upstream commit 679c54f2de672b7d79d02f8c4ad483ff6dd8ce2e ]
Use command_id instead of req->tag in trace_nvme_complete_rq(), because of commit e7006de6c238 ("nvme: code command_id with a genctr for use authentication after release"), cmd->common.command_id is set to ((genctl & 0xf)< 12 | req->tag), no longer req->tag, which makes cid in trace_nvme_complete_rq and trace_nvme_setup_cmd are not the same.
Fixes: e7006de6c238 ("nvme: code command_id with a genctr for use authentication after release") Signed-off-by: Bean Huo beanhuo@micron.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/trace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/host/trace.h b/drivers/nvme/host/trace.h index 37c7f4c89f92..6f0eaf6a1528 100644 --- a/drivers/nvme/host/trace.h +++ b/drivers/nvme/host/trace.h @@ -98,7 +98,7 @@ TRACE_EVENT(nvme_complete_rq, TP_fast_assign( __entry->ctrl_id = nvme_req(req)->ctrl->instance; __entry->qid = nvme_req_qid(req); - __entry->cid = req->tag; + __entry->cid = nvme_req(req)->cmd->common.command_id; __entry->result = le64_to_cpu(nvme_req(req)->result.u64); __entry->retries = nvme_req(req)->retries; __entry->flags = nvme_req(req)->flags;
From: Nick Bowler nbowler@draconx.ca
[ Upstream commit a25d4261582cf00dad884c194d21084836663d3d ]
Commit 89b3d6e60550 ("nvme: simplify the compat ioctl handling") removed the initialization of compat_ioctl from the nvme block_device_operations structures.
Presumably the expectation was that 32-bit ioctls would be directed through the regular handler but this is not the case: failing to assign .compat_ioctl actually means that the compat case is disabled entirely, and any attempt to submit nvme ioctls from 32-bit userspace fails outright with -ENOTTY.
For example:
% smartctl -x /dev/nvme0n1 [...] Read NVMe Identify Controller failed: NVME_IOCTL_ADMIN_CMD: Inappropriate ioctl for device
The blkdev_compat_ptr_ioctl helper can be used to direct compat calls through the main ioctl handler and makes things work again.
Fixes: 89b3d6e60550 ("nvme: simplify the compat ioctl handling") Signed-off-by: Nick Bowler nbowler@draconx.ca Reviewed-by: Guixin Liu kanie@linux.alibaba.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 1 + drivers/nvme/host/multipath.c | 1 + 2 files changed, 2 insertions(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 6a12a906a11e..9c75d7378d31 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2123,6 +2123,7 @@ static int nvme_report_zones(struct gendisk *disk, sector_t sector, static const struct block_device_operations nvme_bdev_ops = { .owner = THIS_MODULE, .ioctl = nvme_ioctl, + .compat_ioctl = blkdev_compat_ptr_ioctl, .open = nvme_open, .release = nvme_release, .getgeo = nvme_getgeo, diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index d3e2440d8abb..432ea9793a84 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -408,6 +408,7 @@ const struct block_device_operations nvme_ns_head_ops = { .open = nvme_ns_head_open, .release = nvme_ns_head_release, .ioctl = nvme_ns_head_ioctl, + .compat_ioctl = blkdev_compat_ptr_ioctl, .getgeo = nvme_getgeo, .report_zones = nvme_ns_head_report_zones, .pr_ops = &nvme_pr_ops,
From: Christoph Hellwig hch@lst.de
[ Upstream commit e06b425bc835ead08b9fd935bf5e47eef473e7a0 ]
nvme_revalidate_zones can also return -ENODEV if e.g. zone sizes aren't constant or not a power of two. In that case we should jump to marking the gendisk hidden and only support pass through.
Fixes: 602e57c9799c ("nvme: also mark passthrough-only namespaces ready in nvme_update_ns_info") Reported-by: Joel Granados j.granados@samsung.com Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Joel Granados j.granados@samsung.com Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 9c75d7378d31..2f965356f345 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1927,8 +1927,10 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
if (ns->head->ids.csi == NVME_CSI_ZNS) { ret = nvme_update_zone_info(ns, lbaf); - if (ret) - goto out_unfreeze; + if (ret) { + blk_mq_unfreeze_queue(ns->disk->queue); + goto out; + } }
set_disk_ro(ns->disk, (id->nsattr & NVME_NS_ATTR_RO) || @@ -1939,7 +1941,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id) if (blk_queue_is_zoned(ns->queue)) { ret = nvme_revalidate_zones(ns); if (ret && !nvme_first_scan(ns->disk)) - return ret; + goto out; }
if (nvme_ns_head_multipath(ns->head)) { @@ -1954,9 +1956,9 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id) disk_update_readahead(ns->head->disk); blk_mq_unfreeze_queue(ns->head->disk->queue); } - return 0;
-out_unfreeze: + ret = 0; +out: /* * If probing fails due an unsupported feature, hide the block device, * but still allow other access. @@ -1966,7 +1968,6 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id) set_bit(NVME_NS_READY, &ns->flags); ret = 0; } - blk_mq_unfreeze_queue(ns->disk->queue); return ret; }
From: Keith Busch kbusch@kernel.org
[ Upstream commit c58c0074c54c2e2bb3bb0d5a4d8896bb660cc8bc ]
The getting pages setup for zone append and normal IO are identical. Use common code for each.
Signed-off-by: Keith Busch kbusch@kernel.org Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220610195830.3574005-3-kbusch@fb.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bio.c | 102 ++++++++++++++++++++++------------------------------ 1 file changed, 42 insertions(+), 60 deletions(-)
diff --git a/block/bio.c b/block/bio.c index d9ff51fc457e..ee5fe1bb015e 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1159,6 +1159,37 @@ static void bio_put_pages(struct page **pages, size_t size, size_t off) put_page(pages[i]); }
+static int bio_iov_add_page(struct bio *bio, struct page *page, + unsigned int len, unsigned int offset) +{ + bool same_page = false; + + if (!__bio_try_merge_page(bio, page, len, offset, &same_page)) { + if (WARN_ON_ONCE(bio_full(bio, len))) + return -EINVAL; + __bio_add_page(bio, page, len, offset); + return 0; + } + + if (same_page) + put_page(page); + return 0; +} + +static int bio_iov_add_zone_append_page(struct bio *bio, struct page *page, + unsigned int len, unsigned int offset) +{ + struct request_queue *q = bdev_get_queue(bio->bi_bdev); + bool same_page = false; + + if (bio_add_hw_page(q, bio, page, len, offset, + queue_max_zone_append_sectors(q), &same_page) != len) + return -EINVAL; + if (same_page) + put_page(page); + return 0; +} + #define PAGE_PTRS_PER_BVEC (sizeof(struct bio_vec) / sizeof(struct page *))
/** @@ -1177,7 +1208,6 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) unsigned short entries_left = bio->bi_max_vecs - bio->bi_vcnt; struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt; struct page **pages = (struct page **)bv; - bool same_page = false; ssize_t size, left; unsigned len, i; size_t offset; @@ -1186,7 +1216,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) * Move page array up in the allocated memory for the bio vecs as far as * possible so that we can start filling biovecs from the beginning * without overwriting the temporary page array. - */ + */ BUILD_BUG_ON(PAGE_PTRS_PER_BVEC < 2); pages += entries_left * (PAGE_PTRS_PER_BVEC - 1);
@@ -1196,18 +1226,18 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
for (left = size, i = 0; left > 0; left -= len, i++) { struct page *page = pages[i]; + int ret;
len = min_t(size_t, PAGE_SIZE - offset, left); + if (bio_op(bio) == REQ_OP_ZONE_APPEND) + ret = bio_iov_add_zone_append_page(bio, page, len, + offset); + else + ret = bio_iov_add_page(bio, page, len, offset);
- if (__bio_try_merge_page(bio, page, len, offset, &same_page)) { - if (same_page) - put_page(page); - } else { - if (WARN_ON_ONCE(bio_full(bio, len))) { - bio_put_pages(pages + i, left, offset); - return -EINVAL; - } - __bio_add_page(bio, page, len, offset); + if (ret) { + bio_put_pages(pages + i, left, offset); + return ret; } offset = 0; } @@ -1216,51 +1246,6 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) return 0; }
-static int __bio_iov_append_get_pages(struct bio *bio, struct iov_iter *iter) -{ - unsigned short nr_pages = bio->bi_max_vecs - bio->bi_vcnt; - unsigned short entries_left = bio->bi_max_vecs - bio->bi_vcnt; - struct request_queue *q = bdev_get_queue(bio->bi_bdev); - unsigned int max_append_sectors = queue_max_zone_append_sectors(q); - struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt; - struct page **pages = (struct page **)bv; - ssize_t size, left; - unsigned len, i; - size_t offset; - int ret = 0; - - /* - * Move page array up in the allocated memory for the bio vecs as far as - * possible so that we can start filling biovecs from the beginning - * without overwriting the temporary page array. - */ - BUILD_BUG_ON(PAGE_PTRS_PER_BVEC < 2); - pages += entries_left * (PAGE_PTRS_PER_BVEC - 1); - - size = iov_iter_get_pages(iter, pages, LONG_MAX, nr_pages, &offset); - if (unlikely(size <= 0)) - return size ? size : -EFAULT; - - for (left = size, i = 0; left > 0; left -= len, i++) { - struct page *page = pages[i]; - bool same_page = false; - - len = min_t(size_t, PAGE_SIZE - offset, left); - if (bio_add_hw_page(q, bio, page, len, offset, - max_append_sectors, &same_page) != len) { - bio_put_pages(pages + i, left, offset); - ret = -EINVAL; - break; - } - if (same_page) - put_page(page); - offset = 0; - } - - iov_iter_advance(iter, size - left); - return ret; -} - /** * bio_iov_iter_get_pages - add user or kernel pages to a bio * @bio: bio to add pages to @@ -1295,10 +1280,7 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) }
do { - if (bio_op(bio) == REQ_OP_ZONE_APPEND) - ret = __bio_iov_append_get_pages(bio, iter); - else - ret = __bio_iov_iter_get_pages(bio, iter); + ret = __bio_iov_iter_get_pages(bio, iter); } while (!ret && iov_iter_count(iter) && !bio_full(bio, 0));
/* don't account direct I/O as memory stall */
From: Keith Busch kbusch@kernel.org
[ Upstream commit 325347d965e7ccf5424a05398807a6d801846612 ]
There are cases where a bio may not accept additional pages, and the iov needs to advance to the last data length that was accepted. The zone append used to handle this correctly, but was inadvertently broken when the setup was made common with the normal r/w case.
Fixes: 576ed9135489c ("block: use bio_add_page in bio_iov_iter_get_pages") Fixes: c58c0074c54c2 ("block/bio: remove duplicate append pages code") Signed-off-by: Keith Busch kbusch@kernel.org Link: https://lore.kernel.org/r/20220712153256.2202024-1-kbusch@fb.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/block/bio.c b/block/bio.c index ee5fe1bb015e..eb7cc591ee93 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1211,6 +1211,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) ssize_t size, left; unsigned len, i; size_t offset; + int ret = 0;
/* * Move page array up in the allocated memory for the bio vecs as far as @@ -1226,7 +1227,6 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
for (left = size, i = 0; left > 0; left -= len, i++) { struct page *page = pages[i]; - int ret;
len = min_t(size_t, PAGE_SIZE - offset, left); if (bio_op(bio) == REQ_OP_ZONE_APPEND) @@ -1237,13 +1237,13 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
if (ret) { bio_put_pages(pages + i, left, offset); - return ret; + break; } offset = 0; }
- iov_iter_advance(iter, size); - return 0; + iov_iter_advance(iter, size - left); + return ret; }
/**
From: Zhang Yi yi.zhang@huawei.com
[ Upstream commit a89573ce4ad32f19f43ec669771726817e185be0 ]
We catch an assert problem in jbd2_journal_commit_transaction() when doing fsstress and request falut injection tests. The problem is happened in a race condition between jbd2_journal_commit_transaction() and ext4_end_io_end(). Firstly, ext4_writepages() writeback dirty pages and start reserved handle, and then the journal was aborted due to some previous metadata IO error, jbd2_journal_abort() start to commit current running transaction, the committing procedure could be raced by ext4_end_io_end() and lead to subtract j_reserved_credits twice from commit_transaction->t_outstanding_credits, finally the t_outstanding_credits is mistakenly smaller than t_nr_buffers and trigger assert.
kjournald2 kworker
jbd2_journal_commit_transaction() write_unlock(&journal->j_state_lock); atomic_sub(j_reserved_credits, t_outstanding_credits); //sub once
jbd2_journal_start_reserved() start_this_handle() //detect aborted journal jbd2_journal_free_reserved() //get running transaction read_lock(&journal->j_state_lock) __jbd2_journal_unreserve_handle() atomic_sub(j_reserved_credits, t_outstanding_credits); //sub again read_unlock(&journal->j_state_lock);
journal->j_running_transaction = NULL; J_ASSERT(t_nr_buffers <= t_outstanding_credits) //bomb!!!
Fix this issue by using journal->j_state_lock to protect the subtraction in jbd2_journal_commit_transaction().
Fixes: 96f1e0974575 ("jbd2: avoid long hold times of j_state_lock while committing a transaction") Signed-off-by: Zhang Yi yi.zhang@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220611130426.2013258-1-yi.zhang@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org --- fs/jbd2/commit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index eb315e81f1a6..af1a9191368c 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -553,13 +553,13 @@ void jbd2_journal_commit_transaction(journal_t *journal) */ jbd2_journal_switch_revoke_table(journal);
+ write_lock(&journal->j_state_lock); /* * Reserved credits cannot be claimed anymore, free them */ atomic_sub(atomic_read(&journal->j_reserved_credits), &commit_transaction->t_outstanding_credits);
- write_lock(&journal->j_state_lock); trace_jbd2_commit_flushing(journal, commit_transaction); stats.run.rs_flushing = jiffies; stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked,
From: Li Lingfeng lilingfeng3@huawei.com
[ Upstream commit 07ea7a617d6b278fb7acedb5cbe1a81ce2de7d0c ]
When migrating to extents, the checksum seed of temporary inode need to be replaced by inode's, otherwise the inode checksums will be incorrect when swapping the inodes data.
However, the temporary inode can not match it's checksum to itself since it has lost it's own checksum seed.
mkfs.ext4 -F /dev/sdc mount /dev/sdc /mnt/sdc xfs_io -fc "pwrite 4k 4k" -c "fsync" /mnt/sdc/testfile chattr -e /mnt/sdc/testfile chattr +e /mnt/sdc/testfile umount /dev/sdc fsck -fn /dev/sdc
======== ... Pass 1: Checking inodes, blocks, and sizes Inode 13 passes checks, but checksum does not match inode. Fix? no ... ========
The fix is simple, save the checksum seed of temporary inode, and recover it after migrating to extents.
Fixes: e81c9302a6c3 ("ext4: set csum seed in tmp inode while migrating to extents") Signed-off-by: Li Lingfeng lilingfeng3@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220617062515.2113438-1-lilingfeng3@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ext4/migrate.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 42f590518b4c..54e7d3c95fd7 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -417,7 +417,7 @@ int ext4_ext_migrate(struct inode *inode) struct inode *tmp_inode = NULL; struct migrate_struct lb; unsigned long max_entries; - __u32 goal; + __u32 goal, tmp_csum_seed; uid_t owner[2];
/* @@ -465,6 +465,7 @@ int ext4_ext_migrate(struct inode *inode) * the migration. */ ei = EXT4_I(inode); + tmp_csum_seed = EXT4_I(tmp_inode)->i_csum_seed; EXT4_I(tmp_inode)->i_csum_seed = ei->i_csum_seed; i_size_write(tmp_inode, i_size_read(inode)); /* @@ -575,6 +576,7 @@ int ext4_ext_migrate(struct inode *inode) * the inode is not visible to user space. */ tmp_inode->i_blocks = 0; + EXT4_I(tmp_inode)->i_csum_seed = tmp_csum_seed;
/* Reset the extent details */ ext4_ext_tree_init(handle, tmp_inode);
From: Zhihao Cheng chengzhihao1@huawei.com
[ Upstream commit 4a734f0869f970b8a9b65062ea40b09a5da9dba8 ]
Following process will fail assertion 'jh->b_frozen_data == NULL' in jbd2_journal_dirty_metadata():
jbd2_journal_commit_transaction unlink(dir/a) jh->b_transaction = trans1 jh->b_jlist = BJ_Metadata journal->j_running_transaction = NULL trans1->t_state = T_COMMIT unlink(dir/b) handle->h_trans = trans2 do_get_write_access jh->b_modified = 0 jh->b_frozen_data = frozen_buffer jh->b_next_transaction = trans2 jbd2_journal_dirty_metadata is_handle_aborted is_journal_aborted // return false
--> jbd2 abort <--
while (commit_transaction->t_buffers) if (is_journal_aborted) jbd2_journal_refile_buffer __jbd2_journal_refile_buffer WRITE_ONCE(jh->b_transaction, jh->b_next_transaction) WRITE_ONCE(jh->b_next_transaction, NULL) __jbd2_journal_file_buffer(jh, BJ_Reserved) J_ASSERT_JH(jh, jh->b_frozen_data == NULL) // assertion failure !
The reproducer (See detail in [Link]) reports: ------------[ cut here ]------------ kernel BUG at fs/jbd2/transaction.c:1629! invalid opcode: 0000 [#1] PREEMPT SMP CPU: 2 PID: 584 Comm: unlink Tainted: G W 5.19.0-rc6-00115-g4a57a8400075-dirty #697 RIP: 0010:jbd2_journal_dirty_metadata+0x3c5/0x470 RSP: 0018:ffffc90000be7ce0 EFLAGS: 00010202 Call Trace: <TASK> __ext4_handle_dirty_metadata+0xa0/0x290 ext4_handle_dirty_dirblock+0x10c/0x1d0 ext4_delete_entry+0x104/0x200 __ext4_unlink+0x22b/0x360 ext4_unlink+0x275/0x390 vfs_unlink+0x20b/0x4c0 do_unlinkat+0x42f/0x4c0 __x64_sys_unlink+0x37/0x50 do_syscall_64+0x35/0x80
After journal aborting, __jbd2_journal_refile_buffer() is executed with holding @jh->b_state_lock, we can fix it by moving 'is_handle_aborted()' into the area protected by @jh->b_state_lock.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216251 Fixes: 470decc613ab20 ("[PATCH] jbd2: initial copy of files from jbd") Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com Link: https://lore.kernel.org/r/20220715125152.4022726-1-chengzhihao1@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org --- fs/jbd2/transaction.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index e9c308ae475f..e0377f558eb1 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -1486,8 +1486,6 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) struct journal_head *jh; int ret = 0;
- if (is_handle_aborted(handle)) - return -EROFS; if (!buffer_jbd(bh)) return -EUCLEAN;
@@ -1534,6 +1532,18 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) journal = transaction->t_journal; spin_lock(&jh->b_state_lock);
+ if (is_handle_aborted(handle)) { + /* + * Check journal aborting with @jh->b_state_lock locked, + * since 'jh->b_transaction' could be replaced with + * 'jh->b_next_transaction' during old transaction + * committing if journal aborted, which may fail + * assertion on 'jh->b_frozen_data == NULL'. + */ + ret = -EROFS; + goto out_unlock_bh; + } + if (jh->b_modified == 0) { /* * This buffer's got modified and becoming part
From: Nathan Chancellor nathan@kernel.org
[ Upstream commit 78acd4ca433425e6dd4032cfc2156c60e34931f2 ]
Clang warns:
drivers/usb/cdns3/cdns3-gadget.c:2290:11: error: variable 'priv_dev' is uninitialized when used here [-Werror,-Wuninitialized] dev_dbg(priv_dev->dev, "usbss: invalid parameters\n"); ^~~~~~~~ include/linux/dev_printk.h:155:18: note: expanded from macro 'dev_dbg' dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__) ^~~ include/linux/dynamic_debug.h:167:7: note: expanded from macro 'dynamic_dev_dbg' dev, fmt, ##__VA_ARGS__) ^~~ include/linux/dynamic_debug.h:152:56: note: expanded from macro '_dynamic_func_call' __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__) ^~~~~~~~~~~ include/linux/dynamic_debug.h:134:15: note: expanded from macro '__dynamic_func_call' func(&id, ##__VA_ARGS__); \ ^~~~~~~~~~~ drivers/usb/cdns3/cdns3-gadget.c:2278:31: note: initialize the variable 'priv_dev' to silence this warning struct cdns3_device *priv_dev; ^ = NULL 1 error generated.
The priv_dev assignment was moved below the if statement to avoid potentially dereferencing ep before it was checked but priv_dev is used in the dev_dbg() call.
To fix this, move the priv_dev and comp_desc assignments back to their original spot and hoist the ep check above those assignments with a call to pr_debug() instead of dev_dbg().
Fixes: c3ffc9c4ca44 ("usb: cdns3: change place of 'priv_ep' assignment in cdns3_gadget_ep_dequeue(), cdns3_gadget_ep_enable()") Link: https://github.com/ClangBuiltLinux/linux/issues/1680 Signed-off-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/cdns3/cdns3-gadget.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c index 1f38ccd637d0..87cfa91a758d 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -2284,16 +2284,20 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep, int ret = 0; int val;
+ if (!ep) { + pr_debug("usbss: ep not configured?\n"); + return -EINVAL; + } + priv_ep = ep_to_cdns3_ep(ep); + priv_dev = priv_ep->cdns3_dev; + comp_desc = priv_ep->endpoint.comp_desc;
- if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) { + if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) { dev_dbg(priv_dev->dev, "usbss: invalid parameters\n"); return -EINVAL; }
- comp_desc = priv_ep->endpoint.comp_desc; - priv_dev = priv_ep->cdns3_dev; - if (!desc->wMaxPacketSize) { dev_err(priv_dev->dev, "usbss: missing wMaxPacketSize\n"); return -EINVAL;
From: Tang Bin tangbin@cmss.chinamobile.com
[ Upstream commit 4ea9496cbc959eb5c78f3e379199aca9ef4e386b ]
dev_pm_domain_attach_by_name() may return NULL in some cases, so IS_ERR() doesn't meet the requirements. Thus fix it.
Fixes: 6319aee10e53 ("opp: Attach genpds to devices from within OPP core") Signed-off-by: Tang Bin tangbin@cmss.chinamobile.com [ Viresh: Replace ENODATA with ENODEV ] Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/opp/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 84063eaebb91..ff0364733dcb 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -2528,8 +2528,8 @@ struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, }
virt_dev = dev_pm_domain_attach_by_name(dev, *name); - if (IS_ERR(virt_dev)) { - ret = PTR_ERR(virt_dev); + if (IS_ERR_OR_NULL(virt_dev)) { + ret = PTR_ERR(virt_dev) ? : -ENODEV; dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret); goto err; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 0a034d93ee929a9ea89f3fa5f1d8492435b9ee6e ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: b6bc07d4360d ("ASoC: cros_ec_codec: support WoV") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Tzung-Bi Shih tzungbi@kernel.org Reviewed-by: Guenter Roeck groeck@chromium.org Link: https://lore.kernel.org/r/20220603131043.38907-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/cros_ec_codec.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index 8b0a9c788a26..11e7b3f6d410 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -995,6 +995,7 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev) dev_dbg(dev, "ap_shm_phys_addr=%#llx len=%#x\n", priv->ap_shm_phys_addr, priv->ap_shm_len); } + of_node_put(node); } #endif
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 3e2649c5e8643bea0867bb1dd970fedadb0eb7f3 ]
of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. This function is missing of_node_put(cpu) in the error path. Fix this by goto out label. of_node_put() will check NULL pointer.
Fixes: 7a3a7671fa6c ("ASoC: samsung: Add driver for Aries boards") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220603130640.37624-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/samsung/aries_wm8994.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sound/soc/samsung/aries_wm8994.c b/sound/soc/samsung/aries_wm8994.c index bb0cf4244e00..edee02d7f100 100644 --- a/sound/soc/samsung/aries_wm8994.c +++ b/sound/soc/samsung/aries_wm8994.c @@ -628,8 +628,10 @@ static int aries_audio_probe(struct platform_device *pdev) return -EINVAL;
codec = of_get_child_by_name(dev->of_node, "codec"); - if (!codec) - return -EINVAL; + if (!codec) { + ret = -EINVAL; + goto out; + }
for_each_card_prelinks(card, i, dai_link) { dai_link->codecs->of_node = of_parse_phandle(codec,
From: Fabio Estevam festevam@gmail.com
[ Upstream commit 2f4a8171da06609bb6a063630ed546ee3d93dad7 ]
Change the of_device_get_match_data() cast to (uintptr_t) to silence the following clang warning:
sound/soc/fsl/imx-audmux.c:301:16: warning: cast to smaller integer type 'enum imx_audmux_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
Reported-by: kernel test robot lkp@intel.com Fixes: 6a8b8b582db1 ("ASoC: imx-audmux: Remove unused .id_table") Signed-off-by: Fabio Estevam festevam@gmail.com Link: https://lore.kernel.org/r/20220526010543.1164793-1-festevam@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/imx-audmux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index dfa05d40b276..a8e5e0f57faf 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c @@ -298,7 +298,7 @@ static int imx_audmux_probe(struct platform_device *pdev) audmux_clk = NULL; }
- audmux_type = (enum imx_audmux_type)of_device_get_match_data(&pdev->dev); + audmux_type = (uintptr_t)of_device_get_match_data(&pdev->dev);
switch (audmux_type) { case IMX31_AUDMUX:
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit ae4f11c1ed2d67192fdf3d89db719ee439827c11 ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Fix missing of_node_put() in error paths.
Fixes: 94319ba10eca ("ASoC: mediatek: Use platform_of_node for machine drivers") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220602034144.60159-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c index 70bf312e855f..8794720cea3a 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c @@ -256,14 +256,16 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_node; } mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node = of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1); if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_node; } mt8173_rt5650_rt5676_codec_conf[0].dlc.of_node = mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node; @@ -276,13 +278,15 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) if (!mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codecs->of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_node; }
card->dev = &pdev->dev;
ret = devm_snd_soc_register_card(&pdev->dev, card);
+put_node: of_node_put(platform_node); return ret; }
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit aa7407f807b250eca7697e5fe9a699bc6c2fab71 ]
Change the header file to fix build errors in max98390.c:
../sound/soc/codecs/max98390.c: In function 'max98390_i2c_probe': ../sound/soc/codecs/max98390.c:1076:22: error: implicit declaration of function 'devm_gpiod_get_optional'; did you mean 'devm_regulator_get_optional'? [-Werror=implicit-function-declaration] 1076 | reset_gpio = devm_gpiod_get_optional(&i2c->dev, ../sound/soc/codecs/max98390.c:1077:55: error: 'GPIOD_OUT_HIGH' undeclared (first use in this function); did you mean 'GPIOF_INIT_HIGH'? 1077 | "reset", GPIOD_OUT_HIGH); ../sound/soc/codecs/max98390.c:1077:55: note: each undeclared identifier is reported only once for each function it appears in ../sound/soc/codecs/max98390.c:1083:17: error: implicit declaration of function 'gpiod_set_value_cansleep'; did you mean 'gpio_set_value_cansleep'? [-Werror=implicit-function-declaration] 1083 | gpiod_set_value_cansleep(reset_gpio, 0);
Fixes: 397ff0249606 ("ASoC: max98390: Add reset gpio control") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Cc: Steve Lee steve.lee.analog@gmail.com Cc: Mark Brown broonie@kernel.org Cc: Liam Girdwood lgirdwood@gmail.com Cc: Jaroslav Kysela perex@perex.cz Cc: Takashi Iwai tiwai@suse.com Cc: alsa-devel@alsa-project.org Link: https://lore.kernel.org/r/20220605163123.23537-1-rdunlap@infradead.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/max98390.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c index 2a6b1648c884..d83f81d9ff4e 100644 --- a/sound/soc/codecs/max98390.c +++ b/sound/soc/codecs/max98390.c @@ -10,7 +10,7 @@ #include <linux/cdev.h> #include <linux/dmi.h> #include <linux/firmware.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/module.h> #include <linux/of_gpio.h>
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 7472eb8d7dd12b6b9b1a4f4527719cc9c7f5965f ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: f0ab0bf250da ("ASoC: add mt6797-mt6351 driver and config option") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220603083417.9011-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/mediatek/mt6797/mt6797-mt6351.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/soc/mediatek/mt6797/mt6797-mt6351.c b/sound/soc/mediatek/mt6797/mt6797-mt6351.c index 496f32bcfb5e..d2f6213a6bfc 100644 --- a/sound/soc/mediatek/mt6797/mt6797-mt6351.c +++ b/sound/soc/mediatek/mt6797/mt6797-mt6351.c @@ -217,7 +217,8 @@ static int mt6797_mt6351_dev_probe(struct platform_device *pdev) if (!codec_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_platform_node; } for_each_card_prelinks(card, i, dai_link) { if (dai_link->codecs->name) @@ -230,6 +231,9 @@ static int mt6797_mt6351_dev_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", __func__, ret);
+ of_node_put(codec_node); +put_platform_node: + of_node_put(platform_node); return ret; }
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit 82fa8f581a954ddeec1602bed9f8b4a09d100e6e ]
As i2c_add_driver could return error if fails, it should be better to check the return value. However, if the CONFIG_I2C and CONFIG_SPI_MASTER are both true, the return value of i2c_add_driver will be covered by spi_register_driver. Therefore, it is necessary to add check and return error if fails.
Fixes: aa0e25caafb7 ("ASoC: da7210: Add support for spi regmap") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Link: https://lore.kernel.org/r/20220531094712.2376759-1-jiasheng@iscas.ac.cn Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/da7210.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 3fa3042e4424..76a21976ccdd 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -1335,6 +1335,8 @@ static int __init da7210_modinit(void) int ret = 0; #if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&da7210_i2c_driver); + if (ret) + return ret; #endif #if defined(CONFIG_SPI_MASTER) ret = spi_register_driver(&da7210_spi_driver);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit efe2178d1a32492f99e7f1f2568eea5c88a85729 ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Fix refcount leak in some error paths.
Fixes: 0f83f9296d5c ("ASoC: mediatek: Add machine driver for ALC5650 codec") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220603124243.31358-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/mediatek/mt8173/mt8173-rt5650.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c index d1c94acb4516..e05f2b0231fe 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c @@ -280,7 +280,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev) if (!mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_platform_node; } mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node = mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node; @@ -293,7 +294,7 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s codec_capture_dai name fail %d\n", __func__, ret); - return ret; + goto put_platform_node; } mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[1].dai_name = codec_capture_dai; @@ -315,12 +316,14 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev) if (!mt8173_rt5650_dais[DAI_LINK_HDMI_I2S].codecs->of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_platform_node; } card->dev = &pdev->dev;
ret = devm_snd_soc_register_card(&pdev->dev, card);
+put_platform_node: of_node_put(platform_node); return ret; }
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 6f3cdf2bf1ba9b70de6c2921a415951a0d59873b ]
Fix the missing clk_disable_unprepare() before return from pic32_uart_startup() in the error handling case.
Fixes: 157b9394709e ("serial: pic32_uart: Add PIC32 UART driver") Reported-by: Hulk Robot hulkci@huawei.com Reviewed-by: Jiri Slaby jirislaby@kernel.org Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20220525021204.2407631-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/pic32_uart.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c index b399aac530fe..f418f1de66b3 100644 --- a/drivers/tty/serial/pic32_uart.c +++ b/drivers/tty/serial/pic32_uart.c @@ -503,7 +503,7 @@ static int pic32_uart_startup(struct uart_port *port) if (!sport->irq_fault_name) { dev_err(port->dev, "%s: kasprintf err!", __func__); ret = -ENOMEM; - goto out_done; + goto out_disable_clk; } irq_set_status_flags(sport->irq_fault, IRQ_NOAUTOEN); ret = request_irq(sport->irq_fault, pic32_uart_fault_interrupt, @@ -579,6 +579,8 @@ static int pic32_uart_startup(struct uart_port *port) out_f: free_irq(sport->irq_fault, port); kfree(sport->irq_fault_name); +out_disable_clk: + clk_disable_unprepare(sport->clk); out_done: return ret; }
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
[ Upstream commit bdb70c424df1543bc02ee2639aecebd20318c599 ]
LSR register readers need to be careful in order to not lose bits that are not preserved across reads. Create a helper that takes care of storing the non-preserved bits into lsr_save_flags.
Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/r/20220608095431.18376-3-ilpo.jarvinen@linux.intel.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250.h | 20 ++++++++++++++++++++ drivers/tty/serial/8250/8250_core.c | 3 +-- drivers/tty/serial/8250/8250_port.c | 15 ++++----------- 3 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 696030cfcb09..c89cb881d9b0 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -123,6 +123,26 @@ static inline void serial_out(struct uart_8250_port *up, int offset, int value) up->port.serial_out(&up->port, offset, value); }
+/** + * serial_lsr_in - Read LSR register and preserve flags across reads + * @up: uart 8250 port + * + * Read LSR register and handle saving non-preserved flags across reads. + * The flags that are not preserved across reads are stored into + * up->lsr_saved_flags. + * + * Returns LSR value or'ed with the preserved flags (if any). + */ +static inline unsigned int serial_lsr_in(struct uart_8250_port *up) +{ + unsigned int lsr = up->lsr_saved_flags; + + lsr |= serial_in(up, UART_LSR); + up->lsr_saved_flags = lsr & LSR_SAVE_FLAGS; + + return lsr; +} + /* * For the 16C950 */ diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 3f56dbc9432b..82726cda6066 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -277,8 +277,7 @@ static void serial8250_backup_timeout(struct timer_list *t) * the "Diva" UART used on the management processor on many HP * ia64 and parisc boxes. */ - lsr = serial_in(up, UART_LSR); - up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + lsr = serial_lsr_in(up); if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) && (lsr & UART_LSR_THRE)) { diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 3c36a06a20b0..c9d8c0de56e5 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1514,11 +1514,9 @@ static inline void __stop_tx(struct uart_8250_port *p) struct uart_8250_em485 *em485 = p->em485;
if (em485) { - unsigned char lsr = serial_in(p, UART_LSR); + unsigned char lsr = serial_lsr_in(p); u64 stop_delay = 0;
- p->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; - if (!(lsr & UART_LSR_THRE)) return; /* @@ -1573,10 +1571,8 @@ static inline void __start_tx(struct uart_port *port)
if (serial8250_set_THRI(up)) { if (up->bugs & UART_BUG_TXEN) { - unsigned char lsr; + unsigned char lsr = serial_lsr_in(up);
- lsr = serial_in(up, UART_LSR); - up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; if (lsr & UART_LSR_THRE) serial8250_tx_chars(up); } @@ -2007,8 +2003,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) serial8250_rpm_get(up);
spin_lock_irqsave(&port->lock, flags); - lsr = serial_port_in(port, UART_LSR); - up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + lsr = serial_lsr_in(up); spin_unlock_irqrestore(&port->lock, flags);
serial8250_rpm_put(up); @@ -2084,9 +2079,7 @@ static void wait_for_lsr(struct uart_8250_port *up, int bits)
/* Wait up to 10ms for the character(s) to be sent. */ for (;;) { - status = serial_in(up, UART_LSR); - - up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; + status = serial_lsr_in(up);
if ((status & bits) == bits) break;
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
[ Upstream commit 6a4241e8f9b17aa17f55842d6478f280c22d2b44 ]
serial8250_handle_irq() assumes it's the first to read LSR register. However, there are 8250 drivers which perform LSR read in their own irq handler prior to calling serial8250_handle_irq(). As not all flags are preserved across LSR reads, use serial_lsr_in() helper to get all the preserved flags.
This commit might fix other commits too besides the ones for DW UART mentioned below. It's just not clear to me which of the other devices clear some of the LSR flags on read. AFAIK, nobody has complained about this problem (either against DW or other devices) so it might not have that bad impact in the end.
Fixes: 424d79183af0 ("serial: 8250_dw: Avoid "too much work" from bogus rx timeout interrupt") Fixes: aa63d786cea2 ("serial: 8250: dw: Add support for DMA flow controlling devices") Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/r/20220608095431.18376-4-ilpo.jarvinen@linux.intel.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index c9d8c0de56e5..2b86c55ed374 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1922,7 +1922,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
spin_lock_irqsave(&port->lock, flags);
- status = serial_port_in(port, UART_LSR); + status = serial_lsr_in(up);
/* * If port is stopped and there are no error conditions in the
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
[ Upstream commit 197eb5c416ff0e52d152e6ff59b4e759d2f3e10d ]
dw8250_handle_irq() reads LSR under a few conditions, convert both to use serial_lsr_in() in order to preserve LSR flags properly across reads.
Fixes: 424d79183af0 ("serial: 8250_dw: Avoid "too much work" from bogus rx timeout interrupt") Fixes: aa63d786cea2 ("serial: 8250: dw: Add support for DMA flow controlling devices") Cc: Douglas Anderson dianders@chromium.org Cc: Phil Edworthy phil.edworthy@renesas.com Cc: Miquel Raynal miquel.raynal@bootlin.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/r/20220608095431.18376-6-ilpo.jarvinen@linux.intel.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_dw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index bb6aca07ab56..7e05b431a314 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -253,7 +253,7 @@ static int dw8250_handle_irq(struct uart_port *p) */ if (!up->dma && rx_timeout) { spin_lock_irqsave(&p->lock, flags); - status = p->serial_in(p, UART_LSR); + status = serial_lsr_in(up);
if (!(status & (UART_LSR_DR | UART_LSR_BI))) (void) p->serial_in(p, UART_RX); @@ -263,7 +263,7 @@ static int dw8250_handle_irq(struct uart_port *p)
/* Manually stop the Rx DMA transfer when acting as flow controller */ if (quirks & DW_UART_QUIRK_IS_DMA_FC && up->dma && up->dma->rx_running && rx_timeout) { - status = p->serial_in(p, UART_LSR); + status = serial_lsr_in(up); if (status & (UART_LSR_DR | UART_LSR_BI)) { dw8250_writel_ext(p, RZN1_UART_RDMACR, 0); dw8250_writel_ext(p, DW_UART_DMASA, 1);
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
[ Upstream commit af14f3007e2dca0d112f10f6717ba43093f74e81 ]
Make sure LSR flags are preserved in dw8250_tx_wait_empty(). This function is called from a low-level out function and therefore cannot call serial_lsr_in() as it would lead to infinite recursion.
It is borderline if the flags need to be saved here at all since this code relates to writing LCR register which usually implies no important characters should be arriving.
Fixes: 914eaf935ec7 ("serial: 8250_dw: Allow TX FIFO to drain before writing to UART_LCR") Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/r/20220608095431.18376-7-ilpo.jarvinen@linux.intel.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_dw.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 7e05b431a314..c0ab67033a25 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -122,12 +122,15 @@ static void dw8250_check_lcr(struct uart_port *p, int value) /* Returns once the transmitter is empty or we run out of retries */ static void dw8250_tx_wait_empty(struct uart_port *p) { + struct uart_8250_port *up = up_to_u8250p(p); unsigned int tries = 20000; unsigned int delay_threshold = tries - 1000; unsigned int lsr;
while (tries--) { lsr = readb (p->membase + (UART_LSR << p->regshift)); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + if (lsr & UART_LSR_TEMT) break;
From: Peter Ujfalusi peter.ujfalusi@linux.intel.com
[ Upstream commit 03f69725749f453b9a4d454a92805f8eb5f095c2 ]
Commit 657774acd00f ("ASoC: SOF: Make sof_suspend/resume IPC agnostic") did not marked ctx_store and ctx_restore as Optional.
Fixes: 657774acd00f ("ASoC: SOF: Make sof_suspend/resume IPC agnostic") Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20220610083549.16773-2-peter.ujfalusi@linux.intel.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sof/sof-priv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index f0f3d72c0da7..f11f575fd1da 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -378,8 +378,8 @@ struct sof_ipc_fw_tracing_ops {
/** * struct sof_ipc_pm_ops - IPC-specific PM ops - * @ctx_save: Function pointer for context save - * @ctx_restore: Function pointer for context restore + * @ctx_save: Optional function pointer for context save + * @ctx_restore: Optional function pointer for context restore */ struct sof_ipc_pm_ops { int (*ctx_save)(struct snd_sof_dev *sdev);
From: Srinivas Kandagatla srinivas.kandagatla@linaro.org
[ Upstream commit 5babb012c847beb6c8c7108fd78f650b7a2c6054 ]
move all the digital gains form using SX_TLV to S8_TLV, these gains are actually 8 bit gains with 7th signed bit and ranges from -84dB to +40dB
rest of the Qualcomm wcd codecs uses these properly.
Fixes: ef8a4757a6db ("ASoC: msm8916-wcd-digital: Add sidetone support") Fixes: 150db8c5afa1 ("ASoC: codecs: Add msm8916-wcd digital codec") Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20220609111901.318047-2-srinivas.kandagatla@linaro... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/msm8916-wcd-digital.c | 46 +++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c index 20a07c92b2fc..098a58990f07 100644 --- a/sound/soc/codecs/msm8916-wcd-digital.c +++ b/sound/soc/codecs/msm8916-wcd-digital.c @@ -328,8 +328,8 @@ static const struct snd_kcontrol_new rx1_mix2_inp1_mux = SOC_DAPM_ENUM( static const struct snd_kcontrol_new rx2_mix2_inp1_mux = SOC_DAPM_ENUM( "RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
-/* Digital Gain control -38.4 dB to +38.4 dB in 0.3 dB steps */ -static const DECLARE_TLV_DB_SCALE(digital_gain, -3840, 30, 0); +/* Digital Gain control -84 dB to +40 dB in 1 dB steps */ +static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
/* Cutoff Freq for High Pass Filter at -3dB */ static const char * const hpf_cutoff_text[] = { @@ -510,15 +510,15 @@ static int wcd_iir_filter_info(struct snd_kcontrol *kcontrol,
static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = { SOC_SINGLE_S8_TLV("RX1 Digital Volume", LPASS_CDC_RX1_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("RX2 Digital Volume", LPASS_CDC_RX2_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("RX3 Digital Volume", LPASS_CDC_RX3_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("TX1 Digital Volume", LPASS_CDC_TX1_VOL_CTL_GAIN, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("TX2 Digital Volume", LPASS_CDC_TX2_VOL_CTL_GAIN, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_ENUM("TX1 HPF Cutoff", tx1_hpf_cutoff_enum), SOC_ENUM("TX2 HPF Cutoff", tx2_hpf_cutoff_enum), SOC_SINGLE("TX1 HPF Switch", LPASS_CDC_TX1_MUX_CTL, 3, 1, 0), @@ -553,22 +553,22 @@ static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = { WCD_IIR_FILTER_CTL("IIR2 Band3", IIR2, BAND3), WCD_IIR_FILTER_CTL("IIR2 Band4", IIR2, BAND4), WCD_IIR_FILTER_CTL("IIR2 Band5", IIR2, BAND5), - SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL, - 0, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL, + -84, 40, digital_gain),
};
From: Srinivas Kandagatla srinivas.kandagatla@linaro.org
[ Upstream commit 2fbe0953732e06b471cdedbf6f615b84235580d8 ]
move all the digital gains form using SX_TLV to S8_TLV, these gains are actually 8 bit gains with 7th signed bit and ranges from -84dB to +40dB
rest of the Qualcomm wcd codecs uses these properly.
Fixes: 8c4f021d806a ("ASoC: wcd9335: add basic controls") Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20220609111901.318047-3-srinivas.kandagatla@linaro... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/wcd9335.c | 81 +++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 45 deletions(-)
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 3cb7a3eab8c7..541ef1cd3b74 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -2264,51 +2264,42 @@ static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc,
static const struct snd_kcontrol_new wcd9335_snd_controls[] = { /* -84dB min - 40dB max */ - SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume", - WCD9335_CDC_RX0_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume", - WCD9335_CDC_RX1_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume", - WCD9335_CDC_RX2_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume", - WCD9335_CDC_RX3_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume", - WCD9335_CDC_RX4_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume", - WCD9335_CDC_RX5_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume", - WCD9335_CDC_RX6_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume", - WCD9335_CDC_RX7_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume", - WCD9335_CDC_RX8_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume", WCD9335_CDC_RX0_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume", WCD9335_CDC_RX1_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume", WCD9335_CDC_RX2_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume", WCD9335_CDC_RX3_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume", WCD9335_CDC_RX4_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX5 Mix Digital Volume", WCD9335_CDC_RX5_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX6 Mix Digital Volume", WCD9335_CDC_RX6_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume", WCD9335_CDC_RX7_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume", WCD9335_CDC_RX8_RX_VOL_MIX_CTL, + -84, 40, digital_gain), SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
From: Charles Keepax ckeepax@opensource.cirrus.com
[ Upstream commit d919630fe77904931277e663c902582ea6f4e4cf ]
The endianness flag is used on the CODEC side to specify an ambivalence to endian, typically because it is lost over the hardware link. This device receives audio over an I2S DAI and as such should have endianness applied.
Fixes: 0d463d016000 ("ASoC: cs35l45: Add driver for Cirrus Logic CS35L45 Smart Amp") Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Link: https://lore.kernel.org/r/20220614131022.778057-1-ckeepax@opensource.cirrus.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/cs35l45.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c index 2367c1a4c10e..145051390471 100644 --- a/sound/soc/codecs/cs35l45.c +++ b/sound/soc/codecs/cs35l45.c @@ -500,6 +500,8 @@ static const struct snd_soc_component_driver cs35l45_component = { .num_controls = ARRAY_SIZE(cs35l45_controls),
.name = "cs35l45", + + .endianness = 1, };
static int __maybe_unused cs35l45_runtime_suspend(struct device *dev)
From: Shengjiu Wang shengjiu.wang@nxp.com
[ Upstream commit abe13e9a561d6b3e82b21362c0d6dd3ecd8a5b13 ]
There is no mutex protection for rpmsg_eptdev_open(), especially for eptdev->ept read and write operation. It may cause issues when multiple instances call rpmsg_eptdev_open() in parallel,the return state may be success or EBUSY.
Fixes: 964e8bedd5a1 ("rpmsg: char: Return an error if device already open") Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com Link: https://lore.kernel.org/r/1653104105-16779-1-git-send-email-shengjiu.wang@nx... Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rpmsg/rpmsg_char.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c index b6183d4f62a2..4f2189111494 100644 --- a/drivers/rpmsg/rpmsg_char.c +++ b/drivers/rpmsg/rpmsg_char.c @@ -120,8 +120,11 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp) struct rpmsg_device *rpdev = eptdev->rpdev; struct device *dev = &eptdev->dev;
- if (eptdev->ept) + mutex_lock(&eptdev->ept_lock); + if (eptdev->ept) { + mutex_unlock(&eptdev->ept_lock); return -EBUSY; + }
get_device(dev);
@@ -137,11 +140,13 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp) if (!ept) { dev_err(dev, "failed to open %s\n", eptdev->chinfo.name); put_device(dev); + mutex_unlock(&eptdev->ept_lock); return -EINVAL; }
eptdev->ept = ept; filp->private_data = eptdev; + mutex_unlock(&eptdev->ept_lock);
return 0; }
From: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com
[ Upstream commit 353d9214682e65c55cdffad8c82139a3321c5f13 ]
During execution of the worker that's used to register rpmsg devices we are safely locking the channels mutex but, when creating a new endpoint for such devices, we are registering a IPI on the SCP, which then makes the SCP to trigger an interrupt, lock its own mutex and in turn register more subdevices. This creates a circular locking dependency situation, as the mtk_rpmsg channels_lock will then depend on the SCP IPI lock.
[ 15.447736] ====================================================== [ 15.460158] WARNING: possible circular locking dependency detected [ 15.460161] 5.17.0-next-20220324+ #399 Not tainted [ 15.460165] ------------------------------------------------------ [ 15.460166] kworker/0:3/155 is trying to acquire lock: [ 15.460170] ffff5b4d0eaf1308 (&scp->ipi_desc[i].lock){+.+.}-{4:4}, at: scp_ipi_lock+0x34/0x50 [mtk_scp_ipi] [ 15.504958] [] but task is already holding lock: [ 15.504960] ffff5b4d0e8f1918 (&mtk_subdev->channels_lock){+.+.}-{4:4}, at: mtk_register_device_work_function+0x50/0x1cc [mtk_rpmsg] [ 15.504978] [] which lock already depends on the new lock.
[ 15.504980] [] the existing dependency chain (in reverse order) is: [ 15.504982] [] -> #1 (&mtk_subdev->channels_lock){+.+.}-{4:4}: [ 15.504990] lock_acquire+0x68/0x84 [ 15.504999] __mutex_lock+0xa4/0x3e0 [ 15.505007] mutex_lock_nested+0x40/0x70 [ 15.505012] mtk_rpmsg_ns_cb+0xe4/0x134 [mtk_rpmsg] [ 15.641684] mtk_rpmsg_ipi_handler+0x38/0x64 [mtk_rpmsg] [ 15.641693] scp_ipi_handler+0xbc/0x180 [mtk_scp] [ 15.663905] mt8192_scp_irq_handler+0x44/0xa4 [mtk_scp] [ 15.663915] scp_irq_handler+0x6c/0xa0 [mtk_scp] [ 15.685779] irq_thread_fn+0x34/0xa0 [ 15.685785] irq_thread+0x18c/0x240 [ 15.685789] kthread+0x104/0x110 [ 15.709579] ret_from_fork+0x10/0x20 [ 15.709586] [] -> #0 (&scp->ipi_desc[i].lock){+.+.}-{4:4}: [ 15.731271] __lock_acquire+0x11e4/0x1910 [ 15.740367] lock_acquire.part.0+0xd8/0x220 [ 15.749813] lock_acquire+0x68/0x84 [ 15.757861] __mutex_lock+0xa4/0x3e0 [ 15.766084] mutex_lock_nested+0x40/0x70 [ 15.775006] scp_ipi_lock+0x34/0x50 [mtk_scp_ipi] [ 15.785503] scp_ipi_register+0x40/0xa4 [mtk_scp_ipi] [ 15.796697] scp_register_ipi+0x1c/0x30 [mtk_scp] [ 15.807194] mtk_rpmsg_create_ept+0xa0/0x108 [mtk_rpmsg] [ 15.818912] rpmsg_create_ept+0x44/0x60 [ 15.827660] cros_ec_rpmsg_probe+0x15c/0x1f0 [ 15.837282] rpmsg_dev_probe+0x128/0x1d0 [ 15.846203] really_probe.part.0+0xa4/0x2a0 [ 15.855649] __driver_probe_device+0xa0/0x150 [ 15.865443] driver_probe_device+0x48/0x150 [ 15.877157] __device_attach_driver+0xc0/0x12c [ 15.889359] bus_for_each_drv+0x80/0xe0 [ 15.900330] __device_attach+0xe4/0x190 [ 15.911303] device_initial_probe+0x1c/0x2c [ 15.922969] bus_probe_device+0xa8/0xb0 [ 15.933927] device_add+0x3a8/0x8a0 [ 15.944193] device_register+0x28/0x40 [ 15.954970] rpmsg_register_device+0x5c/0xa0 [ 15.966782] mtk_register_device_work_function+0x148/0x1cc [mtk_rpmsg] [ 15.983146] process_one_work+0x294/0x664 [ 15.994458] worker_thread+0x7c/0x45c [ 16.005069] kthread+0x104/0x110 [ 16.014789] ret_from_fork+0x10/0x20 [ 16.025201] [] other info that might help us debug this:
[ 16.047769] Possible unsafe locking scenario:
[ 16.063942] CPU0 CPU1 [ 16.075166] ---- ---- [ 16.086376] lock(&mtk_subdev->channels_lock); [ 16.097592] lock(&scp->ipi_desc[i].lock); [ 16.113188] lock(&mtk_subdev->channels_lock); [ 16.129482] lock(&scp->ipi_desc[i].lock); [ 16.140020] [] *** DEADLOCK ***
[ 16.158282] 4 locks held by kworker/0:3/155: [ 16.168978] #0: ffff5b4d00008748 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x1fc/0x664 [ 16.190017] #1: ffff80000953bdc8 ((work_completion)(&mtk_subdev->register_work)){+.+.}-{0:0}, at: process_one_work+0x1fc/0x664 [ 16.215269] #2: ffff5b4d0e8f1918 (&mtk_subdev->channels_lock){+.+.}-{4:4}, at: mtk_register_device_work_function+0x50/0x1cc [mtk_rpmsg] [ 16.242131] #3: ffff5b4d05964190 (&dev->mutex){....}-{4:4}, at: __device_attach+0x44/0x190
To solve this, simply unlock the channels_lock mutex before calling mtk_rpmsg_register_device() and relock it right after, as safety is still ensured by the locking mechanism that happens right after through SCP.
Fixes: 7017996951fd ("rpmsg: add rpmsg support for mt8183 SCP.") Signed-off-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20220525091201.14210-1-angelogioacchino.delregno@c... Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rpmsg/mtk_rpmsg.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/rpmsg/mtk_rpmsg.c b/drivers/rpmsg/mtk_rpmsg.c index 5b4404b8be4c..d1213c33da20 100644 --- a/drivers/rpmsg/mtk_rpmsg.c +++ b/drivers/rpmsg/mtk_rpmsg.c @@ -234,7 +234,9 @@ static void mtk_register_device_work_function(struct work_struct *register_work) if (info->registered) continue;
+ mutex_unlock(&subdev->channels_lock); ret = mtk_rpmsg_register_device(subdev, &info->info); + mutex_lock(&subdev->channels_lock); if (ret) { dev_err(&pdev->dev, "Can't create rpmsg_device\n"); continue;
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit fa220c05d282e7479abe08b54e3bdffd06c25e97 ]
Every iteration of for_each_available_child_of_node() decrements the reference count of the previous node. When breaking early from a for_each_available_child_of_node() loop, we need to explicitly call of_node_put() on the child node. Add missing of_node_put() to avoid refcount leak.
Fixes: 6dedbd1d5443 ("remoteproc: k3-r5: Add a remoteproc driver for R5F subsystem") Signed-off-by: Miaoqian Lin linmq006@gmail.com Acked-by: Suman Anna s-anna@ti.com Link: https://lore.kernel.org/r/20220605083334.23942-1-linmq006@gmail.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/remoteproc/ti_k3_r5_remoteproc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c index 4840ad906018..0481926c6975 100644 --- a/drivers/remoteproc/ti_k3_r5_remoteproc.c +++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c @@ -1655,6 +1655,7 @@ static int k3_r5_cluster_of_init(struct platform_device *pdev) if (!cpdev) { ret = -ENODEV; dev_err(dev, "could not get R5 core platform device\n"); + of_node_put(child); goto fail; }
@@ -1663,6 +1664,7 @@ static int k3_r5_cluster_of_init(struct platform_device *pdev) dev_err(dev, "k3_r5_core_of_init failed, ret = %d\n", ret); put_device(&cpdev->dev); + of_node_put(child); goto fail; }
From: Joe Lawrence joe.lawrence@redhat.com
[ Upstream commit 55eb9a6c8bf3e2099863118ef53e02d9f44f85a8 ]
The test_klp_callbacks_busy module conditionally blocks a future livepatch transition by busy waiting inside its workqueue function, busymod_work_func(). After scheduling this work, a test livepatch is loaded, introducing the transition under test.
Both events are marked in the kernel log for later verification, but there is no synchronization to ensure that busymod_work_func() logs its function entry message before subsequent selftest commands log their own messages. This can lead to a rare test failure due to unexpected ordering like:
# --- expected # +++ result # @@ -1,7 +1,7 @@ # % modprobe test_klp_callbacks_busy block_transition=Y # test_klp_callbacks_busy: test_klp_callbacks_busy_init # -test_klp_callbacks_busy: busymod_work_func enter # % modprobe test_klp_callbacks_demo # +test_klp_callbacks_busy: busymod_work_func enter # livepatch: enabling patch 'test_klp_callbacks_demo' # livepatch: 'test_klp_callbacks_demo': initializing patching transition # test_klp_callbacks_demo: pre_patch_callback: vmlinux
Force the module init function to wait until busymod_work_func() has started (and logged its message), before exiting to the next selftest steps.
Fixes: 547840bd5ae5 ("selftests/livepatch: simplify test-klp-callbacks busy target tests") Signed-off-by: Joe Lawrence joe.lawrence@redhat.com Reviewed-by: Petr Mladek pmladek@suse.com Signed-off-by: Petr Mladek pmladek@suse.com Link: https://lore.kernel.org/r/20220602203233.979681-1-joe.lawrence@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- lib/livepatch/test_klp_callbacks_busy.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/lib/livepatch/test_klp_callbacks_busy.c b/lib/livepatch/test_klp_callbacks_busy.c index 7ac845f65be5..133929e0ce8f 100644 --- a/lib/livepatch/test_klp_callbacks_busy.c +++ b/lib/livepatch/test_klp_callbacks_busy.c @@ -16,10 +16,12 @@ MODULE_PARM_DESC(block_transition, "block_transition (default=false)");
static void busymod_work_func(struct work_struct *work); static DECLARE_WORK(work, busymod_work_func); +static DECLARE_COMPLETION(busymod_work_started);
static void busymod_work_func(struct work_struct *work) { pr_info("%s enter\n", __func__); + complete(&busymod_work_started);
while (READ_ONCE(block_transition)) { /* @@ -37,6 +39,12 @@ static int test_klp_callbacks_busy_init(void) pr_info("%s\n", __func__); schedule_work(&work);
+ /* + * To synchronize kernel messages, hold the init function from + * exiting until the work function's entry message has printed. + */ + wait_for_completion(&busymod_work_started); + if (!block_transition) { /* * Serialize output: print all messages from the work
From: Chen Zhongjin chenzhongjin@huawei.com
[ Upstream commit 0fe6ee8f123a4dfb529a5aff07536bb481f34043 ]
2d186afd04d6 ("profiling: fix shift-out-of-bounds bugs") limits shift value by [0, BITS_PER_LONG -1], which means [0, 63].
However, syzbot found that the max shift value should be the bit number of (_etext - _stext). If shift is outside of this, the "buffer_bytes" will be zero and will cause kzalloc(0). Then the kernel panics due to dereferencing the returned pointer 16.
This can be easily reproduced by passing a large number like 60 to enable profiling and then run readprofile.
LOGS: BUG: kernel NULL pointer dereference, address: 0000000000000010 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page PGD 6148067 P4D 6148067 PUD 6142067 PMD 0 PREEMPT SMP CPU: 4 PID: 184 Comm: readprofile Not tainted 5.18.0+ #162 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 RIP: 0010:read_profile+0x104/0x220 RSP: 0018:ffffc900006fbe80 EFLAGS: 00000202 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 RDX: ffff888006150000 RSI: 0000000000000001 RDI: ffffffff82aba4a0 RBP: 000000000188bb60 R08: 0000000000000010 R09: ffff888006151000 R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff82aba4a0 R13: 0000000000000000 R14: ffffc900006fbf08 R15: 0000000000020c30 FS: 000000000188a8c0(0000) GS:ffff88803ed00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000010 CR3: 0000000006144000 CR4: 00000000000006e0 Call Trace: <TASK> proc_reg_read+0x56/0x70 vfs_read+0x9a/0x1b0 ksys_read+0xa1/0xe0 ? fpregs_assert_state_consistent+0x1e/0x40 do_syscall_64+0x3a/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 RIP: 0033:0x4d4b4e RSP: 002b:00007ffebb668d58 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 RAX: ffffffffffffffda RBX: 000000000188a8a0 RCX: 00000000004d4b4e RDX: 0000000000000400 RSI: 000000000188bb60 RDI: 0000000000000003 RBP: 0000000000000003 R08: 000000000000006e R09: 0000000000000000 R10: 0000000000000041 R11: 0000000000000246 R12: 000000000188bb60 R13: 0000000000000400 R14: 0000000000000000 R15: 000000000188bb60 </TASK> Modules linked in: CR2: 0000000000000010 Killed ---[ end trace 0000000000000000 ]---
Check prof_len in profile_init() to prevent it be zero.
Link: https://lkml.kernel.org/r/20220531012854.229439-1-chenzhongjin@huawei.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Chen Zhongjin chenzhongjin@huawei.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/profile.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/kernel/profile.c b/kernel/profile.c index 37640a0bd8a3..ae82ddfc6a68 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -109,6 +109,13 @@ int __ref profile_init(void)
/* only text is profiled */ prof_len = (_etext - _stext) >> prof_shift; + + if (!prof_len) { + pr_warn("profiling shift: %u too large\n", prof_shift); + prof_on = 0; + return -EINVAL; + } + buffer_bytes = prof_len*sizeof(atomic_t);
if (!alloc_cpumask_var(&prof_cpu_mask, GFP_KERNEL))
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 61afafe8b938bc74841cf4b1a73dd08b9d287c5a ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not needed anymore. This function has two paths missing of_node_put().
Fixes: 6e962bfe56b9 ("remoteproc: imx_rproc: add missing of_node_put") Fixes: a0ff4aa6f010 ("remoteproc: imx_rproc: add a NXP/Freescale imx_rproc driver") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220512045558.7142-1-linmq006@gmail.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/remoteproc/imx_rproc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index 4a3352821b1d..38383e7de3c1 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -594,16 +594,17 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
node = of_parse_phandle(np, "memory-region", a); /* Not map vdevbuffer, vdevring region */ - if (!strncmp(node->name, "vdev", strlen("vdev"))) + if (!strncmp(node->name, "vdev", strlen("vdev"))) { + of_node_put(node); continue; + } err = of_address_to_resource(node, 0, &res); + of_node_put(node); if (err) { dev_err(dev, "unable to resolve memory region\n"); return err; }
- of_node_put(node); - if (b >= IMX_RPROC_MEM_MAX) break;
From: Alexey Kardashevskiy aik@ozlabs.ru
[ Upstream commit a784101f77b1bef4b40f4ad68af3f54fcfa5321b ]
This fixes "no previous prototype":
arch/powerpc/kvm/book3s_hv_rm_xics.c:482:15: warning: no previous prototype for 'xics_rm_h_xirr_x' [-Wmissing-prototypes]
Reported by the kernel test robot.
Fixes: b22af9041927 ("KVM: PPC: Book3s: Remove real mode interrupt controller hcalls handlers") Signed-off-by: Alexey Kardashevskiy aik@ozlabs.ru Reviewed-by: Greg Kurz groug@kaod.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220622055235.1139204-1-aik@ozlabs.ru Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kvm/book3s_xics.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/kvm/book3s_xics.h b/arch/powerpc/kvm/book3s_xics.h index 8e4c79e2fcd8..08fb0843faf5 100644 --- a/arch/powerpc/kvm/book3s_xics.h +++ b/arch/powerpc/kvm/book3s_xics.h @@ -143,6 +143,7 @@ static inline struct kvmppc_ics *kvmppc_xics_find_ics(struct kvmppc_xics *xics, }
extern unsigned long xics_rm_h_xirr(struct kvm_vcpu *vcpu); +extern unsigned long xics_rm_h_xirr_x(struct kvm_vcpu *vcpu); extern int xics_rm_h_ipi(struct kvm_vcpu *vcpu, unsigned long server, unsigned long mfrr); extern int xics_rm_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr);
From: Hangyu Hua hbh25y@gmail.com
[ Upstream commit d7bd416d35121c95fe47330e09a5c04adbc5f928 ]
rpmsg_register_device_override need to call put_device to free vch when driver_set_override fails.
Fix this by adding a put_device() to the error path.
Fixes: bb17d110cbf2 ("rpmsg: Fix calling device_lock() on non-initialized device") Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Hangyu Hua hbh25y@gmail.com Link: https://lore.kernel.org/r/20220624024120.11576-1-hbh25y@gmail.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rpmsg/rpmsg_core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c index 290c1f02da10..5a47cad89fdc 100644 --- a/drivers/rpmsg/rpmsg_core.c +++ b/drivers/rpmsg/rpmsg_core.c @@ -618,6 +618,7 @@ int rpmsg_register_device_override(struct rpmsg_device *rpdev, strlen(driver_override)); if (ret) { dev_err(dev, "device_set_override failed: %d\n", ret); + put_device(dev); return ret; } }
From: Michael Ellerman mpe@ellerman.id.au
[ Upstream commit 4228a996b072d36f3baafb4afdc2d2d66d2cbadf ]
Older machines don't have the firmware feature that enables the code this test is testing. Skip the test if the sysfs directory doesn't exist. Also use the FAIL_IF() macro to provide more verbose error reporting if an error is encountered.
Fixes: 57201d657eb7 ("selftest/powerpc: Add PAPR sysfs attributes sniff test") Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220619233103.2666171-1-mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- .../powerpc/papr_attributes/attr_test.c | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/tools/testing/selftests/powerpc/papr_attributes/attr_test.c b/tools/testing/selftests/powerpc/papr_attributes/attr_test.c index bab0dc06e90b..9b655be641c9 100644 --- a/tools/testing/selftests/powerpc/papr_attributes/attr_test.c +++ b/tools/testing/selftests/powerpc/papr_attributes/attr_test.c @@ -7,6 +7,7 @@ * Copyright 2022, Pratik Rajesh Sampat, IBM Corp. */
+#include <errno.h> #include <stdio.h> #include <string.h> #include <dirent.h> @@ -32,7 +33,7 @@ enum type { NUM_VAL };
-int value_type(int id) +static int value_type(int id) { int val_type;
@@ -54,15 +55,21 @@ int value_type(int id) return val_type; }
-int verify_energy_info(void) +static int verify_energy_info(void) { const char *path = "/sys/firmware/papr/energy_scale_info"; struct dirent *entry; struct stat s; DIR *dirp;
- if (stat(path, &s) || !S_ISDIR(s.st_mode)) - return -1; + errno = 0; + if (stat(path, &s)) { + SKIP_IF(errno == ENOENT); + FAIL_IF(errno); + } + + FAIL_IF(!S_ISDIR(s.st_mode)); + dirp = opendir(path);
while ((entry = readdir(dirp)) != NULL) { @@ -76,25 +83,24 @@ int verify_energy_info(void)
id = atoi(entry->d_name); attr_type = value_type(id); - if (attr_type == INVALID) - return -1; + FAIL_IF(attr_type == INVALID);
/* Check if the files exist and have data in them */ sprintf(file_name, "%s/%d/desc", path, id); f = fopen(file_name, "r"); - if (!f || fgetc(f) == EOF) - return -1; + FAIL_IF(!f); + FAIL_IF(fgetc(f) == EOF);
sprintf(file_name, "%s/%d/value", path, id); f = fopen(file_name, "r"); - if (!f || fgetc(f) == EOF) - return -1; + FAIL_IF(!f); + FAIL_IF(fgetc(f) == EOF);
if (attr_type == STR_VAL) { sprintf(file_name, "%s/%d/value_desc", path, id); f = fopen(file_name, "r"); - if (!f || fgetc(f) == EOF) - return -1; + FAIL_IF(!f); + FAIL_IF(fgetc(f) == EOF); } }
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit bd10b0dafdcf0ec1677cad70101e1f97b9e28f2e ]
h1940_uda1380 uses gpiod*/GPIOD* so it should include GPIO consumer header.
Fixes: 9666e27f90b9 ("ASoC: samsung: h1940: turn into platform driver") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220627141900.470469-1-krzysztof.kozlowski@linaro... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/samsung/h1940_uda1380.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index 907266aee839..fa45a54ab18f 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c @@ -8,7 +8,7 @@ // Based on version from Arnaud Patard arnaud.patard@rtp-net.org
#include <linux/types.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/module.h>
#include <sound/soc.h>
From: Athira Rajeev atrajeev@linux.vnet.ibm.com
[ Upstream commit 890005a7d98f7452cfe86dcfb2aeeb7df01132ce ]
commit 2c9ac51b850d ("powerpc/perf: Fix PMU callbacks to clear pending PMI before resetting an overflown PMC") added a new function "pmi_irq_pending" in hw_irq.h. This function is to check if there is a PMI marked as pending in Paca (PACA_IRQ_PMI).This is used in power_pmu_disable in a WARN_ON. The intention here is to provide a warning if there is PMI pending, but no counter is found overflown.
During some of the perf runs, below warning is hit:
WARNING: CPU: 36 PID: 0 at arch/powerpc/perf/core-book3s.c:1332 power_pmu_disable+0x25c/0x2c0 Modules linked in: -----
NIP [c000000000141c3c] power_pmu_disable+0x25c/0x2c0 LR [c000000000141c8c] power_pmu_disable+0x2ac/0x2c0 Call Trace: [c000000baffcfb90] [c000000000141c8c] power_pmu_disable+0x2ac/0x2c0 (unreliable) [c000000baffcfc10] [c0000000003e2f8c] perf_pmu_disable+0x4c/0x60 [c000000baffcfc30] [c0000000003e3344] group_sched_out.part.124+0x44/0x100 [c000000baffcfc80] [c0000000003e353c] __perf_event_disable+0x13c/0x240 [c000000baffcfcd0] [c0000000003dd334] event_function+0xc4/0x140 [c000000baffcfd20] [c0000000003d855c] remote_function+0x7c/0xa0 [c000000baffcfd50] [c00000000026c394] flush_smp_call_function_queue+0xd4/0x300 [c000000baffcfde0] [c000000000065b24] smp_ipi_demux_relaxed+0xa4/0x100 [c000000baffcfe20] [c0000000000cb2b0] xive_muxed_ipi_action+0x20/0x40 [c000000baffcfe40] [c000000000207c3c] __handle_irq_event_percpu+0x8c/0x250 [c000000baffcfee0] [c000000000207e2c] handle_irq_event_percpu+0x2c/0xa0 [c000000baffcff10] [c000000000210a04] handle_percpu_irq+0x84/0xc0 [c000000baffcff40] [c000000000205f14] generic_handle_irq+0x54/0x80 [c000000baffcff60] [c000000000015740] __do_irq+0x90/0x1d0 [c000000baffcff90] [c000000000016990] __do_IRQ+0xc0/0x140 [c0000009732f3940] [c000000bafceaca8] 0xc000000bafceaca8 [c0000009732f39d0] [c000000000016b78] do_IRQ+0x168/0x1c0 [c0000009732f3a00] [c0000000000090c8] hardware_interrupt_common_virt+0x218/0x220
This means that there is no PMC overflown among the active events in the PMU, but there is a PMU pending in Paca. The function "any_pmc_overflown" checks the PMCs on active events in cpuhw->n_events. Code snippet:
<<>> if (any_pmc_overflown(cpuhw)) clear_pmi_irq_pending(); else WARN_ON(pmi_irq_pending()); <<>>
Here the PMC overflown is not from active event. Example: When we do perf record, default cycles and instructions will be running on PMC6 and PMC5 respectively. It could happen that overflowed event is currently not active and pending PMI is for the inactive event. Debug logs from trace_printk:
<<>> any_pmc_overflown: idx is 5: pmc value is 0xd9a power_pmu_disable: PMC1: 0x0, PMC2: 0x0, PMC3: 0x0, PMC4: 0x0, PMC5: 0xd9a, PMC6: 0x80002011 <<>>
Here active PMC (from idx) is PMC5 , but overflown PMC is PMC6(0x80002011). When we handle PMI interrupt for such cases, if the PMC overflown is from inactive event, it will be ignored. Reference commit: commit bc09c219b2e6 ("powerpc/perf: Fix finding overflowed PMC in interrupt")
Patch addresses two changes: 1) Fix 1 : Removal of warning ( WARN_ON(pmi_irq_pending()); ) We were printing warning if no PMC is found overflown among active PMU events, but PMI pending in PACA. But this could happen in cases where PMC overflown is not in active PMC. An inactive event could have caused the overflow. Hence the warning is not needed. To know pending PMI is from an inactive event, we need to loop through all PMC's which will cause more SPR reads via mfspr and increase in context switch. Also in existing function: perf_event_interrupt, already we ignore PMI's overflown when it is from an inactive PMC.
2) Fix 2: optimization in clearing pending PMI. Currently we check for any active PMC overflown before clearing PMI pending in Paca. This is causing additional SPR read also. From point 1, we know that if PMI pending in Paca from inactive cases, that is going to be ignored during replay. Hence if there is pending PMI in Paca, just clear it irrespective of PMC overflown or not.
In summary, remove the any_pmc_overflown check entirely in power_pmu_disable. ie If there is a pending PMI in Paca, clear it, since we are in pmu_disable. There could be cases where PMI is pending because of inactive PMC ( which later when replayed also will get ignored ), so WARN_ON could give false warning. Hence removing it.
Fixes: 2c9ac51b850d ("powerpc/perf: Fix PMU callbacks to clear pending PMI before resetting an overflown PMC") Signed-off-by: Athira Rajeev atrajeev@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220522142256.24699-1-atrajeev@linux.vnet.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/perf/core-book3s.c | 35 ++++++++++++++------------------- 1 file changed, 15 insertions(+), 20 deletions(-)
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 140502a7fdf8..03c64a0195df 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -1349,27 +1349,22 @@ static void power_pmu_disable(struct pmu *pmu) * a PMI happens during interrupt replay and perf counter * values are cleared by PMU callbacks before replay. * - * If any PMC corresponding to the active PMU events are - * overflown, disable the interrupt by clearing the paca - * bit for PMI since we are disabling the PMU now. - * Otherwise provide a warning if there is PMI pending, but - * no counter is found overflown. + * Disable the interrupt by clearing the paca bit for PMI + * since we are disabling the PMU now. Otherwise provide a + * warning if there is PMI pending, but no counter is found + * overflown. + * + * Since power_pmu_disable runs under local_irq_save, it + * could happen that code hits a PMC overflow without PMI + * pending in paca. Hence only clear PMI pending if it was + * set. + * + * If a PMI is pending, then MSR[EE] must be disabled (because + * the masked PMI handler disabling EE). So it is safe to + * call clear_pmi_irq_pending(). */ - if (any_pmc_overflown(cpuhw)) { - /* - * Since power_pmu_disable runs under local_irq_save, it - * could happen that code hits a PMC overflow without PMI - * pending in paca. Hence only clear PMI pending if it was - * set. - * - * If a PMI is pending, then MSR[EE] must be disabled (because - * the masked PMI handler disabling EE). So it is safe to - * call clear_pmi_irq_pending(). - */ - if (pmi_irq_pending()) - clear_pmi_irq_pending(); - } else - WARN_ON(pmi_irq_pending()); + if (pmi_irq_pending()) + clear_pmi_irq_pending();
val = mmcra = cpuhw->mmcr.mmcra;
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
[ Upstream commit 586fb2641371cf7f23a401ab1c79b17e3ec457f4 ]
commit 900dedd7e47cc3f ("ASoC: Introduce snd_soc_of_get_dai_link_cpus") adds new snd_soc_of_get_dai_link_cpus(), but it is using "codec" everywhere. It is very strange, and is issue when error case. It should call cpu instead of codec in error case. This patch tidyup it.
Fixes: 900dedd7e47cc3f ("ASoC: Introduce snd_soc_of_get_dai_link_cpus") Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Reviewed-by: Martin Povišer povik+lin@cutebit.org Link: https://lore.kernel.org/r/87zgi5p7k1.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/soc-core.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 9574f86dd4de..46f0e8eb79b3 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3433,26 +3433,26 @@ int snd_soc_of_get_dai_link_cpus(struct device *dev, struct of_phandle_args args; struct snd_soc_dai_link_component *component; char *name; - int index, num_codecs, ret; + int index, num_cpus, ret;
- /* Count the number of CODECs */ + /* Count the number of CPUs */ name = "sound-dai"; - num_codecs = of_count_phandle_with_args(of_node, name, + num_cpus = of_count_phandle_with_args(of_node, name, "#sound-dai-cells"); - if (num_codecs <= 0) { - if (num_codecs == -ENOENT) + if (num_cpus <= 0) { + if (num_cpus == -ENOENT) dev_err(dev, "No 'sound-dai' property\n"); else dev_err(dev, "Bad phandle in 'sound-dai'\n"); - return num_codecs; + return num_cpus; } component = devm_kcalloc(dev, - num_codecs, sizeof(*component), + num_cpus, sizeof(*component), GFP_KERNEL); if (!component) return -ENOMEM; dai_link->cpus = component; - dai_link->num_cpus = num_codecs; + dai_link->num_cpus = num_cpus;
/* Parse the list */ for_each_link_cpus(dai_link, index, component) { @@ -3468,7 +3468,7 @@ int snd_soc_of_get_dai_link_cpus(struct device *dev, } return 0; err: - snd_soc_of_put_dai_link_codecs(dai_link); + snd_soc_of_put_dai_link_cpus(dai_link); dai_link->cpus = NULL; dai_link->num_cpus = 0; return ret;
From: Tom Rix trix@redhat.com
[ Upstream commit d2294461b90e0c5b3bbfaaf2c8baff4fd3e2bb13 ]
sparse reports sound/soc/samsung/rx1950_uda1380.c:131:18: warning: symbol 'gpiod_speaker_power' was not declared. Should it be static? sound/soc/samsung/rx1950_uda1380.c:231:24: warning: symbol 'rx1950_audio' was not declared. Should it be static?
Both gpiod_speaker_power and rx1950_audio are only used in rx1950_uda1380.c, so their storage class specifiers should be static.
Fixes: 83d74e354200 ("ASoC: samsung: rx1950: turn into platform driver") Signed-off-by: Tom Rix trix@redhat.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220629185345.910406-1-trix@redhat.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/samsung/rx1950_uda1380.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index ff3acc94a454..abf28321f7d7 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c @@ -128,7 +128,7 @@ static int rx1950_startup(struct snd_pcm_substream *substream) &hw_rates); }
-struct gpio_desc *gpiod_speaker_power; +static struct gpio_desc *gpiod_speaker_power;
static int rx1950_spk_power(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -228,7 +228,7 @@ static int rx1950_probe(struct platform_device *pdev) return devm_snd_soc_register_card(dev, &rx1950_asoc); }
-struct platform_driver rx1950_audio = { +static struct platform_driver rx1950_audio = { .driver = { .name = "rx1950-audio", .pm = &snd_soc_pm_ops,
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
[ Upstream commit b9491b2e45d71eb64245560e208897af95ffbf95 ]
Accessing LSR requires port lock because it mutates lsr_saved_flags in serial_lsr_in().
Fixes: 197eb5c416ff ("serial: 8250_dw: Use serial_lsr_in() in dw8250_handle_irq()") Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/r/c5879db7-bee9-93f-526e-872a292442@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_dw.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index c0ab67033a25..d0dfbf1fc9d8 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -266,7 +266,10 @@ static int dw8250_handle_irq(struct uart_port *p)
/* Manually stop the Rx DMA transfer when acting as flow controller */ if (quirks & DW_UART_QUIRK_IS_DMA_FC && up->dma && up->dma->rx_running && rx_timeout) { + spin_lock_irqsave(&p->lock, flags); status = serial_lsr_in(up); + spin_unlock_irqrestore(&p->lock, flags); + if (status & (UART_LSR_DR | UART_LSR_BI)) { dw8250_writel_ext(p, RZN1_UART_RDMACR, 0); dw8250_writel_ext(p, DW_UART_DMASA, 1);
From: Srinivas Kandagatla srinivas.kandagatla@linaro.org
[ Upstream commit cf6af24b54903f9f70c29b3e5b19cb72cc862d60 ]
Currently we do not check if SoundWire slave initialization timeout expired before continuing to access its registers.
Its possible that the registers are not accessible if timeout is expired. Handle this by returning timeout in resume path.
Reported-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Fixes: 8dd552458361 ("ASoC: codecs: wsa881x: add runtime pm support") Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20220630130023.9308-1-srinivas.kandagatla@linaro.o... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/wsa881x.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index f3a56f3ce487..02a438c6c4c7 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -1175,11 +1175,17 @@ static int __maybe_unused wsa881x_runtime_resume(struct device *dev) struct sdw_slave *slave = dev_to_sdw_dev(dev); struct regmap *regmap = dev_get_regmap(dev, NULL); struct wsa881x_priv *wsa881x = dev_get_drvdata(dev); + unsigned long time;
gpiod_direction_output(wsa881x->sd_n, 1);
- wait_for_completion_timeout(&slave->initialization_complete, - msecs_to_jiffies(WSA881X_PROBE_TIMEOUT)); + time = wait_for_completion_timeout(&slave->initialization_complete, + msecs_to_jiffies(WSA881X_PROBE_TIMEOUT)); + if (!time) { + dev_err(dev, "Initialization not complete, timed out\n"); + gpiod_direction_output(wsa881x->sd_n, 0); + return -ETIMEDOUT; + }
regcache_cache_only(regmap, false); regcache_sync(regmap);
From: Yishai Hadas yishaih@nvidia.com
[ Upstream commit 2b1c1906286fa547845f5385ee72db74b2b0251d ]
Protect mlx5vf_disable_fds() upon close device to be called under the state mutex as done in all other places.
This will prevent a race with any other flow which calls mlx5vf_disable_fds() as of health/recovery upon MLX5_PF_NOTIFY_DISABLE_VF event.
Encapsulate this functionality in a separate function named mlx5vf_cmd_close_migratable() to consider migration caps and for further usage upon close device.
Fixes: 6fadb021266d ("vfio/mlx5: Implement vfio_pci driver for mlx5 devices") Reviewed-by: Kevin Tian kevin.tian@intel.com Signed-off-by: Yishai Hadas yishaih@nvidia.com Link: https://lore.kernel.org/r/20220628155910.171454-2-yishaih@nvidia.com Signed-off-by: Alex Williamson alex.williamson@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/vfio/pci/mlx5/cmd.c | 10 ++++++++++ drivers/vfio/pci/mlx5/cmd.h | 1 + drivers/vfio/pci/mlx5/main.c | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index 9b9f33ca270a..cdd0c667dc77 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -88,6 +88,16 @@ static int mlx5fv_vf_event(struct notifier_block *nb, return 0; }
+void mlx5vf_cmd_close_migratable(struct mlx5vf_pci_core_device *mvdev) +{ + if (!mvdev->migrate_cap) + return; + + mutex_lock(&mvdev->state_mutex); + mlx5vf_disable_fds(mvdev); + mlx5vf_state_mutex_unlock(mvdev); +} + void mlx5vf_cmd_remove_migratable(struct mlx5vf_pci_core_device *mvdev) { if (!mvdev->migrate_cap) diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index 6c3112fdd8b1..aa692d9ce656 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -64,6 +64,7 @@ int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev, size_t *state_size); void mlx5vf_cmd_set_migratable(struct mlx5vf_pci_core_device *mvdev); void mlx5vf_cmd_remove_migratable(struct mlx5vf_pci_core_device *mvdev); +void mlx5vf_cmd_close_migratable(struct mlx5vf_pci_core_device *mvdev); int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, struct mlx5_vf_migration_file *migf); int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev, diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 0558d0649ddb..d754990f0662 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -570,7 +570,7 @@ static void mlx5vf_pci_close_device(struct vfio_device *core_vdev) struct mlx5vf_pci_core_device *mvdev = container_of( core_vdev, struct mlx5vf_pci_core_device, core_device.vdev);
- mlx5vf_disable_fds(mvdev); + mlx5vf_cmd_close_migratable(mvdev); vfio_pci_core_close_device(core_vdev); }
From: Yishai Hadas yishaih@nvidia.com
[ Upstream commit 6e97eba8ad8748fabb795cffc5d9e1a7dcfd7367 ]
vfio core checks whether the driver sets some migration op (e.g. set_state/get_state) and accordingly calls its op.
However, currently mlx5 driver sets the above ops without regards to its migration caps.
This might lead to unexpected usage/Oops if user space may call to the above ops even if the driver doesn't support migration. As for example, the migration state_mutex is not initialized in that case.
The cleanest way to manage that seems to split the migration ops from the main device ops, this will let the driver setting them separately from the main ops when it's applicable.
As part of that, validate ops construction on registration and include a check for VFIO_MIGRATION_STOP_COPY since the uAPI claims it must be set in migration_flags.
HISI driver was changed as well to match this scheme.
This scheme may enable down the road to come with some extra group of ops (e.g. DMA log) that can be set without regards to the other options based on driver caps.
Fixes: 6fadb021266d ("vfio/mlx5: Implement vfio_pci driver for mlx5 devices") Reviewed-by: Kevin Tian kevin.tian@intel.com Signed-off-by: Yishai Hadas yishaih@nvidia.com Link: https://lore.kernel.org/r/20220628155910.171454-3-yishaih@nvidia.com Signed-off-by: Alex Williamson alex.williamson@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 11 +++++-- drivers/vfio/pci/mlx5/cmd.c | 4 ++- drivers/vfio/pci/mlx5/cmd.h | 3 +- drivers/vfio/pci/mlx5/main.c | 9 ++++-- drivers/vfio/pci/vfio_pci_core.c | 7 +++++ drivers/vfio/vfio.c | 11 ++++--- include/linux/vfio.h | 30 ++++++++++++------- 7 files changed, 51 insertions(+), 24 deletions(-)
diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index 4def43f5f7b6..ea762e28c1cc 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -1185,7 +1185,7 @@ static int hisi_acc_vfio_pci_open_device(struct vfio_device *core_vdev) if (ret) return ret;
- if (core_vdev->ops->migration_set_state) { + if (core_vdev->mig_ops) { ret = hisi_acc_vf_qm_init(hisi_acc_vdev); if (ret) { vfio_pci_core_disable(vdev); @@ -1208,6 +1208,11 @@ static void hisi_acc_vfio_pci_close_device(struct vfio_device *core_vdev) vfio_pci_core_close_device(core_vdev); }
+static const struct vfio_migration_ops hisi_acc_vfio_pci_migrn_state_ops = { + .migration_set_state = hisi_acc_vfio_pci_set_device_state, + .migration_get_state = hisi_acc_vfio_pci_get_device_state, +}; + static const struct vfio_device_ops hisi_acc_vfio_pci_migrn_ops = { .name = "hisi-acc-vfio-pci-migration", .open_device = hisi_acc_vfio_pci_open_device, @@ -1219,8 +1224,6 @@ static const struct vfio_device_ops hisi_acc_vfio_pci_migrn_ops = { .mmap = hisi_acc_vfio_pci_mmap, .request = vfio_pci_core_request, .match = vfio_pci_core_match, - .migration_set_state = hisi_acc_vfio_pci_set_device_state, - .migration_get_state = hisi_acc_vfio_pci_get_device_state, };
static const struct vfio_device_ops hisi_acc_vfio_pci_ops = { @@ -1272,6 +1275,8 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device if (!ret) { vfio_pci_core_init_device(&hisi_acc_vdev->core_device, pdev, &hisi_acc_vfio_pci_migrn_ops); + hisi_acc_vdev->core_device.vdev.mig_ops = + &hisi_acc_vfio_pci_migrn_state_ops; } else { pci_warn(pdev, "migration support failed, continue with generic interface\n"); vfio_pci_core_init_device(&hisi_acc_vdev->core_device, pdev, diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index cdd0c667dc77..dd5d7bfe0a49 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -108,7 +108,8 @@ void mlx5vf_cmd_remove_migratable(struct mlx5vf_pci_core_device *mvdev) destroy_workqueue(mvdev->cb_wq); }
-void mlx5vf_cmd_set_migratable(struct mlx5vf_pci_core_device *mvdev) +void mlx5vf_cmd_set_migratable(struct mlx5vf_pci_core_device *mvdev, + const struct vfio_migration_ops *mig_ops) { struct pci_dev *pdev = mvdev->core_device.pdev; int ret; @@ -149,6 +150,7 @@ void mlx5vf_cmd_set_migratable(struct mlx5vf_pci_core_device *mvdev) mvdev->core_device.vdev.migration_flags = VFIO_MIGRATION_STOP_COPY | VFIO_MIGRATION_P2P; + mvdev->core_device.vdev.mig_ops = mig_ops;
end: mlx5_vf_put_core_dev(mvdev->mdev); diff --git a/drivers/vfio/pci/mlx5/cmd.h b/drivers/vfio/pci/mlx5/cmd.h index aa692d9ce656..8208f4701a90 100644 --- a/drivers/vfio/pci/mlx5/cmd.h +++ b/drivers/vfio/pci/mlx5/cmd.h @@ -62,7 +62,8 @@ int mlx5vf_cmd_suspend_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod); int mlx5vf_cmd_resume_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod); int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev, size_t *state_size); -void mlx5vf_cmd_set_migratable(struct mlx5vf_pci_core_device *mvdev); +void mlx5vf_cmd_set_migratable(struct mlx5vf_pci_core_device *mvdev, + const struct vfio_migration_ops *mig_ops); void mlx5vf_cmd_remove_migratable(struct mlx5vf_pci_core_device *mvdev); void mlx5vf_cmd_close_migratable(struct mlx5vf_pci_core_device *mvdev); int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev, diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index d754990f0662..a9b63d15c5d3 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -574,6 +574,11 @@ static void mlx5vf_pci_close_device(struct vfio_device *core_vdev) vfio_pci_core_close_device(core_vdev); }
+static const struct vfio_migration_ops mlx5vf_pci_mig_ops = { + .migration_set_state = mlx5vf_pci_set_device_state, + .migration_get_state = mlx5vf_pci_get_device_state, +}; + static const struct vfio_device_ops mlx5vf_pci_ops = { .name = "mlx5-vfio-pci", .open_device = mlx5vf_pci_open_device, @@ -585,8 +590,6 @@ static const struct vfio_device_ops mlx5vf_pci_ops = { .mmap = vfio_pci_core_mmap, .request = vfio_pci_core_request, .match = vfio_pci_core_match, - .migration_set_state = mlx5vf_pci_set_device_state, - .migration_get_state = mlx5vf_pci_get_device_state, };
static int mlx5vf_pci_probe(struct pci_dev *pdev, @@ -599,7 +602,7 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev, if (!mvdev) return -ENOMEM; vfio_pci_core_init_device(&mvdev->core_device, pdev, &mlx5vf_pci_ops); - mlx5vf_cmd_set_migratable(mvdev); + mlx5vf_cmd_set_migratable(mvdev, &mlx5vf_pci_mig_ops); dev_set_drvdata(&pdev->dev, &mvdev->core_device); ret = vfio_pci_core_register_device(&mvdev->core_device); if (ret) diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index a0d69ddaf90d..2efa06b1fafa 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -1855,6 +1855,13 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) return -EINVAL;
+ if (vdev->vdev.mig_ops) { + if (!(vdev->vdev.mig_ops->migration_get_state && + vdev->vdev.mig_ops->migration_set_state) || + !(vdev->vdev.migration_flags & VFIO_MIGRATION_STOP_COPY)) + return -EINVAL; + } + /* * Prevent binding to PFs with VFs enabled, the VFs might be in use * by the host or other users. We cannot capture the VFs if they diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index e60b06f2ac22..18fc0916587e 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -1544,8 +1544,7 @@ vfio_ioctl_device_feature_mig_device_state(struct vfio_device *device, struct file *filp = NULL; int ret;
- if (!device->ops->migration_set_state || - !device->ops->migration_get_state) + if (!device->mig_ops) return -ENOTTY;
ret = vfio_check_feature(flags, argsz, @@ -1561,7 +1560,8 @@ vfio_ioctl_device_feature_mig_device_state(struct vfio_device *device, if (flags & VFIO_DEVICE_FEATURE_GET) { enum vfio_device_mig_state curr_state;
- ret = device->ops->migration_get_state(device, &curr_state); + ret = device->mig_ops->migration_get_state(device, + &curr_state); if (ret) return ret; mig.device_state = curr_state; @@ -1569,7 +1569,7 @@ vfio_ioctl_device_feature_mig_device_state(struct vfio_device *device, }
/* Handle the VFIO_DEVICE_FEATURE_SET */ - filp = device->ops->migration_set_state(device, mig.device_state); + filp = device->mig_ops->migration_set_state(device, mig.device_state); if (IS_ERR(filp) || !filp) goto out_copy;
@@ -1592,8 +1592,7 @@ static int vfio_ioctl_device_feature_migration(struct vfio_device *device, }; int ret;
- if (!device->ops->migration_set_state || - !device->ops->migration_get_state) + if (!device->mig_ops) return -ENOTTY;
ret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_GET, diff --git a/include/linux/vfio.h b/include/linux/vfio.h index aa888cc51757..d6c592565be7 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -32,6 +32,11 @@ struct vfio_device_set { struct vfio_device { struct device *dev; const struct vfio_device_ops *ops; + /* + * mig_ops is a static property of the vfio_device which must be set + * prior to registering the vfio_device. + */ + const struct vfio_migration_ops *mig_ops; struct vfio_group *group; struct vfio_device_set *dev_set; struct list_head dev_set_list; @@ -61,16 +66,6 @@ struct vfio_device { * match, -errno for abort (ex. match with insufficient or incorrect * additional args) * @device_feature: Optional, fill in the VFIO_DEVICE_FEATURE ioctl - * @migration_set_state: Optional callback to change the migration state for - * devices that support migration. It's mandatory for - * VFIO_DEVICE_FEATURE_MIGRATION migration support. - * The returned FD is used for data transfer according to the FSM - * definition. The driver is responsible to ensure that FD reaches end - * of stream or error whenever the migration FSM leaves a data transfer - * state or before close_device() returns. - * @migration_get_state: Optional callback to get the migration state for - * devices that support migration. It's mandatory for - * VFIO_DEVICE_FEATURE_MIGRATION migration support. */ struct vfio_device_ops { char *name; @@ -87,6 +82,21 @@ struct vfio_device_ops { int (*match)(struct vfio_device *vdev, char *buf); int (*device_feature)(struct vfio_device *device, u32 flags, void __user *arg, size_t argsz); +}; + +/** + * @migration_set_state: Optional callback to change the migration state for + * devices that support migration. It's mandatory for + * VFIO_DEVICE_FEATURE_MIGRATION migration support. + * The returned FD is used for data transfer according to the FSM + * definition. The driver is responsible to ensure that FD reaches end + * of stream or error whenever the migration FSM leaves a data transfer + * state or before close_device() returns. + * @migration_get_state: Optional callback to get the migration state for + * devices that support migration. It's mandatory for + * VFIO_DEVICE_FEATURE_MIGRATION migration support. + */ +struct vfio_migration_ops { struct file *(*migration_set_state)( struct vfio_device *device, enum vfio_device_mig_state new_state);
From: Alexander Lobakin alexandr.lobakin@intel.com
[ Upstream commit 2f7ee2a72ccec8b85a05c4644d7ec9f40c1c50c8 ]
Kbuild spotted the following bug during the testing of one of the optimizations:
In file included from include/linux/cpumask.h:12, [...] from drivers/net/ethernet/intel/ice/ice_switch.c:4: drivers/net/ethernet/intel/ice/ice_switch.c: In function 'ice_find_free_recp_res_idx.constprop': include/linux/bitmap.h:447:22: warning: 'possible_idx[0]' is used uninitialized [-Wuninitialized] 447 | *map |= GENMASK(start + nbits - 1, start); | ^~ In file included from drivers/net/ethernet/intel/ice/ice.h:7, from drivers/net/ethernet/intel/ice/ice_lib.h:7, from drivers/net/ethernet/intel/ice/ice_switch.c:4: drivers/net/ethernet/intel/ice/ice_switch.c:4929:24: note: 'possible_idx[0]' was declared here 4929 | DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS); | ^~~~~~~~~~~~ include/linux/types.h:11:23: note: in definition of macro 'DECLARE_BITMAP' 11 | unsigned long name[BITS_TO_LONGS(bits)] | ^~~~
%ICE_MAX_FV_WORDS is 48, so bitmap_set() here was initializing only 48 bits, leaving a junk in the rest 16. It was previously hidden due to that filling 48 bits makes bitmap_set() call external __bitmap_set(), but after making it use plain bit arithmetics on small bitmaps, compilers started seeing the issue. It was still working because those 16 weren't used anywhere anyhow. bitmap_{clear,set}() are not really intended to initialize bitmaps, rather to modify already initialized ones, as they don't do anything past the passed number of bits. The correct function to do this in that particular case is bitmap_fill(), so use it here. It will do `*possible_idx = ~0UL` instead of `*possible_idx |= GENMASK(47, 0)`, not leaving anything in an undefined state.
Fixes: fd2a6b71e300 ("ice: create advanced switch recipe") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Alexander Lobakin alexandr.lobakin@intel.com Signed-off-by: Yury Norov yury.norov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/ice/ice_switch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c index 8d8f3eec79ee..9b2872e89151 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.c +++ b/drivers/net/ethernet/intel/ice/ice_switch.c @@ -4934,7 +4934,7 @@ ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles, bitmap_zero(recipes, ICE_MAX_NUM_RECIPES); bitmap_zero(used_idx, ICE_MAX_FV_WORDS);
- bitmap_set(possible_idx, 0, ICE_MAX_FV_WORDS); + bitmap_fill(possible_idx, ICE_MAX_FV_WORDS);
/* For each profile we are going to associate the recipe with, add the * recipes that are associated with that profile. This will give us
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit ac77f0077c3265197d378158c85a55eee6d21508 ]
After setting up the control channel on both sides the responder side may want to open a virtual tty to listen on until the initiator starts an application on a user channel. The current implementation allows the open() but no other operation, like termios. These fail with EINVAL. The responder sided application has no means to detect an open by the initiator sided application this way. And the initiator sided applications usually expect the responder sided application to listen on the user channel upon open. Set the user channel into half-open state on responder side once a user application opens the virtual tty to allow IO operations on it. Furthermore, keep the user channel constipated until the initiator side opens it to give the responder sided application the chance to detect the new connection and to avoid data loss if the responder sided application starts sending before the user channel is open.
Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220701061652.39604-1-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index fd4d24f61c46..5a0fd35ce1f9 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1510,6 +1510,8 @@ static void gsm_dlci_close(struct gsm_dlci *dlci) if (debug & 8) pr_debug("DLCI %d goes closed.\n", dlci->addr); dlci->state = DLCI_CLOSED; + /* Prevent us from sending data before the link is up again */ + dlci->constipated = true; if (dlci->addr != 0) { tty_port_tty_hangup(&dlci->port, false); spin_lock_irqsave(&dlci->lock, flags); @@ -1539,6 +1541,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) del_timer(&dlci->t1); /* This will let a tty open continue */ dlci->state = DLCI_OPEN; + dlci->constipated = false; if (debug & 8) pr_debug("DLCI %d goes open.\n", dlci->addr); /* Send current modem state */ @@ -1619,6 +1622,25 @@ static void gsm_dlci_begin_open(struct gsm_dlci *dlci) mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); }
+/** + * gsm_dlci_set_opening - change state to opening + * @dlci: DLCI to open + * + * Change internal state to wait for DLCI open from initiator side. + * We set off timers and responses upon reception of an SABM. + */ +static void gsm_dlci_set_opening(struct gsm_dlci *dlci) +{ + switch (dlci->state) { + case DLCI_CLOSED: + case DLCI_CLOSING: + dlci->state = DLCI_OPENING; + break; + default: + break; + } +} + /** * gsm_dlci_begin_close - start channel open procedure * @dlci: DLCI to open @@ -1762,10 +1784,13 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr) dlci->addr = addr; dlci->adaption = gsm->adaption; dlci->state = DLCI_CLOSED; - if (addr) + if (addr) { dlci->data = gsm_dlci_data; - else + /* Prevent us from sending data before the link is up */ + dlci->constipated = true; + } else { dlci->data = gsm_dlci_command; + } gsm->dlci[addr] = dlci; return dlci; } @@ -3174,6 +3199,8 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) /* Start sending off SABM messages */ if (gsm->initiator) gsm_dlci_begin_open(dlci); + else + gsm_dlci_set_opening(dlci); /* And wait for virtual carrier */ return tty_port_block_til_ready(port, tty, filp); }
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit 01aecd917114577c423f07cec0d186ad007d76fc ]
The current implementation registers/deregisters the user ttys at mux attach/detach. That means that the user devices are available before any control channel is open. However, user channel initialization requires an open control channel. Furthermore, the user is not informed if the mux restarts due to configuration changes. Put the registration/deregistration procedure into separate function to improve readability. Move registration to mux activation and deregistration to mux cleanup to keep the user devices only open as long as a control channel exists. The user will be informed via the device driver if the mux was reconfigured in a way that required a mux re-activation. This makes it necessary to add T2 initialization to gsmld_open() for the ldisc open code path (not the reconfiguration code path) to avoid deletion of an uninitialized T2 at mux cleanup.
Fixes: d50f6dcaf22a ("tty: n_gsm: expose gsmtty device nodes at ldisc open time") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220701061652.39604-2-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 117 ++++++++++++++++++++++++++++++-------------- 1 file changed, 79 insertions(+), 38 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 5a0fd35ce1f9..e8c0ce114c07 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -235,6 +235,7 @@ struct gsm_mux { struct gsm_dlci *dlci[NUM_DLCI]; int old_c_iflag; /* termios c_iflag value before attach */ bool constipated; /* Asked by remote to shut up */ + bool has_devices; /* Devices were registered */
spinlock_t tx_lock; unsigned int tx_bytes; /* TX data outstanding */ @@ -463,6 +464,68 @@ static void gsm_hex_dump_bytes(const char *fname, const u8 *data, kfree(prefix); }
+/** + * gsm_register_devices - register all tty devices for a given mux index + * + * @driver: the tty driver that describes the tty devices + * @index: the mux number is used to calculate the minor numbers of the + * ttys for this mux and may differ from the position in the + * mux array. + */ +static int gsm_register_devices(struct tty_driver *driver, unsigned int index) +{ + struct device *dev; + int i; + unsigned int base; + + if (!driver || index >= MAX_MUX) + return -EINVAL; + + base = index * NUM_DLCI; /* first minor for this index */ + for (i = 1; i < NUM_DLCI; i++) { + /* Don't register device 0 - this is the control channel + * and not a usable tty interface + */ + dev = tty_register_device(gsm_tty_driver, base + i, NULL); + if (IS_ERR(dev)) { + if (debug & 8) + pr_info("%s failed to register device minor %u", + __func__, base + i); + for (i--; i >= 1; i--) + tty_unregister_device(gsm_tty_driver, base + i); + return PTR_ERR(dev); + } + } + + return 0; +} + +/** + * gsm_unregister_devices - unregister all tty devices for a given mux index + * + * @driver: the tty driver that describes the tty devices + * @index: the mux number is used to calculate the minor numbers of the + * ttys for this mux and may differ from the position in the + * mux array. + */ +static void gsm_unregister_devices(struct tty_driver *driver, + unsigned int index) +{ + int i; + unsigned int base; + + if (!driver || index >= MAX_MUX) + return; + + base = index * NUM_DLCI; /* first minor for this index */ + for (i = 1; i < NUM_DLCI; i++) { + /* Don't unregister device 0 - this is the control + * channel and not a usable tty interface + */ + tty_unregister_device(gsm_tty_driver, base + i); + } +} + /** * gsm_print_packet - display a frame for debug * @hdr: header to print before decode @@ -2204,6 +2267,10 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) del_timer_sync(&gsm->t2_timer);
/* Free up any link layer users and finally the control channel */ + if (gsm->has_devices) { + gsm_unregister_devices(gsm_tty_driver, gsm->num); + gsm->has_devices = false; + } for (i = NUM_DLCI - 1; i >= 0; i--) if (gsm->dlci[i]) gsm_dlci_release(gsm->dlci[i]); @@ -2227,6 +2294,7 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) static int gsm_activate_mux(struct gsm_mux *gsm) { struct gsm_dlci *dlci; + int ret;
timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); init_waitqueue_head(&gsm->event); @@ -2238,9 +2306,14 @@ static int gsm_activate_mux(struct gsm_mux *gsm) else gsm->receive = gsm1_receive;
+ ret = gsm_register_devices(gsm_tty_driver, gsm->num); + if (ret) + return ret; + dlci = gsm_dlci_alloc(gsm, 0); if (dlci == NULL) return -ENOMEM; + gsm->has_devices = true; gsm->dead = false; /* Tty opens are now permissible */ return 0; } @@ -2500,39 +2573,14 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len) * will need moving to an ioctl path. */
-static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) +static void gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) { - unsigned int base; - int ret, i; - gsm->tty = tty_kref_get(tty); /* Turn off tty XON/XOFF handling to handle it explicitly. */ gsm->old_c_iflag = tty->termios.c_iflag; tty->termios.c_iflag &= (IXON | IXOFF); - ret = gsm_activate_mux(gsm); - if (ret != 0) - tty_kref_put(gsm->tty); - else { - /* Don't register device 0 - this is the control channel and not - a usable tty interface */ - base = mux_num_to_base(gsm); /* Base for this MUX */ - for (i = 1; i < NUM_DLCI; i++) { - struct device *dev; - - dev = tty_register_device(gsm_tty_driver, - base + i, NULL); - if (IS_ERR(dev)) { - for (i--; i >= 1; i--) - tty_unregister_device(gsm_tty_driver, - base + i); - return PTR_ERR(dev); - } - } - } - return ret; }
- /** * gsmld_detach_gsm - stop doing 0710 mux * @tty: tty attached to the mux @@ -2543,12 +2591,7 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) { - unsigned int base = mux_num_to_base(gsm); /* Base for this MUX */ - int i; - WARN_ON(tty != gsm->tty); - for (i = 1; i < NUM_DLCI; i++) - tty_unregister_device(gsm_tty_driver, base + i); /* Restore tty XON/XOFF handling. */ gsm->tty->termios.c_iflag = gsm->old_c_iflag; tty_kref_put(gsm->tty); @@ -2640,7 +2683,6 @@ static void gsmld_close(struct tty_struct *tty) static int gsmld_open(struct tty_struct *tty) { struct gsm_mux *gsm; - int ret;
if (tty->ops->write == NULL) return -EINVAL; @@ -2656,12 +2698,11 @@ static int gsmld_open(struct tty_struct *tty) /* Attach the initial passive connection */ gsm->encoding = 1;
- ret = gsmld_attach_gsm(tty, gsm); - if (ret != 0) { - gsm_cleanup_mux(gsm, false); - mux_put(gsm); - } - return ret; + gsmld_attach_gsm(tty, gsm); + + timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); + + return 0; }
/**
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit 556fc8ac06513cced381588d6d58c184d95cc4fe ]
1) The function drains the fifo for the given user tty/DLCI without considering 'TX_THRESH_HI' and different to gsm_dlci_data_output_framed(), which moves only one packet from the user side to the internal transmission queue. We can only handle one packet at a time here if we want to allow DLCI priority handling in gsm_dlci_data_sweep() to avoid link starvation. 2) Furthermore, the additional header octet from convergence layer type 2 is not counted against MTU. It is part of the UI/UIH frame message which needs to be limited to MTU. Hence, it is wrong not to consider this octet. 3) Finally, the waiting user tty is not informed about freed space in its send queue.
Take at most one packet worth of data out of the DLCI fifo to fix 1). Limit the max user data size per packet to MTU - 1 in case of convergence layer type 2 to leave space for the control signal octet which is added in the later part of the function. This fixes 2). Add tty_port_tty_wakeup() to wake up the user tty if new write space has been made available to fix 3).
Fixes: 268e526b935e ("tty/n_gsm: avoid fifo overflow in gsm_dlci_data_output") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220701061652.39604-3-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 74 +++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 32 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index e8c0ce114c07..d056b15b4d61 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -886,41 +886,51 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci) { struct gsm_msg *msg; u8 *dp; - int len, total_size, size; - int h = dlci->adaption - 1; + int h, len, size;
- total_size = 0; - while (1) { - len = kfifo_len(&dlci->fifo); - if (len == 0) - return total_size; - - /* MTU/MRU count only the data bits */ - if (len > gsm->mtu) - len = gsm->mtu; - - size = len + h; - - msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); - /* FIXME: need a timer or something to kick this so it can't - get stuck with no work outstanding and no buffer free */ - if (msg == NULL) - return -ENOMEM; - dp = msg->data; - switch (dlci->adaption) { - case 1: /* Unstructured */ - break; - case 2: /* Unstructed with modem bits. - Always one byte as we never send inline break data */ - *dp++ = (gsm_encode_modem(dlci) << 1) | EA; - break; - } - WARN_ON(kfifo_out_locked(&dlci->fifo, dp , len, &dlci->lock) != len); - __gsm_data_queue(dlci, msg); - total_size += size; + /* for modem bits without break data */ + h = ((dlci->adaption == 1) ? 0 : 1); + + len = kfifo_len(&dlci->fifo); + if (len == 0) + return 0; + + /* MTU/MRU count only the data bits but watch adaption mode */ + if ((len + h) > gsm->mtu) + len = gsm->mtu - h; + + size = len + h; + + msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); + /* FIXME: need a timer or something to kick this so it can't + * get stuck with no work outstanding and no buffer free + */ + if (!msg) + return -ENOMEM; + dp = msg->data; + switch (dlci->adaption) { + case 1: /* Unstructured */ + break; + case 2: /* Unstructured with modem bits. + * Always one byte as we never send inline break data + */ + *dp++ = (gsm_encode_modem(dlci) << 1) | EA; + break; + default: + pr_err("%s: unsupported adaption %d\n", __func__, + dlci->adaption); + break; } + + WARN_ON(len != kfifo_out_locked(&dlci->fifo, dp, len, + &dlci->lock)); + + /* Notify upper layer about available send space. */ + tty_port_tty_wakeup(&dlci->port); + + __gsm_data_queue(dlci, msg); /* Bytes of data we used up */ - return total_size; + return size; }
/**
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit c568f7086c6e771c77aad13d727c70ef70e07243 ]
The current implementation does not handle the situation that no data is in the internal queue and needs to be sent out while the user tty fifo is full. Add a timer that moves more data from user tty down to the internal queue which is then serialized on the ldisc. This timer is triggered if no data was moved from a user tty to the internal queue within 10 * T1.
Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220701061652.39604-4-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index d056b15b4d61..a01225819b92 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -244,6 +244,7 @@ struct gsm_mux { struct list_head tx_list; /* Pending data packets */
/* Control messages */ + struct timer_list kick_timer; /* Kick TX queuing on timeout */ struct timer_list t2_timer; /* Retransmit timer for commands */ int cretries; /* Command retry counter */ struct gsm_control *pending_cmd;/* Our current pending command */ @@ -850,6 +851,7 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) list_add_tail(&msg->list, &gsm->tx_list); gsm->tx_bytes += msg->len; gsm_data_kick(gsm, dlci); + mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100); }
/** @@ -902,9 +904,6 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci) size = len + h;
msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); - /* FIXME: need a timer or something to kick this so it can't - * get stuck with no work outstanding and no buffer free - */ if (!msg) return -ENOMEM; dp = msg->data; @@ -981,9 +980,6 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
size = len + overhead; msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); - - /* FIXME: need a timer or something to kick this so it can't - get stuck with no work outstanding and no buffer free */ if (msg == NULL) { skb_queue_tail(&dlci->skb_list, dlci->skb); dlci->skb = NULL; @@ -1079,9 +1075,9 @@ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci, * renegotiate DLCI priorities with optional stuff. Needs optimising. */
-static void gsm_dlci_data_sweep(struct gsm_mux *gsm) +static int gsm_dlci_data_sweep(struct gsm_mux *gsm) { - int len; + int len, ret = 0; /* Priority ordering: We should do priority with RR of the groups */ int i = 1;
@@ -1104,7 +1100,11 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm) /* DLCI empty - try the next */ if (len == 0) i++; + else + ret++; } + + return ret; }
/** @@ -1823,6 +1823,30 @@ static void gsm_dlci_command(struct gsm_dlci *dlci, const u8 *data, int len) } }
+/** + * gsm_kick_timer - transmit if possible + * @t: timer contained in our gsm object + * + * Transmit data from DLCIs if the queue is empty. We can't rely on + * a tty wakeup except when we filled the pipe so we need to fire off + * new data ourselves in other cases. + */ +static void gsm_kick_timer(struct timer_list *t) +{ + struct gsm_mux *gsm = from_timer(gsm, t, kick_timer); + unsigned long flags; + int sent = 0; + + spin_lock_irqsave(&gsm->tx_lock, flags); + /* If we have nothing running then we need to fire up */ + if (gsm->tx_bytes < TX_THRESH_LO) + sent = gsm_dlci_data_sweep(gsm); + spin_unlock_irqrestore(&gsm->tx_lock, flags); + + if (sent && debug & 4) + pr_info("%s TX queue stalled\n", __func__); +} + /* * Allocate/Free DLCI channels */ @@ -2274,6 +2298,7 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) }
/* Finish outstanding timers, making sure they are done */ + del_timer_sync(&gsm->kick_timer); del_timer_sync(&gsm->t2_timer);
/* Free up any link layer users and finally the control channel */ @@ -2306,6 +2331,7 @@ static int gsm_activate_mux(struct gsm_mux *gsm) struct gsm_dlci *dlci; int ret;
+ timer_setup(&gsm->kick_timer, gsm_kick_timer, 0); timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); init_waitqueue_head(&gsm->event); spin_lock_init(&gsm->control_lock); @@ -2710,6 +2736,7 @@ static int gsmld_open(struct tty_struct *tty)
gsmld_attach_gsm(tty, gsm);
+ timer_setup(&gsm->kick_timer, gsm_kick_timer, 0); timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
return 0;
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit bec0224816d19abe4fe503586d16d51890540615 ]
n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.a... The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to the newer 27.010 here. Chapter 5.4.6.3.6 states that FCoff stops the transmission on all channels except the control channel. This is already implemented in gsm_data_kick(). However, chapter 5.4.8.1 explains that this shall result in the same behavior as software flow control on the ldisc in advanced option mode. That means only flow control frames shall be sent during flow off. The current implementation does not consider this case.
Change gsm_data_kick() to send only flow control frames if constipated to abide the standard. gsm_read_ea_val() and gsm_is_flow_ctrl_msg() are introduced as helper functions for this. It is planned to use gsm_read_ea_val() in later code cleanups for other functions, too.
Fixes: c01af4fec2c8 ("n_gsm : Flow control handling in Mux driver") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220701061652.39604-5-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 54 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index a01225819b92..3f415b2fa199 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -421,6 +421,27 @@ static int gsm_read_ea(unsigned int *val, u8 c) return c & EA; }
+/** + * gsm_read_ea_val - read a value until EA + * @val: variable holding value + * @data: buffer of data + * @dlen: length of data + * + * Processes an EA value. Updates the passed variable and + * returns the processed data length. + */ +static unsigned int gsm_read_ea_val(unsigned int *val, const u8 *data, int dlen) +{ + unsigned int len = 0; + + for (; dlen > 0; dlen--) { + len++; + if (gsm_read_ea(val, *data++)) + break; + } + return len; +} + /** * gsm_encode_modem - encode modem data bits * @dlci: DLCI to encode from @@ -746,6 +767,37 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, return m; }
+/** + * gsm_is_flow_ctrl_msg - checks if flow control message + * @msg: message to check + * + * Returns true if the given message is a flow control command of the + * control channel. False is returned in any other case. + */ +static bool gsm_is_flow_ctrl_msg(struct gsm_msg *msg) +{ + unsigned int cmd; + + if (msg->addr > 0) + return false; + + switch (msg->ctrl & ~PF) { + case UI: + case UIH: + cmd = 0; + if (gsm_read_ea_val(&cmd, msg->data + 2, msg->len - 2) < 1) + break; + switch (cmd & ~PF) { + case CMD_FCOFF: + case CMD_FCON: + return true; + } + break; + } + + return false; +} + /** * gsm_data_kick - poke the queue * @gsm: GSM Mux @@ -765,7 +817,7 @@ static void gsm_data_kick(struct gsm_mux *gsm, struct gsm_dlci *dlci) int len;
list_for_each_entry_safe(msg, nmsg, &gsm->tx_list, list) { - if (gsm->constipated && msg->addr) + if (gsm->constipated && !gsm_is_flow_ctrl_msg(msg)) continue; if (gsm->encoding != 0) { gsm->txframe[0] = GSM1_SOF;
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit 4fae831b3a71fc5a44cc5c7d0b8c1267ee7659f5 ]
In the current implementation control packets are re-transmitted even if the control channel closed down during T2. This is wrong. Check whether the control channel is open before re-transmitting any packets. Note that control channel open/close is handled by T1 and not T2 and remains unaffected by this.
Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220701061652.39604-7-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 3f415b2fa199..39359274096d 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1532,7 +1532,7 @@ static void gsm_control_retransmit(struct timer_list *t) spin_lock_irqsave(&gsm->control_lock, flags); ctrl = gsm->pending_cmd; if (ctrl) { - if (gsm->cretries == 0) { + if (gsm->cretries == 0 || !gsm->dlci[0] || gsm->dlci[0]->dead) { gsm->pending_cmd = NULL; ctrl->error = -ETIMEDOUT; ctrl->done = 1;
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit 32dd59f96924f45e33bc79854f7a00679c0fa28e ]
The function may be used by the user directly and also by the n_gsm internal functions. They can lead into a race condition which results in interleaved frames if both are writing at the same time. The receiving side is not able to decode those interleaved frames correctly.
Add a lock around the low side tty write to avoid race conditions and frame interleaving between user originated writes and n_gsm writes.
Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220701061652.39604-9-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 39359274096d..9a3d7db33394 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2859,11 +2859,24 @@ static ssize_t gsmld_read(struct tty_struct *tty, struct file *file, static ssize_t gsmld_write(struct tty_struct *tty, struct file *file, const unsigned char *buf, size_t nr) { - int space = tty_write_room(tty); + struct gsm_mux *gsm = tty->disc_data; + unsigned long flags; + int space; + int ret; + + if (!gsm) + return -ENODEV; + + ret = -ENOBUFS; + spin_lock_irqsave(&gsm->tx_lock, flags); + space = tty_write_room(tty); if (space >= nr) - return tty->ops->write(tty, buf, nr); - set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); - return -ENOBUFS; + ret = tty->ops->write(tty, buf, nr); + else + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + spin_unlock_irqrestore(&gsm->tx_lock, flags); + + return ret; }
/**
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit 0af021678d5d30c31f5a6b631f404ead3575212a ]
The current implementation queues up new control and user packets as needed and processes this queue down to the ldisc in the same code path. That means that the upper and the lower layer are hard coupled in the code. Due to this deadlocks can happen as seen below while transmitting data, especially during ldisc congestion. Furthermore, the data channels starve the control channel on high transmission load on the ldisc.
Introduce an additional control channel data queue to prevent timeouts and link hangups during ldisc congestion. This is being processed before the user channel data queue in gsm_data_kick(), i.e. with the highest priority. Put the queue to ldisc data path into a workqueue and trigger it whenever new data has been put into the transmission queue. Change gsm_dlci_data_sweep() accordingly to fill up the transmission queue until TX_THRESH_HI. This solves the locking issue, keeps latency low and provides good performance on high data load. Note that now all packets from a DLCI are removed from the internal queue if the associated DLCI was closed. This ensures that no data is sent by the introduced write task to an already closed DLCI.
BUG: spinlock recursion on CPU#0, test_v24_loop/124 lock: serial8250_ports+0x3a8/0x7500, .magic: dead4ead, .owner: test_v24_loop/124, .owner_cpu: 0 CPU: 0 PID: 124 Comm: test_v24_loop Tainted: G O 5.18.0-rc2 #3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 Call Trace: <IRQ> dump_stack_lvl+0x34/0x44 do_raw_spin_lock+0x76/0xa0 _raw_spin_lock_irqsave+0x72/0x80 uart_write_room+0x3b/0xc0 gsm_data_kick+0x14b/0x240 [n_gsm] gsmld_write_wakeup+0x35/0x70 [n_gsm] tty_wakeup+0x53/0x60 tty_port_default_wakeup+0x1b/0x30 serial8250_tx_chars+0x12f/0x220 serial8250_handle_irq.part.0+0xfe/0x150 serial8250_default_handle_irq+0x48/0x80 serial8250_interrupt+0x56/0xa0 __handle_irq_event_percpu+0x78/0x1f0 handle_irq_event+0x34/0x70 handle_fasteoi_irq+0x90/0x1e0 __common_interrupt+0x69/0x100 common_interrupt+0x48/0xc0 asm_common_interrupt+0x1e/0x40 RIP: 0010:__do_softirq+0x83/0x34e Code: 2a 0a ff 0f b7 ed c7 44 24 10 0a 00 00 00 48 c7 c7 51 2a 64 82 e8 2d e2 d5 ff 65 66 c7 05 83 af 1e 7e 00 00 fb b8 ff ff ff ff <49> c7 c2 40 61 80 82 0f bc c5 41 89 c4 41 83 c4 01 0f 84 e6 00 00 RSP: 0018:ffffc90000003f98 EFLAGS: 00000286 RAX: 00000000ffffffff RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff82642a51 RDI: ffffffff825bb5e7 RBP: 0000000000000200 R08: 00000008de3271a8 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000030 R14: 0000000000000000 R15: 0000000000000000 ? __do_softirq+0x73/0x34e irq_exit_rcu+0xb5/0x100 common_interrupt+0xa4/0xc0 </IRQ> <TASK> asm_common_interrupt+0x1e/0x40 RIP: 0010:_raw_spin_unlock_irqrestore+0x2e/0x50 Code: 00 55 48 89 fd 48 83 c7 18 53 48 89 f3 48 8b 74 24 10 e8 85 28 36 ff 48 89 ef e8 cd 58 36 ff 80 e7 02 74 01 fb bf 01 00 00 00 <e8> 3d 97 33 ff 65 8b 05 96 23 2b 7e 85 c0 74 03 5b 5d c3 0f 1f 44 RSP: 0018:ffffc9000020fd08 EFLAGS: 00000202 RAX: 0000000000000000 RBX: 0000000000000246 RCX: 0000000000000000 RDX: 0000000000000004 RSI: ffffffff8257fd74 RDI: 0000000000000001 RBP: ffff8880057de3a0 R08: 00000008de233000 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000100 R14: 0000000000000202 R15: ffff8880057df0b8 ? _raw_spin_unlock_irqrestore+0x23/0x50 gsmtty_write+0x65/0x80 [n_gsm] n_tty_write+0x33f/0x530 ? swake_up_all+0xe0/0xe0 file_tty_write.constprop.0+0x1b1/0x320 ? n_tty_flush_buffer+0xb0/0xb0 new_sync_write+0x10c/0x190 vfs_write+0x282/0x310 ksys_write+0x68/0xe0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f3e5e35c15c Code: 8b 7c 24 08 89 c5 e8 c5 ff ff ff 89 ef 89 44 24 08 e8 58 bc 02 00 8b 44 24 08 48 83 c4 10 5d c3 48 63 ff b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 76 10 48 8b 15 fd fc 05 00 f7 d8 64 89 02 48 83 RSP: 002b:00007ffcee77cd18 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00007ffcee77cd70 RCX: 00007f3e5e35c15c RDX: 0000000000000100 RSI: 00007ffcee77cd90 RDI: 0000000000000003 RBP: 0000000000000100 R08: 0000000000000000 R09: 7efefefefefefeff R10: 00007f3e5e3bddeb R11: 0000000000000246 R12: 00007ffcee77ce8f R13: 0000000000000001 R14: 000056214404e010 R15: 00007ffcee77cd90 </TASK>
Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220701122332.2039-1-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 407 ++++++++++++++++++++++++++++++-------------- 1 file changed, 279 insertions(+), 128 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 9a3d7db33394..79869f2b570c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -5,6 +5,14 @@ * * * THIS IS A DEVELOPMENT SNAPSHOT IT IS NOT A FINAL RELEASE * * + * Outgoing path: + * tty -> DLCI fifo -> scheduler -> GSM MUX data queue ---o-> ldisc + * control message -> GSM MUX control queue --´ + * + * Incoming path: + * ldisc -> gsm_queue() -o--> tty + * `-> gsm_control_response() + * * TO DO: * Mostly done: ioctls for setting modes/timing * Partly done: hooks so you can pull off frames to non tty devs @@ -210,6 +218,9 @@ struct gsm_mux { /* Events on the GSM channel */ wait_queue_head_t event;
+ /* ldisc send work */ + struct work_struct tx_work; + /* Bits for GSM mode decoding */
/* Framing Layer */ @@ -241,7 +252,8 @@ struct gsm_mux { unsigned int tx_bytes; /* TX data outstanding */ #define TX_THRESH_HI 8192 #define TX_THRESH_LO 2048 - struct list_head tx_list; /* Pending data packets */ + struct list_head tx_ctrl_list; /* Pending control packets */ + struct list_head tx_data_list; /* Pending data packets */
/* Control messages */ struct timer_list kick_timer; /* Kick TX queuing on timeout */ @@ -371,6 +383,11 @@ static const u8 gsm_fcs8[256] = {
static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len); static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk); +static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, + u8 ctrl); +static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg); +static void gsmld_write_trigger(struct gsm_mux *gsm); +static void gsmld_write_task(struct work_struct *work);
/** * gsm_fcs_add - update FCS @@ -655,57 +672,73 @@ static int gsm_stuff_frame(const u8 *input, u8 *output, int len) * @cr: command/response bit seen as initiator * @control: control byte including PF bit * - * Format up and transmit a control frame. These do not go via the - * queueing logic as they should be transmitted ahead of data when - * they are needed. - * - * FIXME: Lock versus data TX path + * Format up and transmit a control frame. These should be transmitted + * ahead of data when they are needed. */ - -static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control) +static int gsm_send(struct gsm_mux *gsm, int addr, int cr, int control) { - int len; - u8 cbuf[10]; - u8 ibuf[3]; + struct gsm_msg *msg; + u8 *dp; int ocr; + unsigned long flags; + + msg = gsm_data_alloc(gsm, addr, 0, control); + if (!msg) + return -ENOMEM;
/* toggle C/R coding if not initiator */ ocr = cr ^ (gsm->initiator ? 0 : 1);
- switch (gsm->encoding) { - case 0: - cbuf[0] = GSM0_SOF; - cbuf[1] = (addr << 2) | (ocr << 1) | EA; - cbuf[2] = control; - cbuf[3] = EA; /* Length of data = 0 */ - cbuf[4] = 0xFF - gsm_fcs_add_block(INIT_FCS, cbuf + 1, 3); - cbuf[5] = GSM0_SOF; - len = 6; - break; - case 1: - case 2: - /* Control frame + packing (but not frame stuffing) in mode 1 */ - ibuf[0] = (addr << 2) | (ocr << 1) | EA; - ibuf[1] = control; - ibuf[2] = 0xFF - gsm_fcs_add_block(INIT_FCS, ibuf, 2); - /* Stuffing may double the size worst case */ - len = gsm_stuff_frame(ibuf, cbuf + 1, 3); - /* Now add the SOF markers */ - cbuf[0] = GSM1_SOF; - cbuf[len + 1] = GSM1_SOF; - /* FIXME: we can omit the lead one in many cases */ - len += 2; - break; - default: - WARN_ON(1); - return; - } - gsmld_output(gsm, cbuf, len); - if (!gsm->initiator) { - cr = cr & gsm->initiator; - control = control & ~PF; + msg->data -= 3; + dp = msg->data; + *dp++ = (addr << 2) | (ocr << 1) | EA; + *dp++ = control; + + if (gsm->encoding == 0) + *dp++ = EA; /* Length of data = 0 */ + + *dp = 0xFF - gsm_fcs_add_block(INIT_FCS, msg->data, dp - msg->data); + msg->len = (dp - msg->data) + 1; + + gsm_print_packet("Q->", addr, cr, control, NULL, 0); + + spin_lock_irqsave(&gsm->tx_lock, flags); + list_add_tail(&msg->list, &gsm->tx_ctrl_list); + gsm->tx_bytes += msg->len; + spin_unlock_irqrestore(&gsm->tx_lock, flags); + gsmld_write_trigger(gsm); + + return 0; +} + +/** + * gsm_dlci_clear_queues - remove outstanding data for a DLCI + * @gsm: mux + * @dlci: clear for this DLCI + * + * Clears the data queues for a given DLCI. + */ +static void gsm_dlci_clear_queues(struct gsm_mux *gsm, struct gsm_dlci *dlci) +{ + struct gsm_msg *msg, *nmsg; + int addr = dlci->addr; + unsigned long flags; + + /* Clear DLCI write fifo first */ + spin_lock_irqsave(&dlci->lock, flags); + kfifo_reset(&dlci->fifo); + spin_unlock_irqrestore(&dlci->lock, flags); + + /* Clear data packets in MUX write queue */ + spin_lock_irqsave(&gsm->tx_lock, flags); + list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) { + if (msg->addr != addr) + continue; + gsm->tx_bytes -= msg->len; + list_del(&msg->list); + kfree(msg); } - gsm_print_packet("-->", addr, cr, control, NULL, 0); + spin_unlock_irqrestore(&gsm->tx_lock, flags); }
/** @@ -767,6 +800,45 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, return m; }
+/** + * gsm_send_packet - sends a single packet + * @gsm: GSM Mux + * @msg: packet to send + * + * The given packet is encoded and sent out. No memory is freed. + * The caller must hold the gsm tx lock. + */ +static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg) +{ + int len, ret; + + + if (gsm->encoding == 0) { + gsm->txframe[0] = GSM0_SOF; + memcpy(gsm->txframe + 1, msg->data, msg->len); + gsm->txframe[msg->len + 1] = GSM0_SOF; + len = msg->len + 2; + } else { + gsm->txframe[0] = GSM1_SOF; + len = gsm_stuff_frame(msg->data, gsm->txframe + 1, msg->len); + gsm->txframe[len + 1] = GSM1_SOF; + len += 2; + } + + if (debug & 4) + gsm_hex_dump_bytes(__func__, gsm->txframe, len); + gsm_print_packet("-->", msg->addr, gsm->initiator, msg->ctrl, msg->data, + msg->len); + + ret = gsmld_output(gsm, gsm->txframe, len); + if (ret <= 0) + return ret; + /* FIXME: Can eliminate one SOF in many more cases */ + gsm->tx_bytes -= msg->len; + + return 0; +} + /** * gsm_is_flow_ctrl_msg - checks if flow control message * @msg: message to check @@ -799,59 +871,81 @@ static bool gsm_is_flow_ctrl_msg(struct gsm_msg *msg) }
/** - * gsm_data_kick - poke the queue + * gsm_data_kick - poke the queue * @gsm: GSM Mux - * @dlci: DLCI sending the data * * The tty device has called us to indicate that room has appeared in - * the transmit queue. Ram more data into the pipe if we have any + * the transmit queue. Ram more data into the pipe if we have any. * If we have been flow-stopped by a CMD_FCOFF, then we can only - * send messages on DLCI0 until CMD_FCON - * - * FIXME: lock against link layer control transmissions + * send messages on DLCI0 until CMD_FCON. The caller must hold + * the gsm tx lock. */ - -static void gsm_data_kick(struct gsm_mux *gsm, struct gsm_dlci *dlci) +static int gsm_data_kick(struct gsm_mux *gsm) { struct gsm_msg *msg, *nmsg; - int len; + struct gsm_dlci *dlci; + int ret;
- list_for_each_entry_safe(msg, nmsg, &gsm->tx_list, list) { + clear_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags); + + /* Serialize control messages and control channel messages first */ + list_for_each_entry_safe(msg, nmsg, &gsm->tx_ctrl_list, list) { if (gsm->constipated && !gsm_is_flow_ctrl_msg(msg)) + return -EAGAIN; + ret = gsm_send_packet(gsm, msg); + switch (ret) { + case -ENOSPC: + return -ENOSPC; + case -ENODEV: + /* ldisc not open */ + gsm->tx_bytes -= msg->len; + list_del(&msg->list); + kfree(msg); continue; - if (gsm->encoding != 0) { - gsm->txframe[0] = GSM1_SOF; - len = gsm_stuff_frame(msg->data, - gsm->txframe + 1, msg->len); - gsm->txframe[len + 1] = GSM1_SOF; - len += 2; - } else { - gsm->txframe[0] = GSM0_SOF; - memcpy(gsm->txframe + 1 , msg->data, msg->len); - gsm->txframe[msg->len + 1] = GSM0_SOF; - len = msg->len + 2; - } - - if (debug & 4) - gsm_hex_dump_bytes(__func__, gsm->txframe, len); - if (gsmld_output(gsm, gsm->txframe, len) <= 0) + default: + if (ret >= 0) { + list_del(&msg->list); + kfree(msg); + } break; - /* FIXME: Can eliminate one SOF in many more cases */ - gsm->tx_bytes -= msg->len; - - list_del(&msg->list); - kfree(msg); + } + }
- if (dlci) { - tty_port_tty_wakeup(&dlci->port); - } else { - int i = 0; + if (gsm->constipated) + return -EAGAIN;
- for (i = 0; i < NUM_DLCI; i++) - if (gsm->dlci[i]) - tty_port_tty_wakeup(&gsm->dlci[i]->port); + /* Serialize other channels */ + if (list_empty(&gsm->tx_data_list)) + return 0; + list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) { + dlci = gsm->dlci[msg->addr]; + /* Send only messages for DLCIs with valid state */ + if (dlci->state != DLCI_OPEN) { + gsm->tx_bytes -= msg->len; + list_del(&msg->list); + kfree(msg); + continue; + } + ret = gsm_send_packet(gsm, msg); + switch (ret) { + case -ENOSPC: + return -ENOSPC; + case -ENODEV: + /* ldisc not open */ + gsm->tx_bytes -= msg->len; + list_del(&msg->list); + kfree(msg); + continue; + default: + if (ret >= 0) { + list_del(&msg->list); + kfree(msg); + } + break; } } + + return 1; }
/** @@ -900,9 +994,21 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) msg->data = dp;
/* Add to the actual output queue */ - list_add_tail(&msg->list, &gsm->tx_list); + switch (msg->ctrl & ~PF) { + case UI: + case UIH: + if (msg->addr > 0) { + list_add_tail(&msg->list, &gsm->tx_data_list); + break; + } + fallthrough; + default: + list_add_tail(&msg->list, &gsm->tx_ctrl_list); + break; + } gsm->tx_bytes += msg->len; - gsm_data_kick(gsm, dlci); + + gsmld_write_trigger(gsm); mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100); }
@@ -1129,32 +1235,39 @@ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci,
static int gsm_dlci_data_sweep(struct gsm_mux *gsm) { - int len, ret = 0; /* Priority ordering: We should do priority with RR of the groups */ - int i = 1; - - while (i < NUM_DLCI) { - struct gsm_dlci *dlci; + int i, len, ret = 0; + bool sent; + struct gsm_dlci *dlci;
- if (gsm->tx_bytes > TX_THRESH_HI) - break; - dlci = gsm->dlci[i]; - if (dlci == NULL || dlci->constipated) { - i++; - continue; + while (gsm->tx_bytes < TX_THRESH_HI) { + for (sent = false, i = 1; i < NUM_DLCI; i++) { + dlci = gsm->dlci[i]; + /* skip unused or blocked channel */ + if (!dlci || dlci->constipated) + continue; + /* skip channels with invalid state */ + if (dlci->state != DLCI_OPEN) + continue; + /* count the sent data per adaption */ + if (dlci->adaption < 3 && !dlci->net) + len = gsm_dlci_data_output(gsm, dlci); + else + len = gsm_dlci_data_output_framed(gsm, dlci); + /* on error exit */ + if (len < 0) + return ret; + if (len > 0) { + ret++; + sent = true; + /* The lower DLCs can starve the higher DLCs! */ + break; + } + /* try next */ } - if (dlci->adaption < 3 && !dlci->net) - len = gsm_dlci_data_output(gsm, dlci); - else - len = gsm_dlci_data_output_framed(gsm, dlci); - if (len < 0) + if (!sent) break; - /* DLCI empty - try the next */ - if (len == 0) - i++; - else - ret++; - } + };
return ret; } @@ -1402,7 +1515,6 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, const u8 *data, int clen) { u8 buf[1]; - unsigned long flags;
switch (command) { case CMD_CLD: { @@ -1424,9 +1536,7 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, gsm->constipated = false; gsm_control_reply(gsm, CMD_FCON, NULL, 0); /* Kick the link in case it is idling */ - spin_lock_irqsave(&gsm->tx_lock, flags); - gsm_data_kick(gsm, NULL); - spin_unlock_irqrestore(&gsm->tx_lock, flags); + gsmld_write_trigger(gsm); break; case CMD_FCOFF: /* Modem wants us to STFU */ @@ -1629,8 +1739,6 @@ static int gsm_control_wait(struct gsm_mux *gsm, struct gsm_control *control)
static void gsm_dlci_close(struct gsm_dlci *dlci) { - unsigned long flags; - del_timer(&dlci->t1); if (debug & 8) pr_debug("DLCI %d goes closed.\n", dlci->addr); @@ -1639,17 +1747,16 @@ static void gsm_dlci_close(struct gsm_dlci *dlci) dlci->constipated = true; if (dlci->addr != 0) { tty_port_tty_hangup(&dlci->port, false); - spin_lock_irqsave(&dlci->lock, flags); - kfifo_reset(&dlci->fifo); - spin_unlock_irqrestore(&dlci->lock, flags); + gsm_dlci_clear_queues(dlci->gsm, dlci); /* Ensure that gsmtty_open() can return. */ tty_port_set_initialized(&dlci->port, 0); wake_up_interruptible(&dlci->port.open_wait); } else dlci->gsm->dead = true; - wake_up(&dlci->gsm->event); /* A DLCI 0 close is a MUX termination so we need to kick that back to userspace somehow */ + gsm_dlci_data_kick(dlci); + wake_up(&dlci->gsm->event); }
/** @@ -1672,6 +1779,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) /* Send current modem state */ if (dlci->addr) gsm_modem_update(dlci, 0); + gsm_dlci_data_kick(dlci); wake_up(&dlci->gsm->event); }
@@ -2222,7 +2330,7 @@ static void gsm1_receive(struct gsm_mux *gsm, unsigned char c) } else if ((c & ISO_IEC_646_MASK) == XOFF) { gsm->constipated = false; /* Kick the link in case it is idling */ - gsm_data_kick(gsm, NULL); + gsmld_write_trigger(gsm); return; } if (c == GSM1_SOF) { @@ -2353,6 +2461,9 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) del_timer_sync(&gsm->kick_timer); del_timer_sync(&gsm->t2_timer);
+ /* Finish writing to ldisc */ + flush_work(&gsm->tx_work); + /* Free up any link layer users and finally the control channel */ if (gsm->has_devices) { gsm_unregister_devices(gsm_tty_driver, gsm->num); @@ -2364,9 +2475,12 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) mutex_unlock(&gsm->mutex); /* Now wipe the queues */ tty_ldisc_flush(gsm->tty); - list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) + list_for_each_entry_safe(txq, ntxq, &gsm->tx_ctrl_list, list) + kfree(txq); + INIT_LIST_HEAD(&gsm->tx_ctrl_list); + list_for_each_entry_safe(txq, ntxq, &gsm->tx_data_list, list) kfree(txq); - INIT_LIST_HEAD(&gsm->tx_list); + INIT_LIST_HEAD(&gsm->tx_data_list); }
/** @@ -2385,6 +2499,7 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
timer_setup(&gsm->kick_timer, gsm_kick_timer, 0); timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); + INIT_WORK(&gsm->tx_work, gsmld_write_task); init_waitqueue_head(&gsm->event); spin_lock_init(&gsm->control_lock); spin_lock_init(&gsm->tx_lock); @@ -2494,7 +2609,8 @@ static struct gsm_mux *gsm_alloc_mux(void) spin_lock_init(&gsm->lock); mutex_init(&gsm->mutex); kref_init(&gsm->ref); - INIT_LIST_HEAD(&gsm->tx_list); + INIT_LIST_HEAD(&gsm->tx_ctrl_list); + INIT_LIST_HEAD(&gsm->tx_data_list);
gsm->t1 = T1; gsm->t2 = T2; @@ -2651,6 +2767,47 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len) return gsm->tty->ops->write(gsm->tty, data, len); }
+ +/** + * gsmld_write_trigger - schedule ldisc write task + * @gsm: our mux + */ +static void gsmld_write_trigger(struct gsm_mux *gsm) +{ + if (!gsm || !gsm->dlci[0] || gsm->dlci[0]->dead) + return; + schedule_work(&gsm->tx_work); +} + + +/** + * gsmld_write_task - ldisc write task + * @work: our tx write work + * + * Writes out data to the ldisc if possible. We are doing this here to + * avoid dead-locking. This returns if no space or data is left for output. + */ +static void gsmld_write_task(struct work_struct *work) +{ + struct gsm_mux *gsm = container_of(work, struct gsm_mux, tx_work); + unsigned long flags; + int i, ret; + + /* All outstanding control channel and control messages and one data + * frame is sent. + */ + ret = -ENODEV; + spin_lock_irqsave(&gsm->tx_lock, flags); + if (gsm->tty) + ret = gsm_data_kick(gsm); + spin_unlock_irqrestore(&gsm->tx_lock, flags); + + if (ret >= 0) + for (i = 0; i < NUM_DLCI; i++) + if (gsm->dlci[i]) + tty_port_tty_wakeup(&gsm->dlci[i]->port); +} + /** * gsmld_attach_gsm - mode set up * @tty: our tty structure @@ -2790,6 +2947,7 @@ static int gsmld_open(struct tty_struct *tty)
timer_setup(&gsm->kick_timer, gsm_kick_timer, 0); timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); + INIT_WORK(&gsm->tx_work, gsmld_write_task);
return 0; } @@ -2806,16 +2964,9 @@ static int gsmld_open(struct tty_struct *tty) static void gsmld_write_wakeup(struct tty_struct *tty) { struct gsm_mux *gsm = tty->disc_data; - unsigned long flags;
/* Queue poll */ - clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); - spin_lock_irqsave(&gsm->tx_lock, flags); - gsm_data_kick(gsm, NULL); - if (gsm->tx_bytes < TX_THRESH_LO) { - gsm_dlci_data_sweep(gsm); - } - spin_unlock_irqrestore(&gsm->tx_lock, flags); + gsmld_write_trigger(gsm); }
/**
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit 7349660438603ed19282e75949561406531785a5 ]
Within gsm_activate_mux() all timers and locks are initiated before the actual resource for the control channel is allocated. This can lead to race conditions.
Allocate the control channel DLCI object first to avoid race conditions.
Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220701122332.2039-2-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 79869f2b570c..ba399a660573 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2497,6 +2497,10 @@ static int gsm_activate_mux(struct gsm_mux *gsm) struct gsm_dlci *dlci; int ret;
+ dlci = gsm_dlci_alloc(gsm, 0); + if (dlci == NULL) + return -ENOMEM; + timer_setup(&gsm->kick_timer, gsm_kick_timer, 0); timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); INIT_WORK(&gsm->tx_work, gsmld_write_task); @@ -2513,9 +2517,6 @@ static int gsm_activate_mux(struct gsm_mux *gsm) if (ret) return ret;
- dlci = gsm_dlci_alloc(gsm, 0); - if (dlci == NULL) - return -ENOMEM; gsm->has_devices = true; gsm->dead = false; /* Tty opens are now permissible */ return 0;
From: Liang He windhl@126.com
[ Upstream commit f507c0c67dac57d2bcd5dcae4b6139b0305d8957 ]
We should call of_node_put() for the reference 'dsp_of_node' returned by of_parse_phandle() which will increase the refcount.
Fixes: 9bae4880acee ("ASoC: qcom: move ipq806x specific bits out of lpass driver.") Co-authored-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Liang He windhl@126.com Link: https://lore.kernel.org/r/20220702020109.263980-1-windhl@126.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/qcom/lpass-cpu.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index e6846ad2b5fa..964eb07f46d6 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -1090,6 +1090,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0); if (dsp_of_node) { dev_err(dev, "DSP exists and holds audio resources\n"); + of_node_put(dsp_of_node); return -EBUSY; }
From: Tiezhu Yang yangtiezhu@loongson.cn
[ Upstream commit 08472f6ebdc23334ad11dcd761d2d52c32897793 ]
prom_init_numa_memory() is annotated __init and not used by any module, thus don't export it.
Remove not needed EXPORT_SYMBOL for prom_init_numa_memory() to fix the following section mismatch warning:
LD vmlinux.o MODPOST vmlinux.symvers WARNING: modpost: vmlinux.o(___ksymtab+prom_init_numa_memory+0x0): Section mismatch in reference from the variable __ksymtab_prom_init_numa_memory to the function .init.text:prom_init_numa_memory() The symbol prom_init_numa_memory is exported and annotated __init Fix this by removing the __init annotation of prom_init_numa_memory or drop the export.
This is build on Linux 5.19-rc4.
Fixes: 6fbde6b492df ("MIPS: Loongson64: Move files to the top-level directory") Signed-off-by: Tiezhu Yang yangtiezhu@loongson.cn Reviewed-by: Huacai Chen chenhuacai@kernel.org Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/loongson64/numa.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/mips/loongson64/numa.c b/arch/mips/loongson64/numa.c index 69a533148efd..8f61e93c0c5b 100644 --- a/arch/mips/loongson64/numa.c +++ b/arch/mips/loongson64/numa.c @@ -196,7 +196,6 @@ void __init prom_init_numa_memory(void) pr_info("CP0_PageGrain: CP0 5.1 (0x%x)\n", read_c0_pagegrain()); prom_meminit(); } -EXPORT_SYMBOL(prom_init_numa_memory);
pg_data_t * __init arch_alloc_nodedata(int nid) {
From: Shengjiu Wang shengjiu.wang@nxp.com
[ Upstream commit c0fabd12a8570cb932f13d9388f3d887ad44369b ]
The DSD/PDM rate not only DSD64/128/256/512, which are the multiple rate of 44.1kHz, but also support the multiple rate of 8kHz, so can't force all mclk frequency to be 22579200Hz, need to assign the frequency according to rate.
Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver") Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com Link: https://lore.kernel.org/r/1657100575-8261-1-git-send-email-shengjiu.wang@nxp... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/imx-card.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c index 6f8efd838fcc..c0eb218a254b 100644 --- a/sound/soc/fsl/imx-card.c +++ b/sound/soc/fsl/imx-card.c @@ -17,6 +17,9 @@
#include "fsl_sai.h"
+#define IMX_CARD_MCLK_22P5792MHZ 22579200 +#define IMX_CARD_MCLK_24P576MHZ 24576000 + enum codec_type { CODEC_DUMMY = 0, CODEC_AK5558 = 1, @@ -353,9 +356,14 @@ static int imx_aif_hw_params(struct snd_pcm_substream *substream, mclk_freq = akcodec_get_mclk_rate(substream, params, slots, slot_width); else mclk_freq = params_rate(params) * slots * slot_width; - /* Use the maximum freq from DSD512 (512*44100 = 22579200) */ - if (format_is_dsd(params)) - mclk_freq = 22579200; + + if (format_is_dsd(params)) { + /* Use the maximum freq from DSD512 (512*44100 = 22579200) */ + if (!(params_rate(params) % 11025)) + mclk_freq = IMX_CARD_MCLK_22P5792MHZ; + else + mclk_freq = IMX_CARD_MCLK_24P576MHZ; + }
ret = snd_soc_dai_set_sysclk(cpu_dai, link_data->cpu_sysclk_id, mclk_freq, SND_SOC_CLOCK_OUT);
From: Sireesh Kodali sireeshkodali1@gmail.com
[ Upstream commit bed0adac1ded4cb486ba19a3a7e730fbd9a1c9c6 ]
The wcnss_get_irq function is expected to return a value > 0 in the event that an IRQ is succssfully obtained, but it instead returns 0. This causes the stop and ready IRQs to never actually be used despite being defined in the device-tree. This patch fixes that.
Fixes: aed361adca9f ("remoteproc: qcom: Introduce WCNSS peripheral image loader") Signed-off-by: Sireesh Kodali sireeshkodali1@gmail.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220526141740.15834-2-sireeshkodali1@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/remoteproc/qcom_wcnss.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c index 9a223d394087..68f37296b151 100644 --- a/drivers/remoteproc/qcom_wcnss.c +++ b/drivers/remoteproc/qcom_wcnss.c @@ -467,6 +467,7 @@ static int wcnss_request_irq(struct qcom_wcnss *wcnss, irq_handler_t thread_fn) { int ret; + int irq_number;
ret = platform_get_irq_byname(pdev, name); if (ret < 0 && optional) { @@ -477,14 +478,19 @@ static int wcnss_request_irq(struct qcom_wcnss *wcnss, return ret; }
+ irq_number = ret; + ret = devm_request_threaded_irq(&pdev->dev, ret, NULL, thread_fn, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "wcnss", wcnss); - if (ret) + if (ret) { dev_err(&pdev->dev, "request %s IRQ failed\n", name); + return ret; + }
- return ret; + /* Return the IRQ number if the IRQ was successfully acquired */ + return irq_number; }
static int wcnss_alloc_memory_region(struct qcom_wcnss *wcnss)
From: Michael Kawano mkawano@linux.ibm.com
[ Upstream commit 3566ee1d776c1393393564b2514f9cd52a49c16e ]
As vfio-ccw devices are created/destroyed, the uuid of the associated mdevs that are recorded in $S390DBF/vfio_ccw_msg/sprintf get lost. This is because a pointer to the UUID is stored instead of the UUID itself, and that memory may have been repurposed if/when the logs are examined. The result is usually garbage UUID data in the logs, though there is an outside chance of an oops happening here.
Simply remove the UUID from the traces, as the subchannel number will provide useful configuration information for problem determination, and is stored directly into the log instead of a pointer.
As we were the only consumer of mdev_uuid(), remove that too.
Cc: Kirti Wankhede kwankhede@nvidia.com Signed-off-by: Michael Kawano mkawano@linux.ibm.com Fixes: 60e05d1cf0875 ("vfio-ccw: add some logging") Fixes: b7701dfbf9832 ("vfio-ccw: Register a chp_event callback for vfio-ccw") [farman: reworded commit message, added Fixes: tags] Signed-off-by: Eric Farman farman@linux.ibm.com Reviewed-by: Jason Gunthorpe jgg@nvidia.com Reviewed-by: Matthew Rosato mjrosato@linux.ibm.com Reviewed-by: Kirti Wankhede kwankhede@nvidia.com Link: https://lore.kernel.org/r/20220707135737.720765-2-farman@linux.ibm.com Signed-off-by: Alex Williamson alex.williamson@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/cio/vfio_ccw_drv.c | 5 ++--- drivers/s390/cio/vfio_ccw_fsm.c | 26 ++++++++++++-------------- drivers/s390/cio/vfio_ccw_ops.c | 8 ++++---- include/linux/mdev.h | 5 ----- 4 files changed, 18 insertions(+), 26 deletions(-)
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index ee182cfb467d..35055eb94115 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -14,7 +14,6 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/slab.h> -#include <linux/uuid.h> #include <linux/mdev.h>
#include <asm/isc.h> @@ -358,8 +357,8 @@ static int vfio_ccw_chp_event(struct subchannel *sch, return 0;
trace_vfio_ccw_chp_event(private->sch->schid, mask, event); - VFIO_CCW_MSG_EVENT(2, "%pUl (%x.%x.%04x): mask=0x%x event=%d\n", - mdev_uuid(private->mdev), sch->schid.cssid, + VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: mask=0x%x event=%d\n", + sch->schid.cssid, sch->schid.ssid, sch->schid.sch_no, mask, event);
diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c index 8483a266051c..bbcc5b486749 100644 --- a/drivers/s390/cio/vfio_ccw_fsm.c +++ b/drivers/s390/cio/vfio_ccw_fsm.c @@ -10,7 +10,6 @@ */
#include <linux/vfio.h> -#include <linux/mdev.h>
#include "ioasm.h" #include "vfio_ccw_private.h" @@ -242,7 +241,6 @@ static void fsm_io_request(struct vfio_ccw_private *private, union orb *orb; union scsw *scsw = &private->scsw; struct ccw_io_region *io_region = private->io_region; - struct mdev_device *mdev = private->mdev; char *errstr = "request"; struct subchannel_id schid = get_schid(private);
@@ -256,8 +254,8 @@ static void fsm_io_request(struct vfio_ccw_private *private, if (orb->tm.b) { io_region->ret_code = -EOPNOTSUPP; VFIO_CCW_MSG_EVENT(2, - "%pUl (%x.%x.%04x): transport mode\n", - mdev_uuid(mdev), schid.cssid, + "sch %x.%x.%04x: transport mode\n", + schid.cssid, schid.ssid, schid.sch_no); errstr = "transport mode"; goto err_out; @@ -265,8 +263,8 @@ static void fsm_io_request(struct vfio_ccw_private *private, io_region->ret_code = cp_init(&private->cp, orb); if (io_region->ret_code) { VFIO_CCW_MSG_EVENT(2, - "%pUl (%x.%x.%04x): cp_init=%d\n", - mdev_uuid(mdev), schid.cssid, + "sch %x.%x.%04x: cp_init=%d\n", + schid.cssid, schid.ssid, schid.sch_no, io_region->ret_code); errstr = "cp init"; @@ -276,8 +274,8 @@ static void fsm_io_request(struct vfio_ccw_private *private, io_region->ret_code = cp_prefetch(&private->cp); if (io_region->ret_code) { VFIO_CCW_MSG_EVENT(2, - "%pUl (%x.%x.%04x): cp_prefetch=%d\n", - mdev_uuid(mdev), schid.cssid, + "sch %x.%x.%04x: cp_prefetch=%d\n", + schid.cssid, schid.ssid, schid.sch_no, io_region->ret_code); errstr = "cp prefetch"; @@ -289,8 +287,8 @@ static void fsm_io_request(struct vfio_ccw_private *private, io_region->ret_code = fsm_io_helper(private); if (io_region->ret_code) { VFIO_CCW_MSG_EVENT(2, - "%pUl (%x.%x.%04x): fsm_io_helper=%d\n", - mdev_uuid(mdev), schid.cssid, + "sch %x.%x.%04x: fsm_io_helper=%d\n", + schid.cssid, schid.ssid, schid.sch_no, io_region->ret_code); errstr = "cp fsm_io_helper"; @@ -300,16 +298,16 @@ static void fsm_io_request(struct vfio_ccw_private *private, return; } else if (scsw->cmd.fctl & SCSW_FCTL_HALT_FUNC) { VFIO_CCW_MSG_EVENT(2, - "%pUl (%x.%x.%04x): halt on io_region\n", - mdev_uuid(mdev), schid.cssid, + "sch %x.%x.%04x: halt on io_region\n", + schid.cssid, schid.ssid, schid.sch_no); /* halt is handled via the async cmd region */ io_region->ret_code = -EOPNOTSUPP; goto err_out; } else if (scsw->cmd.fctl & SCSW_FCTL_CLEAR_FUNC) { VFIO_CCW_MSG_EVENT(2, - "%pUl (%x.%x.%04x): clear on io_region\n", - mdev_uuid(mdev), schid.cssid, + "sch %x.%x.%04x: clear on io_region\n", + schid.cssid, schid.ssid, schid.sch_no); /* clear is handled via the async cmd region */ io_region->ret_code = -EOPNOTSUPP; diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index b49e2e9db2dc..0e05bff78b8e 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -131,8 +131,8 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev) private->mdev = mdev; private->state = VFIO_CCW_STATE_IDLE;
- VFIO_CCW_MSG_EVENT(2, "mdev %pUl, sch %x.%x.%04x: create\n", - mdev_uuid(mdev), private->sch->schid.cssid, + VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: create\n", + private->sch->schid.cssid, private->sch->schid.ssid, private->sch->schid.sch_no);
@@ -154,8 +154,8 @@ static void vfio_ccw_mdev_remove(struct mdev_device *mdev) { struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
- VFIO_CCW_MSG_EVENT(2, "mdev %pUl, sch %x.%x.%04x: remove\n", - mdev_uuid(mdev), private->sch->schid.cssid, + VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: remove\n", + private->sch->schid.cssid, private->sch->schid.ssid, private->sch->schid.sch_no);
diff --git a/include/linux/mdev.h b/include/linux/mdev.h index bb539794f54a..47ad3b104d9e 100644 --- a/include/linux/mdev.h +++ b/include/linux/mdev.h @@ -65,11 +65,6 @@ struct mdev_driver { struct device_driver driver; };
-static inline const guid_t *mdev_uuid(struct mdev_device *mdev) -{ - return &mdev->uuid; -} - extern struct bus_type mdev_bus_type;
int mdev_register_device(struct device *dev, struct mdev_driver *mdev_driver);
From: Eric Farman farman@linux.ibm.com
[ Upstream commit f6c876d67e956de8d69349b0ee43bc7277c09e5c ]
The FSM is in STANDBY state when arriving in vfio_ccw_mdev_probe(), and this routine converts it to IDLE as part of its processing. The error exit sets it to IDLE (again) but clears the private->mdev pointer.
The FSM should of course be managing the state itself, but the correct thing for vfio_ccw_mdev_probe() to do would be to put the state back the way it found it.
The corresponding check of private->mdev in vfio_ccw_sch_io_todo() can be removed, since the distinction is unnecessary at this point.
Fixes: 3bf1311f351ef ("vfio/ccw: Convert to use vfio_register_emulated_iommu_dev()") Signed-off-by: Eric Farman farman@linux.ibm.com Reviewed-by: Jason Gunthorpe jgg@nvidia.com Reviewed-by: Matthew Rosato mjrosato@linux.ibm.com Link: https://lore.kernel.org/r/20220707135737.720765-3-farman@linux.ibm.com Signed-off-by: Alex Williamson alex.williamson@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/cio/vfio_ccw_drv.c | 5 +++-- drivers/s390/cio/vfio_ccw_ops.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 35055eb94115..179eb614fa5b 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -106,9 +106,10 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work) /* * Reset to IDLE only if processing of a channel program * has finished. Do not overwrite a possible processing - * state if the final interrupt was for HSCH or CSCH. + * state if the interrupt was unsolicited, or if the final + * interrupt was for HSCH or CSCH. */ - if (private->mdev && cp_is_finished) + if (cp_is_finished) private->state = VFIO_CCW_STATE_IDLE;
if (private->io_trigger) diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 0e05bff78b8e..9a05dadcbb75 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -146,7 +146,7 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev) vfio_uninit_group_dev(&private->vdev); atomic_inc(&private->avail); private->mdev = NULL; - private->state = VFIO_CCW_STATE_IDLE; + private->state = VFIO_CCW_STATE_STANDBY; return ret; }
From: Eric Farman farman@linux.ibm.com
[ Upstream commit cffcc109fd682075dee79bade3d60a07152a8fd1 ]
The routine vfio_ccw_sch_event() is tasked with handling subchannel events, specifically machine checks, on behalf of vfio-ccw. It correctly calls cio_update_schib(), and if that fails (meaning the subchannel is gone) it makes an FSM event call to mark the subchannel Not Operational.
If that worked, however, then it decides that if the FSM state was already Not Operational (implying the subchannel just came back), then it should simply change the FSM to partially- or fully-open.
Remove this trickery, since a subchannel returning will require more probing than simply "oh all is well again" to ensure it works correctly.
Fixes: bbe37e4cb8970 ("vfio: ccw: introduce a finite state machine") Signed-off-by: Eric Farman farman@linux.ibm.com Reviewed-by: Matthew Rosato mjrosato@linux.ibm.com Link: https://lore.kernel.org/r/20220707135737.720765-4-farman@linux.ibm.com Signed-off-by: Alex Williamson alex.williamson@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/cio/vfio_ccw_drv.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 179eb614fa5b..279ad2161f17 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -301,19 +301,11 @@ static int vfio_ccw_sch_event(struct subchannel *sch, int process) if (work_pending(&sch->todo_work)) goto out_unlock;
- if (cio_update_schib(sch)) { - vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER); - rc = 0; - goto out_unlock; - } - - private = dev_get_drvdata(&sch->dev); - if (private->state == VFIO_CCW_STATE_NOT_OPER) { - private->state = private->mdev ? VFIO_CCW_STATE_IDLE : - VFIO_CCW_STATE_STANDBY; - } rc = 0;
+ if (cio_update_schib(sch)) + vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER); + out_unlock: spin_unlock_irqrestore(sch->lock, flags);
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
[ Upstream commit 817a62108dfacebd548e38451bf0e7eee023e97f ]
Audio Graph Card2 is using of_get_property(), but it should use of_property_read_u32() to getting rate. Otherwise the setting will be strange value. This patch fixup it.
Fixes: c3a15c92a67b701 ("ASoC: audio-graph-card2: add Codec2Codec support") Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/87h741s961.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/generic/audio-graph-card2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index d34b29a49268..8e0628e6f2a0 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -856,7 +856,7 @@ int audio_graph2_link_c2c(struct asoc_simple_priv *priv, struct device_node *port0, *port1, *ports; struct device_node *codec0_port, *codec1_port; struct device_node *ep0, *ep1; - u32 val; + u32 val = 0; int ret = -EINVAL;
/* @@ -880,7 +880,8 @@ int audio_graph2_link_c2c(struct asoc_simple_priv *priv, ports = of_get_parent(port0); port1 = of_get_next_child(ports, lnk);
- if (!of_get_property(ports, "rate", &val)) { + of_property_read_u32(ports, "rate", &val); + if (!val) { struct device *dev = simple_priv_to_dev(priv);
dev_err(dev, "Codec2Codec needs rate settings\n");
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 9d3aaceb73acadf134596a2f8db9c451c1332d3d ]
Some Freescale 8250 implementations have the problem that a single long break results in one irq per character frame time. The code in fsl8250_handle_irq() that is supposed to handle that uses the BI bit in lsr_saved_flags to detect such a situation and then skip the second received character. However it also stores other error bits and so after a single frame error the character received in the next irq handling is passed to the upper layer with a frame error, too.
So after a spike on the data line (which is correctly recognized as a frame error) the following valid character is thrown away, because the driver reports a frame error for that one, too.
To weaken this problem restrict saving LSR to only the BI bit.
Note however that the handling is still broken:
- lsr_saved_flags is updated using orig_lsr which is the LSR content for the first received char, but there might be more in the FIFO, so a character is thrown away that is received later and not necessarily the one following the break. - The doubled break might be the 2nd and 3rd char in the FIFO, so the workaround doesn't catch these, because serial8250_rx_chars() doesn't handle the workaround. - lsr_saved_flags might have set UART_LSR_BI at the entry of fsl8250_handle_irq() which doesn't originate from fsl8250_handle_irq()'s "up->lsr_saved_flags |= orig_lsr & UART_LSR_BI;" but from e.g. from serial8250_tx_empty(). - For a long or a short break this isn't about two characters, but more or only a single one.
Fixes: 9deaa53ac7fa ("serial: add irq handler for Freescale 16550 errata.") Acked-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Link: https://lore.kernel.org/r/20220704085119.55900-1-u.kleine-koenig@pengutronix... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_fsl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c index 9c01c531349d..71ce43685797 100644 --- a/drivers/tty/serial/8250/8250_fsl.c +++ b/drivers/tty/serial/8250/8250_fsl.c @@ -77,7 +77,7 @@ int fsl8250_handle_irq(struct uart_port *port) if ((lsr & UART_LSR_THRE) && (up->ier & UART_IER_THRI)) serial8250_tx_chars(up);
- up->lsr_saved_flags = orig_lsr; + up->lsr_saved_flags |= orig_lsr & UART_LSR_BI;
uart_unlock_and_check_sysrq_irqrestore(&up->port, flags);
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit f30e10caa80aa1f35508bc17fc302dbbde9a833c ]
n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.a... The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to the newer 27.010 here. Chapter 5.7.3 states that the valid range for the maximum number of retransmissions (N2) is from 0 to 255 (both including). gsm_dlci_t1() handles this number incorrectly by performing N2 - 1 retransmission attempts. Setting N2 to zero results in more than 255 retransmission attempts. Fix gsm_dlci_t1() to comply with 3GPP 27.010.
Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220707113223.3685-1-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index ba399a660573..1a70e7ae90cc 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1805,8 +1805,8 @@ static void gsm_dlci_t1(struct timer_list *t)
switch (dlci->state) { case DLCI_OPENING: - dlci->retries--; if (dlci->retries) { + dlci->retries--; gsm_command(dlci->gsm, dlci->addr, SABM|PF); mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); } else if (!dlci->addr && gsm->control == (DM | PF)) { @@ -1821,8 +1821,8 @@ static void gsm_dlci_t1(struct timer_list *t)
break; case DLCI_CLOSING: - dlci->retries--; if (dlci->retries) { + dlci->retries--; gsm_command(dlci->gsm, dlci->addr, DISC|PF); mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); } else
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit 18a948c7d90995d127785e308fa7b701df4c499f ]
n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.a... The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to the newer 27.010 here. Chapter 5.3.3 defines the DM response. There exists no DM command. However, the current implementation incorrectly sends DM as command in case of unexpected UIH frames in gsm_queue(). Correct this behavior by always sending DM as response.
Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220707113223.3685-2-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 1a70e7ae90cc..90060018928f 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2207,7 +2207,7 @@ static void gsm_queue(struct gsm_mux *gsm) case UIH: case UIH|PF: if (dlci == NULL || dlci->state != DLCI_OPEN) { - gsm_command(gsm, address, DM|PF); + gsm_response(gsm, address, DM|PF); return; } dlci->data(dlci, gsm->buf, gsm->len);
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit 59ff0680ecbfec742b1e0381e7cc46b41eb06647 ]
The current implementation constipates all transmission paths during flow control except for flow control frames. However, these may not be located at the beginning of the transmission queue of the control channel. Ensure that flow control frames in the transmission queue for the control channel are always handled even if constipated by skipping through other messages.
Fixes: 0af021678d5d ("tty: n_gsm: fix deadlock and link starvation in outgoing data path") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220707113223.3685-3-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 90060018928f..51447ccccbab 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -891,7 +891,7 @@ static int gsm_data_kick(struct gsm_mux *gsm) /* Serialize control messages and control channel messages first */ list_for_each_entry_safe(msg, nmsg, &gsm->tx_ctrl_list, list) { if (gsm->constipated && !gsm_is_flow_ctrl_msg(msg)) - return -EAGAIN; + continue; ret = gsm_send_packet(gsm, msg); switch (ret) { case -ENOSPC:
From: Daniel Starke daniel.starke@siemens.com
[ Upstream commit 7e5b4322cde067e1d0f1bf8f490e93f664a7c843 ]
gsmld_poll() currently fails to handle the following corner cases correctly: - remote party closed the associated tty
Add the missing checks and map those to EPOLLHUP. Reorder the checks to group them by their reaction.
Fixes: e1eaea46bb40 ("tty: n_gsm line discipline") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220707113223.3685-4-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 51447ccccbab..caa5c14ed57f 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3053,12 +3053,15 @@ static __poll_t gsmld_poll(struct tty_struct *tty, struct file *file,
poll_wait(file, &tty->read_wait, wait); poll_wait(file, &tty->write_wait, wait); + + if (gsm->dead) + mask |= EPOLLHUP; if (tty_hung_up_p(file)) mask |= EPOLLHUP; + if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) + mask |= EPOLLHUP; if (!tty_is_writelocked(tty) && tty_write_room(tty) > 0) mask |= EPOLLOUT | EPOLLWRNORM; - if (gsm->dead) - mask |= EPOLLHUP; return mask; }
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit 8baa65126e19af5ee9f3c07e7bb53da41c39e4b1 ]
The GIC user offset is mapped into every process' virtual address and is therefore part of the hot-path of arch_setup_additional_pages(). Utilize __pa() such that we are more optimal even when CONFIG_DEBUG_VIRTUAL is enabled, and while at it utilize PFN_DOWN() instead of open-coding the right shift by PAGE_SHIFT.
Reported-by: Greg Ungerer gerg@kernel.org Suggested-by: Serge Semin fancer.lancer@gmail.com Fixes: dfad83cb7193 ("MIPS: Add support for CONFIG_DEBUG_VIRTUAL") Signed-off-by: Florian Fainelli f.fainelli@gmail.com Acked-by: Greg Ungerer gerg@kernel.org Tested-by: Greg Ungerer gerg@kernel.org Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/kernel/vdso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 3d0cf471f2fe..b2cc2c2dd4bf 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c @@ -159,7 +159,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) /* Map GIC user page. */ if (gic_size) { gic_base = (unsigned long)mips_gic_base + MIPS_GIC_USER_OFS; - gic_pfn = virt_to_phys((void *)gic_base) >> PAGE_SHIFT; + gic_pfn = PFN_DOWN(__pa(gic_base));
ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size, pgprot_noncached(vma->vm_page_prot));
From: YC Hung yc.hung@mediatek.com
[ Upstream commit 99bad468846f7a255dcfc95454401c83ae02e89b ]
Fix StatVectorSel wrong setting.
Fixes: b7f6503830 ("ASoC: SOF: mediatek: Add fw loader and mt8195 dsp ops to load firmware") Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: YC Hung yc.hung@mediatek.com Reviewed-by: Li-Yu Yu afg984@gmail.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: KuanHsun Cheng Allen-KH.Cheng@mediatek.com Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com Link: https://lore.kernel.org/r/20220708203904.29214-3-pierre-louis.bossart@linux.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sof/mediatek/mt8195/mt8195-loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/sof/mediatek/mt8195/mt8195-loader.c b/sound/soc/sof/mediatek/mt8195/mt8195-loader.c index ed18d6379e92..ef2664c3cd47 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195-loader.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195-loader.c @@ -21,7 +21,7 @@ void sof_hifixdsp_boot_sequence(struct snd_sof_dev *sdev, u32 boot_addr)
/* pull high StatVectorSel to use AltResetVec (set bit4 to 1) */ snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, DSP_RESET_SW, - DSP_RESET_SW, DSP_RESET_SW); + STATVECTOR_SEL, STATVECTOR_SEL);
/* toggle DReset & BReset */ /* pull high DReset & BReset */
From: Robin Murphy robin.murphy@arm.com
[ Upstream commit c51ba246cb172c9e947dc6fb8868a1eaf0b2a913 ]
In the failure case of trying to use a buffer which we'd previously failed to allocate, the "!mem" condition is no longer sufficient since io_tlb_default_mem became static and assigned by default. Update the condition to work as intended per the rest of that conversion.
Fixes: 463e862ac63e ("swiotlb: Convert io_default_tlb_mem to static allocation") Signed-off-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/dma/swiotlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index cb50f8d38360..5830dce6081b 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -580,7 +580,7 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr, int index; phys_addr_t tlb_addr;
- if (!mem) + if (!mem || !mem->nslabs) panic("Can not allocate SWIOTLB buffer earlier and can't now provide you with the DMA bounce buffer");
if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
From: Alexander Lobakin alexandr.lobakin@intel.com
[ Upstream commit 428bc098635680a664779f26f24fe9197d186172 ]
GENMASK*() family takes the first and the last bits of the mask *including* them. So, with the current code bitmap_to_arr64() doesn't clear the tail properly:
nbits % exp mask must be 1 GENMASK(1, 0) 0x3 0x1 ... 63 GENMASK(63, 0) 0xffffffffffffffff 0x7fffffffffffffff
This was found by making the function always available instead of 32-bit BE systems only (for reusing in some new functionality). Turn the number of bits into the last bit set by subtracting 1. @nbits is already checked to be positive beforehand.
Fixes: 0a97953fd221 ("lib: add bitmap_{from,to}_arr64") Signed-off-by: Alexander Lobakin alexandr.lobakin@intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Yury Norov yury.norov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- lib/bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/bitmap.c b/lib/bitmap.c index b18e31ea6e66..e903e13c62e1 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -1564,7 +1564,7 @@ void bitmap_to_arr64(u64 *buf, const unsigned long *bitmap, unsigned int nbits)
/* Clear tail bits in the last element of array beyond nbits. */ if (nbits % 64) - buf[-1] &= GENMASK_ULL(nbits % 64, 0); + buf[-1] &= GENMASK_ULL((nbits - 1) % 64, 0); } EXPORT_SYMBOL(bitmap_to_arr64); #endif
From: Peter Ujfalusi peter.ujfalusi@linux.intel.com
[ Upstream commit d5bd47f3ca124058a8e87eae4508afeda2132611 ]
We have sanity checks for byte controls and if any of the fail the locally allocated scontrol->ipc_control_data is freed up, but not set to NULL.
On a rollback path of the error the higher level code will also try to free the scontrol->ipc_control_data which will eventually going to lead to memory corruption as double freeing memory is not a good thing.
Fixes: b5cee8feb1d4 ("ASoC: SOF: topology: Make control parsing IPC agnostic") Reported-by: Seppo Ingalsuo seppo.ingalsuo@linux.intel.com Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Seppo Ingalsuo seppo.ingalsuo@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20220712130103.31514-1-peter.ujfalusi@linux.intel.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sof/ipc3-topology.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 10740c55294d..e97f50d5bcba 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -1628,6 +1628,7 @@ static int sof_ipc3_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_ return 0; err: kfree(scontrol->ipc_control_data); + scontrol->ipc_control_data = NULL; return ret; }
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 72d67d6b3447303a441a8cedc34f7224b75f64b5 ]
If regulator_get_voltage() fails, it should return the error code in mtk_cpu_dvfs_info_init().
Fixes: 0daa47325bae ("cpufreq: mediatek: Link CCI device to CPU") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Rex-BC Chen rex-bc.chen@mediatek.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/mediatek-cpufreq.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 76f6b3884e6b..7f2680bc9a0f 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -478,6 +478,7 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) if (info->soc_data->ccifreq_supported) { info->vproc_on_boot = regulator_get_voltage(info->proc_reg); if (info->vproc_on_boot < 0) { + ret = info->vproc_on_boot; dev_err(info->cpu_dev, "invalid Vproc value: %d\n", info->vproc_on_boot); goto out_disable_inter_clock;
From: Liang He windhl@126.com
[ Upstream commit eda26893dabfc6da7a1e1ff5f8628ed9faab3ab9 ]
We should call of_node_put() for the reference before its replacement as it returned by of_get_parent() which has increased the refcount. Besides, we should also call of_node_put() before return.
Fixes: c8c74939f791 ("ASoC: audio-graph-card2: add Multi CPU/Codec support") Signed-off-by: Liang He windhl@126.com Link: https://lore.kernel.org/r/20220713071200.366729-1-windhl@126.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/generic/audio-graph-card2.c | 35 +++++++++++++++++++-------- 1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 8e0628e6f2a0..5dba7c89007d 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -229,7 +229,8 @@ enum graph_type {
static enum graph_type __graph_get_type(struct device_node *lnk) { - struct device_node *np; + struct device_node *np, *parent_np; + enum graph_type ret;
/* * target { @@ -240,19 +241,33 @@ static enum graph_type __graph_get_type(struct device_node *lnk) * }; */ np = of_get_parent(lnk); - if (of_node_name_eq(np, "ports")) - np = of_get_parent(np); + if (of_node_name_eq(np, "ports")) { + parent_np = of_get_parent(np); + of_node_put(np); + np = parent_np; + }
- if (of_node_name_eq(np, GRAPH_NODENAME_MULTI)) - return GRAPH_MULTI; + if (of_node_name_eq(np, GRAPH_NODENAME_MULTI)) { + ret = GRAPH_MULTI; + goto out_put; + }
- if (of_node_name_eq(np, GRAPH_NODENAME_DPCM)) - return GRAPH_DPCM; + if (of_node_name_eq(np, GRAPH_NODENAME_DPCM)) { + ret = GRAPH_DPCM; + goto out_put; + }
- if (of_node_name_eq(np, GRAPH_NODENAME_C2C)) - return GRAPH_C2C; + if (of_node_name_eq(np, GRAPH_NODENAME_C2C)) { + ret = GRAPH_C2C; + goto out_put; + } + + ret = GRAPH_NORMAL; + +out_put: + of_node_put(np); + return ret;
- return GRAPH_NORMAL; }
static enum graph_type graph_get_type(struct asoc_simple_priv *priv,
From: Liang He windhl@126.com
[ Upstream commit a8d5df69e2ec702d979f7d04ed519caf8691a032 ]
In mt6359_parse_dt() and mt6359_accdet_parse_dt(), we should call of_node_put() for the reference returned by of_get_child_by_name() which has increased the refcount.
Fixes: 683530285316 ("ASoC: mt6359: fix failed to parse DT properties") Fixes: eef07b9e0925 ("ASoC: mediatek: mt6359: add MT6359 accdet jack driver") Signed-off-by: Liang He windhl@126.com Link: https://lore.kernel.org/r/20220713102013.367336-1-windhl@126.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/mt6359-accdet.c | 1 + sound/soc/codecs/mt6359.c | 1 + 2 files changed, 2 insertions(+)
diff --git a/sound/soc/codecs/mt6359-accdet.c b/sound/soc/codecs/mt6359-accdet.c index 6d3d170144a0..c190628e2905 100644 --- a/sound/soc/codecs/mt6359-accdet.c +++ b/sound/soc/codecs/mt6359-accdet.c @@ -675,6 +675,7 @@ static int mt6359_accdet_parse_dt(struct mt6359_accdet *priv) sizeof(struct three_key_threshold)); }
+ of_node_put(node); dev_warn(priv->dev, "accdet caps=%x\n", priv->caps);
return 0; diff --git a/sound/soc/codecs/mt6359.c b/sound/soc/codecs/mt6359.c index 23709b180409..c9a453ce8a2a 100644 --- a/sound/soc/codecs/mt6359.c +++ b/sound/soc/codecs/mt6359.c @@ -2778,6 +2778,7 @@ static int mt6359_parse_dt(struct mt6359_priv *priv)
ret = of_property_read_u32(np, "mediatek,mic-type-2", &priv->mux_select[MUX_MIC_TYPE_2]); + of_node_put(np); if (ret) { dev_info(priv->dev, "%s() failed to read mic-type-2, use default (%d)\n",
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit fa9b878ff86f4adccddf62492a5894fbdb04f97d ]
There are two bugs that have to do with when we copy the payload:
size = simple_write_to_buffer(ipc4_msg->data_ptr, priv->max_msg_size, ppos, buffer, count);
The value of "*ppos" was supposed to be zero but it is sizeof(ipc4_msg->header_u64) so it will copy the data into the middle of the "ipc4_msg->data_ptr" buffer instead of to the start. The second problem is "buffer" should be "buffer + sizeof(ipc4_msg->header_u64)".
This function is used for fuzz testing so the data is normally random and this bug likely does not affect anyone very much.
In this context, it's simpler and more appropriate to use copy_from_user() instead of simple_write_to_buffer() so I have re-written the function.
Fixes: 066c67624d8c ("ASoC: SOF: ipc-msg-injector: Add support for IPC4 messages") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/Ysg1tB2FKLnRMsel@kili Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sof/sof-client-ipc-msg-injector.c | 29 +++++++++------------ 1 file changed, 12 insertions(+), 17 deletions(-)
diff --git a/sound/soc/sof/sof-client-ipc-msg-injector.c b/sound/soc/sof/sof-client-ipc-msg-injector.c index 6bdfa527b7f7..752d5320680f 100644 --- a/sound/soc/sof/sof-client-ipc-msg-injector.c +++ b/sound/soc/sof/sof-client-ipc-msg-injector.c @@ -181,7 +181,7 @@ static ssize_t sof_msg_inject_ipc4_dfs_write(struct file *file, struct sof_client_dev *cdev = file->private_data; struct sof_msg_inject_priv *priv = cdev->data; struct sof_ipc4_msg *ipc4_msg = priv->tx_buffer; - ssize_t size; + size_t data_size; int ret;
if (*ppos) @@ -191,25 +191,20 @@ static ssize_t sof_msg_inject_ipc4_dfs_write(struct file *file, return -EINVAL;
/* copy the header first */ - size = simple_write_to_buffer(&ipc4_msg->header_u64, - sizeof(ipc4_msg->header_u64), - ppos, buffer, count); - if (size < 0) - return size; - if (size != sizeof(ipc4_msg->header_u64)) + if (copy_from_user(&ipc4_msg->header_u64, buffer, + sizeof(ipc4_msg->header_u64))) return -EFAULT;
- count -= size; + data_size = count - sizeof(ipc4_msg->header_u64); + if (data_size > priv->max_msg_size) + return -EINVAL; + /* Copy the payload */ - size = simple_write_to_buffer(ipc4_msg->data_ptr, - priv->max_msg_size, ppos, buffer, - count); - if (size < 0) - return size; - if (size != count) + if (copy_from_user(ipc4_msg->data_ptr, + buffer + sizeof(ipc4_msg->header_u64), data_size)) return -EFAULT;
- ipc4_msg->data_size = count; + ipc4_msg->data_size = data_size;
/* Initialize the reply storage */ ipc4_msg = priv->rx_buffer; @@ -221,9 +216,9 @@ static ssize_t sof_msg_inject_ipc4_dfs_write(struct file *file,
/* return the error code if test failed */ if (ret < 0) - size = ret; + return ret;
- return size; + return count; };
static int sof_msg_inject_dfs_release(struct inode *inode, struct file *file)
From: Doug Berger opendmb@gmail.com
[ Upstream commit 3182efd036c1b955403d131258234896cbd9fbeb ]
Commit 9cabe26e65a8 ("serial: 8250_bcm7271: UART errors after resuming from S2") prevented an early enabling of RTS during resume, but it did not actively restore the RTS state after resume.
Fixes: 9cabe26e65a8 ("serial: 8250_bcm7271: UART errors after resuming from S2") Signed-off-by: Doug Berger opendmb@gmail.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Link: https://lore.kernel.org/r/20220714031316.404918-1-f.fainelli@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_bcm7271.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c index 9b878d023dac..8efdc271eb75 100644 --- a/drivers/tty/serial/8250/8250_bcm7271.c +++ b/drivers/tty/serial/8250/8250_bcm7271.c @@ -1139,16 +1139,19 @@ static int __maybe_unused brcmuart_suspend(struct device *dev) struct brcmuart_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = serial8250_get_port(priv->line); struct uart_port *port = &up->port; - - serial8250_suspend_port(priv->line); - clk_disable_unprepare(priv->baud_mux_clk); + unsigned long flags;
/* * This will prevent resume from enabling RTS before the - * baud rate has been resored. + * baud rate has been restored. */ + spin_lock_irqsave(&port->lock, flags); priv->saved_mctrl = port->mctrl; - port->mctrl = 0; + port->mctrl &= ~TIOCM_RTS; + spin_unlock_irqrestore(&port->lock, flags); + + serial8250_suspend_port(priv->line); + clk_disable_unprepare(priv->baud_mux_clk);
return 0; } @@ -1158,6 +1161,7 @@ static int __maybe_unused brcmuart_resume(struct device *dev) struct brcmuart_priv *priv = dev_get_drvdata(dev); struct uart_8250_port *up = serial8250_get_port(priv->line); struct uart_port *port = &up->port; + unsigned long flags; int ret;
ret = clk_prepare_enable(priv->baud_mux_clk); @@ -1180,7 +1184,15 @@ static int __maybe_unused brcmuart_resume(struct device *dev) start_rx_dma(serial8250_get_port(priv->line)); } serial8250_resume_port(priv->line); - port->mctrl = priv->saved_mctrl; + + if (priv->saved_mctrl & TIOCM_RTS) { + /* Restore RTS */ + spin_lock_irqsave(&port->lock, flags); + port->mctrl |= TIOCM_RTS; + port->ops->set_mctrl(port, port->mctrl); + spin_unlock_irqrestore(&port->lock, flags); + } + return 0; }
From: Sam Protsenko semen.protsenko@linaro.org
[ Upstream commit fce398d2d02c0a9a2bedf7c7201b123e153e8963 ]
If iommu_device_register() fails in exynos_sysmmu_probe(), the previous calls have to be cleaned up. In this case, the iommu_device_sysfs_add() should be cleaned up, by calling its remove counterpart call.
Fixes: d2c302b6e8b1 ("iommu/exynos: Make use of iommu_device_register interface") Signed-off-by: Sam Protsenko semen.protsenko@linaro.org Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Acked-by: Marek Szyprowski m.szyprowski@samsung.com Link: https://lore.kernel.org/r/20220714165550.8884-3-semen.protsenko@linaro.org Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/exynos-iommu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 71f2018e23fe..cd4b889d5537 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -630,7 +630,7 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
ret = iommu_device_register(&data->iommu, &exynos_iommu_ops, dev); if (ret) - return ret; + goto err_iommu_register;
platform_set_drvdata(pdev, data);
@@ -657,6 +657,10 @@ static int exynos_sysmmu_probe(struct platform_device *pdev) pm_runtime_enable(dev);
return 0; + +err_iommu_register: + iommu_device_sysfs_remove(&data->iommu); + return ret; }
static int __maybe_unused exynos_sysmmu_suspend(struct device *dev)
From: Kent Overstreet kent.overstreet@gmail.com
[ Upstream commit 6cda12864cb0f99810a5809e11e3ee5b102c9a47 ]
An upcoming patch is going to require passing the client through p9_req_put() -> p9_req_free(), but that's awkward with the kref indirection - so this patch switches to using refcount_t directly.
Link: https://lkml.kernel.org/r/20220704014243.153050-1-kent.overstreet@gmail.com Signed-off-by: Kent Overstreet kent.overstreet@gmail.com Cc: Eric Van Hensbergen ericvh@gmail.com Cc: Latchesar Ionkov lucho@ionkov.net Signed-off-by: Dominique Martinet asmadeus@codewreck.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/9p/client.h | 6 +++--- net/9p/client.c | 19 ++++++++----------- 2 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/include/net/9p/client.h b/include/net/9p/client.h index ec1d1706f43c..c038c2d73dae 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -76,7 +76,7 @@ enum p9_req_status_t { struct p9_req_t { int status; int t_err; - struct kref refcount; + refcount_t refcount; wait_queue_head_t wq; struct p9_fcall tc; struct p9_fcall rc; @@ -227,12 +227,12 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag);
static inline void p9_req_get(struct p9_req_t *r) { - kref_get(&r->refcount); + refcount_inc(&r->refcount); }
static inline int p9_req_try_get(struct p9_req_t *r) { - return kref_get_unless_zero(&r->refcount); + return refcount_inc_not_zero(&r->refcount); }
int p9_req_put(struct p9_req_t *r); diff --git a/net/9p/client.c b/net/9p/client.c index 8bba0d9cf975..0ee48e8b7220 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -305,7 +305,7 @@ p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size) * callback), so p9_client_cb eats the second ref there * as the pointer is duplicated directly by virtqueue_add_sgs() */ - refcount_set(&req->refcount.refcount, 2); + refcount_set(&req->refcount, 2);
return req;
@@ -370,18 +370,15 @@ static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r) return p9_req_put(r); }
-static void p9_req_free(struct kref *ref) -{ - struct p9_req_t *r = container_of(ref, struct p9_req_t, refcount); - - p9_fcall_fini(&r->tc); - p9_fcall_fini(&r->rc); - kmem_cache_free(p9_req_cache, r); -} - int p9_req_put(struct p9_req_t *r) { - return kref_put(&r->refcount, p9_req_free); + if (refcount_dec_and_test(&r->refcount)) { + p9_fcall_fini(&r->tc); + p9_fcall_fini(&r->rc); + kmem_cache_free(p9_req_cache, r); + return 1; + } + return 0; } EXPORT_SYMBOL(p9_req_put);
From: Kent Overstreet kent.overstreet@gmail.com
[ Upstream commit 8b11ff098af42b1fa57fc817daadd53c8b244a0c ]
This is to aid in adding mempools, in the next patch.
Link: https://lkml.kernel.org/r/20220704014243.153050-2-kent.overstreet@gmail.com Signed-off-by: Kent Overstreet kent.overstreet@gmail.com Cc: Eric Van Hensbergen ericvh@gmail.com Cc: Latchesar Ionkov lucho@ionkov.net Signed-off-by: Dominique Martinet asmadeus@codewreck.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/9p/client.h | 2 +- net/9p/client.c | 12 ++++++------ net/9p/trans_fd.c | 12 ++++++------ net/9p/trans_rdma.c | 2 +- net/9p/trans_virtio.c | 4 ++-- net/9p/trans_xen.c | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/include/net/9p/client.h b/include/net/9p/client.h index c038c2d73dae..cb78e0e33332 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -235,7 +235,7 @@ static inline int p9_req_try_get(struct p9_req_t *r) return refcount_inc_not_zero(&r->refcount); }
-int p9_req_put(struct p9_req_t *r); +int p9_req_put(struct p9_client *c, struct p9_req_t *r);
void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status);
diff --git a/net/9p/client.c b/net/9p/client.c index 0ee48e8b7220..a36a40137caa 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -341,7 +341,7 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag) if (!p9_req_try_get(req)) goto again; if (req->tc.tag != tag) { - p9_req_put(req); + p9_req_put(c, req); goto again; } } @@ -367,10 +367,10 @@ static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r) spin_lock_irqsave(&c->lock, flags); idr_remove(&c->reqs, tag); spin_unlock_irqrestore(&c->lock, flags); - return p9_req_put(r); + return p9_req_put(c, r); }
-int p9_req_put(struct p9_req_t *r) +int p9_req_put(struct p9_client *c, struct p9_req_t *r) { if (refcount_dec_and_test(&r->refcount)) { p9_fcall_fini(&r->tc); @@ -423,7 +423,7 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
wake_up(&req->wq); p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag); - p9_req_put(req); + p9_req_put(c, req); } EXPORT_SYMBOL(p9_client_cb);
@@ -706,7 +706,7 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c, reterr: p9_tag_remove(c, req); /* We have to put also the 2nd reference as it won't be used */ - p9_req_put(req); + p9_req_put(c, req); return ERR_PTR(err); }
@@ -743,7 +743,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) err = c->trans_mod->request(c, req); if (err < 0) { /* write won't happen */ - p9_req_put(req); + p9_req_put(c, req); if (err != -ERESTARTSYS && err != -EFAULT) c->status = Disconnected; goto recalc_sigpending; diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 8f8f95e39b03..007c3f45fe05 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -378,7 +378,7 @@ static void p9_read_work(struct work_struct *work) m->rc.sdata = NULL; m->rc.offset = 0; m->rc.capacity = 0; - p9_req_put(m->rreq); + p9_req_put(m->client, m->rreq); m->rreq = NULL; }
@@ -492,7 +492,7 @@ static void p9_write_work(struct work_struct *work) m->wpos += err; if (m->wpos == m->wsize) { m->wpos = m->wsize = 0; - p9_req_put(m->wreq); + p9_req_put(m->client, m->wreq); m->wreq = NULL; }
@@ -695,7 +695,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req) if (req->status == REQ_STATUS_UNSENT) { list_del(&req->req_list); req->status = REQ_STATUS_FLSHD; - p9_req_put(req); + p9_req_put(client, req); ret = 0; } spin_unlock(&client->lock); @@ -722,7 +722,7 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) list_del(&req->req_list); req->status = REQ_STATUS_FLSHD; spin_unlock(&client->lock); - p9_req_put(req); + p9_req_put(client, req);
return 0; } @@ -883,12 +883,12 @@ static void p9_conn_destroy(struct p9_conn *m) p9_mux_poll_stop(m); cancel_work_sync(&m->rq); if (m->rreq) { - p9_req_put(m->rreq); + p9_req_put(m->client, m->rreq); m->rreq = NULL; } cancel_work_sync(&m->wq); if (m->wreq) { - p9_req_put(m->wreq); + p9_req_put(m->client, m->wreq); m->wreq = NULL; }
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 88e563826674..d817d3745238 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c @@ -350,7 +350,7 @@ send_done(struct ib_cq *cq, struct ib_wc *wc) c->busa, c->req->tc.size, DMA_TO_DEVICE); up(&rdma->sq_sem); - p9_req_put(c->req); + p9_req_put(client, c->req); kfree(c); }
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index b24a4fb0f0a2..147972bf2e79 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -199,7 +199,7 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req) /* Reply won't come, so drop req ref */ static int p9_virtio_cancelled(struct p9_client *client, struct p9_req_t *req) { - p9_req_put(req); + p9_req_put(client, req); return 0; }
@@ -523,7 +523,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, kvfree(out_pages); if (!kicked) { /* reply won't come */ - p9_req_put(req); + p9_req_put(client, req); } return err; } diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c index 833cd3792c51..227f89cc7237 100644 --- a/net/9p/trans_xen.c +++ b/net/9p/trans_xen.c @@ -163,7 +163,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req) ring->intf->out_prod = prod; spin_unlock_irqrestore(&ring->lock, flags); notify_remote_via_irq(ring->irq); - p9_req_put(p9_req); + p9_req_put(client, p9_req);
return 0; }
From: Hangyu Hua hbh25y@gmail.com
[ Upstream commit 4ac7573e1f9333073fa8d303acc941c9b7ab7f61 ]
p9_req_put need to be called when m->rreq->rc.sdata is NULL to avoid temporary refcount leak.
Link: https://lkml.kernel.org/r/20220712104438.30800-1-hbh25y@gmail.com Fixes: 728356dedeff ("9p: Add refcount to p9_req_t") Signed-off-by: Hangyu Hua hbh25y@gmail.com [Dominique: commit wording adjustments, p9_req_put argument fixes for rebase] Signed-off-by: Dominique Martinet asmadeus@codewreck.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/9p/trans_fd.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 007c3f45fe05..e758978b44be 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -343,6 +343,7 @@ static void p9_read_work(struct work_struct *work) p9_debug(P9_DEBUG_ERROR, "No recv fcall for tag %d (req %p), disconnecting!\n", m->rc.tag, m->rreq); + p9_req_put(m->client, m->rreq); m->rreq = NULL; err = -EIO; goto error;
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit 8a2b456665d1e797123669581524cbb095fb003b ]
It is permissible for kernel code to call virt_to_phys() against virtual addresses that are in KSEG0 or KSEG1 and we need to be dealing with both types. Rewrite the test condition to ensure that the kernel virtual addresses are above PAGE_OFFSET which they must be, and below KSEG2 where the non-linear mapping starts.
For EVA, there is not much that we can do given the linear address range that is offered, so just return any virtual address as being valid.
Finally, when HIGHMEM is not enabled, all virtual addresses are assumed to be valid as well.
Fixes: dfad83cb7193 ("MIPS: Add support for CONFIG_DEBUG_VIRTUAL") Signed-off-by: Florian Fainelli f.fainelli@gmail.com Reviewed-by: Serge Semin fancer.lancer@gmail.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/mm/physaddr.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/arch/mips/mm/physaddr.c b/arch/mips/mm/physaddr.c index a1ced5e44951..f9b8c85e9843 100644 --- a/arch/mips/mm/physaddr.c +++ b/arch/mips/mm/physaddr.c @@ -5,6 +5,7 @@ #include <linux/mmdebug.h> #include <linux/mm.h>
+#include <asm/addrspace.h> #include <asm/sections.h> #include <asm/io.h> #include <asm/page.h> @@ -12,15 +13,6 @@
static inline bool __debug_virt_addr_valid(unsigned long x) { - /* high_memory does not get immediately defined, and there - * are early callers of __pa() against PAGE_OFFSET - */ - if (!high_memory && x >= PAGE_OFFSET) - return true; - - if (high_memory && x >= PAGE_OFFSET && x < (unsigned long)high_memory) - return true; - /* * MAX_DMA_ADDRESS is a virtual address that may not correspond to an * actual physical address. Enough code relies on @@ -30,7 +22,9 @@ static inline bool __debug_virt_addr_valid(unsigned long x) if (x == MAX_DMA_ADDRESS) return true;
- return false; + return x >= PAGE_OFFSET && (KSEGX(x) < KSEG2 || + IS_ENABLED(CONFIG_EVA) || + !IS_ENABLED(CONFIG_HIGHMEM)); }
phys_addr_t __virt_to_phys(volatile const void *x)
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 65382585f067d4256ba087934f30f85c9b6984de ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when done.
Fixes: 53e2822e56c7 ("rpmsg: Introduce Qualcomm SMD backend") Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220511120737.57374-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rpmsg/qcom_smd.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index 1957b27c4cf3..f7af53891ef9 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -1383,6 +1383,7 @@ static int qcom_smd_parse_edge(struct device *dev, }
edge->ipc_regmap = syscon_node_to_regmap(syscon_np); + of_node_put(syscon_np); if (IS_ERR(edge->ipc_regmap)) { ret = PTR_ERR(edge->ipc_regmap); goto put_node;
From: Emil Renner Berthing emil.renner.berthing@canonical.com
[ Upstream commit 399e7aa82105ea46d8998fa535b047541c48030f ]
When requesting a PWM it might return -EPROBE_DEFER if it hasn't probed yet. This is not an error, so just propagate the -EPROBE_DEFER without logging anything. There is already dev_err_probe for exactly this situation.
Fixes: 9fa2762110dd ("leds: Add PWM multicolor driver") Signed-off-by: Emil Renner Berthing emil.renner.berthing@canonical.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Pavel Machek pavel@ucw.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/leds/rgb/leds-pwm-multicolor.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/leds/rgb/leds-pwm-multicolor.c b/drivers/leds/rgb/leds-pwm-multicolor.c index 45e38708ecb1..eb67b89d28e9 100644 --- a/drivers/leds/rgb/leds-pwm-multicolor.c +++ b/drivers/leds/rgb/leds-pwm-multicolor.c @@ -72,8 +72,7 @@ static int iterate_subleds(struct device *dev, struct pwm_mc_led *priv, pwmled = &priv->leds[priv->mc_cdev.num_colors]; pwmled->pwm = devm_fwnode_pwm_get(dev, fwnode, NULL); if (IS_ERR(pwmled->pwm)) { - ret = PTR_ERR(pwmled->pwm); - dev_err(dev, "unable to request PWM: %d\n", ret); + ret = dev_err_probe(dev, PTR_ERR(pwmled->pwm), "unable to request PWM\n"); goto release_fwnode; } pwm_init_state(pwmled->pwm, &pwmled->state);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 045ed31e23aea840648c290dbde04797064960db ]
The kfifo_to_user() macro is supposed to return zero for success or negative error codes. Unfortunately, there is a signedness bug so it returns unsigned int. This only affects callers which try to save the result in ssize_t and as far as I can see the only place which does that is line6_hwdep_read().
TL;DR: s/_uint/_int/.
Link: https://lkml.kernel.org/r/YrVL3OJVLlNhIMFs@kili Fixes: 144ecf310eb5 ("kfifo: fix kfifo_alloc() to return a signed int value") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Cc: Stefani Seibold stefani@seibold.net Cc: Randy Dunlap randy.dunlap@oracle.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/kfifo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 86249476b57f..0b35a41440ff 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -688,7 +688,7 @@ __kfifo_uint_must_check_helper( \ * writer, you don't need extra locking to use these macro. */ #define kfifo_to_user(fifo, to, len, copied) \ -__kfifo_uint_must_check_helper( \ +__kfifo_int_must_check_helper( \ ({ \ typeof((fifo) + 1) __tmp = (fifo); \ void __user *__to = (to); \
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
[ Upstream commit bd27acaac24e4b252ee28dddcabaee80456d0faf ]
Currently instrumentation_end() won't be called if printk_ratelimit() returned false.
Link: https://lkml.kernel.org/r/a636d8e0-ad32-5888-acac-671f7f553bb3@I-love.SAKURA... Fixes: 126f21f0e8d46e2c ("lib/smp_processor_id: Move it into noinstr section") Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Cc: Thomas Gleixner tglx@linutronix.de Cc: Alexandre Chartre alexandre.chartre@oracle.com Cc: Peter Zijlstra peterz@infradead.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/smp_processor_id.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c index 046ac6297c78..a2bb7738c373 100644 --- a/lib/smp_processor_id.c +++ b/lib/smp_processor_id.c @@ -47,9 +47,9 @@ unsigned int check_preemption_disabled(const char *what1, const char *what2)
printk("caller is %pS\n", __builtin_return_address(0)); dump_stack(); - instrumentation_end();
out_enable: + instrumentation_end(); preempt_enable_no_resched_notrace(); out: return this_cpu;
From: Zhihao Cheng chengzhihao1@huawei.com
[ Upstream commit d919a1e79bac890421537cf02ae773007bf55e6b ]
Commit 7bc3e6e55acf06 ("proc: Use a list of inodes to flush from proc") moved proc_flush_task() behind __exit_signal(). Then, process systemd can take long period high cpu usage during releasing task in following concurrent processes:
systemd ps kernel_waitid stat(/proc/tgid) do_wait filename_lookup wait_consider_task lookup_fast release_task __exit_signal __unhash_process detach_pid __change_pid // remove task->pid_links d_revalidate -> pid_revalidate // 0 d_invalidate(/proc/tgid) shrink_dcache_parent(/proc/tgid) d_walk(/proc/tgid) spin_lock_nested(/proc/tgid/fd) // iterating opened fd proc_flush_pid | d_invalidate (/proc/tgid/fd) | shrink_dcache_parent(/proc/tgid/fd) | shrink_dentry_list(subdirs) ↓ shrink_lock_dentry(/proc/tgid/fd) --> race on dentry lock
Function d_invalidate() will remove dentry from hash firstly, but why does proc_flush_pid() process dentry '/proc/tgid/fd' before dentry '/proc/tgid'? That's because proc_pid_make_inode() adds proc inode in reverse order by invoking hlist_add_head_rcu(). But proc should not add any inodes under '/proc/tgid' except '/proc/tgid/task/pid', fix it by adding inode into 'pid->inodes' only if the inode is /proc/tgid or /proc/tgid/task/pid.
Performance regression: Create 200 tasks, each task open one file for 50,000 times. Kill all tasks when opened files exceed 10,000,000 (cat /proc/sys/fs/file-nr).
Before fix: $ time killall -wq aa real 4m40.946s # During this period, we can see 'ps' and 'systemd' taking high cpu usage.
After fix: $ time killall -wq aa real 1m20.732s # During this period, we can see 'systemd' taking high cpu usage.
Link: https://lkml.kernel.org/r/20220713130029.4133533-1-chengzhihao1@huawei.com Fixes: 7bc3e6e55acf06 ("proc: Use a list of inodes to flush from proc") Link: https://bugzilla.kernel.org/show_bug.cgi?id=216054 Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com Signed-off-by: Zhang Yi yi.zhang@huawei.com Suggested-by: Brian Foster bfoster@redhat.com Reviewed-by: Brian Foster bfoster@redhat.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Eric Biederman ebiederm@xmission.com Cc: Matthew Wilcox willy@infradead.org Cc: Baoquan He bhe@redhat.com Cc: Kalesh Singh kaleshsingh@google.com Cc: Yu Kuai yukuai3@huawei.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/base.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c index 8dfa36a99c74..93f7e3d971e4 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1885,7 +1885,7 @@ void proc_pid_evict_inode(struct proc_inode *ei) put_pid(pid); }
-struct inode *proc_pid_make_inode(struct super_block * sb, +struct inode *proc_pid_make_inode(struct super_block *sb, struct task_struct *task, umode_t mode) { struct inode * inode; @@ -1914,11 +1914,6 @@ struct inode *proc_pid_make_inode(struct super_block * sb,
/* Let the pid remember us for quick removal */ ei->pid = pid; - if (S_ISDIR(mode)) { - spin_lock(&pid->lock); - hlist_add_head_rcu(&ei->sibling_inodes, &pid->inodes); - spin_unlock(&pid->lock); - }
task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid); security_task_to_inode(task, inode); @@ -1931,6 +1926,39 @@ struct inode *proc_pid_make_inode(struct super_block * sb, return NULL; }
+/* + * Generating an inode and adding it into @pid->inodes, so that task will + * invalidate inode's dentry before being released. + * + * This helper is used for creating dir-type entries under '/proc' and + * '/proc/<tgid>/task'. Other entries(eg. fd, stat) under '/proc/<tgid>' + * can be released by invalidating '/proc/<tgid>' dentry. + * In theory, dentries under '/proc/<tgid>/task' can also be released by + * invalidating '/proc/<tgid>' dentry, we reserve it to handle single + * thread exiting situation: Any one of threads should invalidate its + * '/proc/<tgid>/task/<pid>' dentry before released. + */ +static struct inode *proc_pid_make_base_inode(struct super_block *sb, + struct task_struct *task, umode_t mode) +{ + struct inode *inode; + struct proc_inode *ei; + struct pid *pid; + + inode = proc_pid_make_inode(sb, task, mode); + if (!inode) + return NULL; + + /* Let proc_flush_pid find this directory inode */ + ei = PROC_I(inode); + pid = ei->pid; + spin_lock(&pid->lock); + hlist_add_head_rcu(&ei->sibling_inodes, &pid->inodes); + spin_unlock(&pid->lock); + + return inode; +} + int pid_getattr(struct user_namespace *mnt_userns, const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags) { @@ -3369,7 +3397,8 @@ static struct dentry *proc_pid_instantiate(struct dentry * dentry, { struct inode *inode;
- inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO); + inode = proc_pid_make_base_inode(dentry->d_sb, task, + S_IFDIR | S_IRUGO | S_IXUGO); if (!inode) return ERR_PTR(-ENOENT);
@@ -3671,7 +3700,8 @@ static struct dentry *proc_task_instantiate(struct dentry *dentry, struct task_struct *task, const void *ptr) { struct inode *inode; - inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO); + inode = proc_pid_make_base_inode(dentry->d_sb, task, + S_IFDIR | S_IRUGO | S_IXUGO); if (!inode) return ERR_PTR(-ENOENT);
From: Siddharth Gupta sidgup@codeaurora.org
[ Upstream commit 7b6ece968fca4ec9e42d34caff7e06dc84c45717 ]
Client drivers need to check if coredump is enabled for the rproc before continuing with coredump generation. This change adds a check in the PAS driver.
Fixes: 8ed8485c4f05 ("remoteproc: qcom: Add capability to collect minidumps") Signed-off-by: Siddharth Gupta sidgup@codeaurora.org Signed-off-by: Sibi Sankar quic_sibis@quicinc.com Reviewed-by: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/1657022900-2049-5-git-send-email-quic_sibis@quicin... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/remoteproc/qcom_q6v5_pas.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 6ae39c5653b1..1c170d278b29 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -87,6 +87,9 @@ static void adsp_minidump(struct rproc *rproc) { struct qcom_adsp *adsp = rproc->priv;
+ if (rproc->dump_conf == RPROC_COREDUMP_DISABLED) + return; + qcom_minidump(rproc, adsp->minidump_id); }
From: Sibi Sankar quic_sibis@quicinc.com
[ Upstream commit 47c04e00eff86a81cd357c3feed04c86089bcb85 ]
The SSCTL service comes up after a finite time when the remote Q6 comes out of reset. Any graceful shutdowns requested during this period will be a NOP and abrupt tearing down of the glink channel might lead to pending transactions on the remote Q6 side and will ultimately lead to a fatal error. Fix this by waiting for the SSCTL service when a graceful shutdown is requested.
Fixes: 1fb82ee806d1 ("remoteproc: qcom: Introduce sysmon") Reviewed-by: Matthias Kaehlcke mka@chromium.org Signed-off-by: Sibi Sankar quic_sibis@quicinc.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/1657022900-2049-7-git-send-email-quic_sibis@quicin... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/remoteproc/qcom_sysmon.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c index 9fca81492863..a9f04dd83ab6 100644 --- a/drivers/remoteproc/qcom_sysmon.c +++ b/drivers/remoteproc/qcom_sysmon.c @@ -41,6 +41,7 @@ struct qcom_sysmon { struct completion comp; struct completion ind_comp; struct completion shutdown_comp; + struct completion ssctl_comp; struct mutex lock;
bool ssr_ack; @@ -445,6 +446,8 @@ static int ssctl_new_server(struct qmi_handle *qmi, struct qmi_service *svc)
svc->priv = sysmon;
+ complete(&sysmon->ssctl_comp); + return 0; }
@@ -501,6 +504,7 @@ static int sysmon_start(struct rproc_subdev *subdev) .ssr_event = SSCTL_SSR_EVENT_AFTER_POWERUP };
+ reinit_completion(&sysmon->ssctl_comp); mutex_lock(&sysmon->state_lock); sysmon->state = SSCTL_SSR_EVENT_AFTER_POWERUP; blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event); @@ -545,6 +549,11 @@ static void sysmon_stop(struct rproc_subdev *subdev, bool crashed) if (crashed) return;
+ if (sysmon->ssctl_instance) { + if (!wait_for_completion_timeout(&sysmon->ssctl_comp, HZ / 2)) + dev_err(sysmon->dev, "timeout waiting for ssctl service\n"); + } + if (sysmon->ssctl_version) sysmon->shutdown_acked = ssctl_request_shutdown(sysmon); else if (sysmon->ept) @@ -631,6 +640,7 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc, init_completion(&sysmon->comp); init_completion(&sysmon->ind_comp); init_completion(&sysmon->shutdown_comp); + init_completion(&sysmon->ssctl_comp); mutex_init(&sysmon->lock); mutex_init(&sysmon->state_lock);
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 128ac294e1b437cb8a7f2ff8ede1cde9082bddbe ]
None of the in-tree instantiations of struct t7l66xb_platform_data provides a disable callback. So better don't dereference this function pointer unconditionally. As there is no user, drop it completely instead of calling it conditional.
This is a preparation for making platform remove callbacks return void.
Fixes: 1f192015ca5b ("mfd: driver for the T7L66XB TMIO SoC") Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Lee Jones lee.jones@linaro.org Link: https://lore.kernel.org/r/20220530192430.2108217-3-u.kleine-koenig@pengutron... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/t7l66xb.c | 6 +----- include/linux/mfd/t7l66xb.h | 1 - 2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 5369c67e3280..663ffd4b8570 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c @@ -397,11 +397,8 @@ static int t7l66xb_probe(struct platform_device *dev)
static int t7l66xb_remove(struct platform_device *dev) { - struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev); struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - int ret;
- ret = pdata->disable(dev); clk_disable_unprepare(t7l66xb->clk48m); clk_put(t7l66xb->clk48m); clk_disable_unprepare(t7l66xb->clk32k); @@ -412,8 +409,7 @@ static int t7l66xb_remove(struct platform_device *dev) mfd_remove_devices(&dev->dev); kfree(t7l66xb);
- return ret; - + return 0; }
static struct platform_driver t7l66xb_platform_driver = { diff --git a/include/linux/mfd/t7l66xb.h b/include/linux/mfd/t7l66xb.h index 69632c1b07bd..ae3e7a5c5219 100644 --- a/include/linux/mfd/t7l66xb.h +++ b/include/linux/mfd/t7l66xb.h @@ -12,7 +12,6 @@
struct t7l66xb_platform_data { int (*enable)(struct platform_device *dev); - int (*disable)(struct platform_device *dev); int (*suspend)(struct platform_device *dev); int (*resume)(struct platform_device *dev);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 1520669c8255bd637c6b248b2be910e2688d38dd ]
of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: 327156c59360 ("mfd: max77620: Add core driver for MAX77620/MAX20024") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org Link: https://lore.kernel.org/r/20220601043222.64441-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/max77620.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c index fec2096474ad..a6661e07035b 100644 --- a/drivers/mfd/max77620.c +++ b/drivers/mfd/max77620.c @@ -419,9 +419,11 @@ static int max77620_initialise_fps(struct max77620_chip *chip) ret = max77620_config_fps(chip, fps_child); if (ret < 0) { of_node_put(fps_child); + of_node_put(fps_np); return ret; } } + of_node_put(fps_np);
config = chip->enable_global_lpm ? MAX77620_ONOFFCNFG2_SLP_LPM_MSK : 0; ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 393a40b50fe976a121b15752d2dd6151c7a92126 ]
On a number of platforms that contain acp3x controller a new ERR level message is showing up:
`acp6x pci device not found`
This is because ACP3x and ACP6x share same PCI ID but can be identified by PCI revision. As this is expected behavior for a system with ACP3x decrease message to debug.
Fixes: b1630fcbfde6c ("ASoC: amd: yc: add new YC platform varaint support") Cc: Vijendar Mukunda Vijendar.Mukunda@amd.com Signed-off-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20220718213402.19497-1-mario.limonciello@amd.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/amd/yc/pci-acp6x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/amd/yc/pci-acp6x.c b/sound/soc/amd/yc/pci-acp6x.c index 20f7a99783f2..77c5fa1f7af1 100644 --- a/sound/soc/amd/yc/pci-acp6x.c +++ b/sound/soc/amd/yc/pci-acp6x.c @@ -159,7 +159,7 @@ static int snd_acp6x_probe(struct pci_dev *pci, case 0x6f: break; default: - dev_err(&pci->dev, "acp6x pci device not found\n"); + dev_dbg(&pci->dev, "acp6x pci device not found\n"); return -ENODEV; } if (pci_enable_device(pci)) {
From: Liang He windhl@126.com
[ Upstream commit a91eb6803c1c715738682fece095145cbd68fe0b ]
In qcom_iommu_has_secure_context(), we should call of_node_put() for the reference 'child' when breaking out of for_each_child_of_node() which will automatically increase and decrease the refcount.
Fixes: d051f28c8807 ("iommu/qcom: Initialize secure page table") Signed-off-by: Liang He windhl@126.com Link: https://lore.kernel.org/r/20220719124955.1242171-1-windhl@126.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/arm/arm-smmu/qcom_iommu.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c index 4c077c38fbd6..c11d2c2cbb62 100644 --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -750,9 +750,12 @@ static bool qcom_iommu_has_secure_context(struct qcom_iommu_dev *qcom_iommu) { struct device_node *child;
- for_each_child_of_node(qcom_iommu->dev->of_node, child) - if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec")) + for_each_child_of_node(qcom_iommu->dev->of_node, child) { + if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec")) { + of_node_put(child); return true; + } + }
return false; }
From: Adrian Hunter adrian.hunter@intel.com
[ Upstream commit 68566a7cf56bf3148797c218ed45a9de078ef47c ]
Synthesized MMAP events have zero ino_generation, so do not compare them to DSOs with a real ino_generation otherwise we end up with a DSO without a build id.
Fixes: 0e3149f86b99ddab ("perf dso: Move dso_id from 'struct map' to 'struct dso'") Signed-off-by: Adrian Hunter adrian.hunter@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Ian Rogers irogers@google.com Cc: Jiri Olsa jolsa@kernel.org Cc: kvm@vger.kernel.org Cc: Namhyung Kim namhyung@kernel.org Link: https://lore.kernel.org/r/20220711093218.10967-2-adrian.hunter@intel.com [ Added clarification to the comment from Ian + more detailed explanation from Adrian ] Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/dsos.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index b97366f77bbf..2bd23e4cf19e 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -23,8 +23,19 @@ static int __dso_id__cmp(struct dso_id *a, struct dso_id *b) if (a->ino > b->ino) return -1; if (a->ino < b->ino) return 1;
- if (a->ino_generation > b->ino_generation) return -1; - if (a->ino_generation < b->ino_generation) return 1; + /* + * Synthesized MMAP events have zero ino_generation, avoid comparing + * them with MMAP events with actual ino_generation. + * + * I found it harmful because the mismatch resulted in a new + * dso that did not have a build ID whereas the original dso did have a + * build ID. The build ID was essential because the object was not found + * otherwise. - Adrian + */ + if (a->ino_generation && b->ino_generation) { + if (a->ino_generation > b->ino_generation) return -1; + if (a->ino_generation < b->ino_generation) return 1; + }
return 0; }
From: Sunil V L sunilvl@ventanamicro.com
[ Upstream commit c029e487e7c00e5594a4ae946952605db34e359b ]
The hartid variable is of type int but compared with ULONG_MAX(INVALID_HARTID). This issue is fixed by changing the hartid variable type to unsigned long.
Fixes: c78f94f35cf6 ("RISC-V: Use __cpu_up_stack/task_pointer only for spinwait method")
Signed-off-by: Sunil V L sunilvl@ventanamicro.com Reviewed-by: Atish Patra atishp@rivosinc.com Link: https://lore.kernel.org/r/20220527051743.2829940-3-sunilvl@ventanamicro.com Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/kernel/cpu_ops_spinwait.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/kernel/cpu_ops_spinwait.c b/arch/riscv/kernel/cpu_ops_spinwait.c index c662a7cf10a4..d98d19226b5f 100644 --- a/arch/riscv/kernel/cpu_ops_spinwait.c +++ b/arch/riscv/kernel/cpu_ops_spinwait.c @@ -20,7 +20,7 @@ void *__cpu_spinwait_task_pointer[NR_CPUS] __section(".data"); static void cpu_update_secondary_bootdata(unsigned int cpuid, struct task_struct *tidle) { - int hartid = cpuid_to_hartid_map(cpuid); + unsigned long hartid = cpuid_to_hartid_map(cpuid);
/* * The hartid must be less than NR_CPUS to avoid out-of-bound access @@ -29,7 +29,7 @@ static void cpu_update_secondary_bootdata(unsigned int cpuid, * spinwait booting is not the recommended approach for any platforms * booting Linux in S-mode and can be disabled in the future. */ - if (hartid == INVALID_HARTID || hartid >= NR_CPUS) + if (hartid == INVALID_HARTID || hartid >= (unsigned long) NR_CPUS) return;
/* Make sure tidle is updated */
From: Alexander Gordeev agordeev@linux.ibm.com
[ Upstream commit f6749da17a34eb08c9665f072ce7c812ff68aad2 ]
The number of bytes in a chunk is correctly calculated, but instead the total number of bytes is passed to copy_to_user_real() function.
Reported-by: Matthew Wilcox willy@infradead.org Fixes: df9694c7975f ("s390/dump: streamline oldmem copy functions") Signed-off-by: Alexander Gordeev agordeev@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kernel/crash_dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 28124d0fa1d5..f8ebdd70dd31 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -199,7 +199,7 @@ static int copy_oldmem_user(void __user *dst, unsigned long src, size_t count) } else { len = count; } - rc = copy_to_user_real(dst, src, count); + rc = copy_to_user_real(dst, src, len); if (rc) return rc; }
From: Alexander Gordeev agordeev@linux.ibm.com
[ Upstream commit 9ffed254d938c9e99eb7761c7f739294c84e0367 ]
Memory buffer used for reading out data from hardware system area is not protected against concurrent access.
Reported-by: Matthew Wilcox willy@infradead.org Fixes: 411ed3225733 ("[S390] zfcpdump support.") Acked-by: Heiko Carstens hca@linux.ibm.com Tested-by: Alexander Egorenkov egorenar@linux.ibm.com Link: https://lore.kernel.org/r/e68137f0f9a0d2558f37becc20af18e2939934f6.165820689... Signed-off-by: Alexander Gordeev agordeev@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/char/zcore.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 516783ba950f..92b32ce645b9 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -50,6 +50,7 @@ static struct dentry *zcore_reipl_file; static struct dentry *zcore_hsa_file; static struct ipl_parameter_block *zcore_ipl_block;
+static DEFINE_MUTEX(hsa_buf_mutex); static char hsa_buf[PAGE_SIZE] __aligned(PAGE_SIZE);
/* @@ -66,19 +67,24 @@ int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count) if (!hsa_available) return -ENODATA;
+ mutex_lock(&hsa_buf_mutex); while (count) { if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) { TRACE("sclp_sdias_copy() failed\n"); + mutex_unlock(&hsa_buf_mutex); return -EIO; } offset = src % PAGE_SIZE; bytes = min(PAGE_SIZE - offset, count); - if (copy_to_user(dest, hsa_buf + offset, bytes)) + if (copy_to_user(dest, hsa_buf + offset, bytes)) { + mutex_unlock(&hsa_buf_mutex); return -EFAULT; + } src += bytes; dest += bytes; count -= bytes; } + mutex_unlock(&hsa_buf_mutex); return 0; }
@@ -96,9 +102,11 @@ int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) if (!hsa_available) return -ENODATA;
+ mutex_lock(&hsa_buf_mutex); while (count) { if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) { TRACE("sclp_sdias_copy() failed\n"); + mutex_unlock(&hsa_buf_mutex); return -EIO; } offset = src % PAGE_SIZE; @@ -108,6 +116,7 @@ int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) dest += bytes; count -= bytes; } + mutex_unlock(&hsa_buf_mutex); return 0; }
From: Thomas Richter tmricht@linux.ibm.com
[ Upstream commit 87abe344cd280802f431998fabfd35d2d340ca90 ]
Perf test case 83: perf stat CSV output linter might fail on s390. The reason for this is the output of the command
./perf stat -x, -A -a --no-merge true
which depends on a .config file setting. When CONFIG_SCHED_TOPOLOGY is set, the output of above perf command is
CPU0,1.50,msec,cpu-clock,1502781,100.00,1.052,CPUs utilized
When CONFIG_SCHED_TOPOLOGY is *NOT* set the output of above perf command is
0.95,msec,cpu-clock,949800,100.00,1.060,CPUs utilized
Fix the test case to accept both output formats.
Output before: # perf test 83 83: perf stat CSV output linter : FAILED! #
Output after: # ./perf test 83 83: perf stat CSV output linter : Ok #
Fixes: ec906102e5b7d339 ("perf test: Fix "perf stat CSV output linter" test on s390") Signed-off-by: Thomas Richter tmricht@linux.ibm.com Acked-by: Ian Rogers irogers@google.com Acked-by: Sumanth Korikkar sumanthk@linux.ibm.com Cc: Heiko Carstens hca@linux.ibm.com Cc: Sven Schnelle svens@linux.ibm.com Cc: Vasily Gorbik gor@linux.ibm.com Link: https://lore.kernel.org/r/20220720123419.220953-1-tmricht@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/tests/shell/stat+csv_output.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/tools/perf/tests/shell/stat+csv_output.sh b/tools/perf/tests/shell/stat+csv_output.sh index 38c26f3ef4c1..eb5196f58190 100755 --- a/tools/perf/tests/shell/stat+csv_output.sh +++ b/tools/perf/tests/shell/stat+csv_output.sh @@ -8,7 +8,8 @@ set -e
function commachecker() { - local -i cnt=0 exp=0 + local -i cnt=0 + local exp=0
case "$1" in "--no-args") exp=6 @@ -17,7 +18,7 @@ function commachecker() ;; "--interval") exp=7 ;; "--per-thread") exp=7 ;; "--system-wide-no-aggr") exp=7 - [ $(uname -m) = "s390x" ] && exp=6 + [ $(uname -m) = "s390x" ] && exp='^[6-7]$' ;; "--per-core") exp=8 ;; "--per-socket") exp=8 ;; "--per-node") exp=8 @@ -34,7 +35,7 @@ function commachecker() x=$(echo $line | tr -d -c ',') cnt="${#x}" # echo $line $cnt - [ "$cnt" -ne "$exp" ] && { + [[ ! "$cnt" =~ $exp ]] && { echo "wrong number of fields. expected $exp in $line" 1>&2 exit 1; }
From: Shengjiu Wang shengjiu.wang@nxp.com
[ Upstream commit c49932726de24405d45516b3f8ad2735714fdf05 ]
Fix sparse warning: sound/soc/fsl/fsl_asrc.c:1177:60: sparse: warning: incorrect type in argument 3 (different base types) sound/soc/fsl/fsl_asrc.c:1177:60: sparse: expected unsigned int [usertype] *out_value sound/soc/fsl/fsl_asrc.c:1177:60: sparse: got restricted snd_pcm_format_t * sound/soc/fsl/fsl_asrc.c:1200:47: sparse: warning: restricted snd_pcm_format_t degrades to integer
Fixes: 4520af41fd21 ("ASoC: fsl_asrc: Support new property fsl,asrc-format") Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com Link: https://lore.kernel.org/r/1658399393-28777-3-git-send-email-shengjiu.wang@nx... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/fsl_asrc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 20a9f8e924b3..aa5edf32d988 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -1066,6 +1066,7 @@ static int fsl_asrc_probe(struct platform_device *pdev) struct resource *res; void __iomem *regs; int irq, ret, i; + u32 asrc_fmt = 0; u32 map_idx; char tmp[16]; u32 width; @@ -1174,7 +1175,8 @@ static int fsl_asrc_probe(struct platform_device *pdev) return ret; }
- ret = of_property_read_u32(np, "fsl,asrc-format", &asrc->asrc_format); + ret = of_property_read_u32(np, "fsl,asrc-format", &asrc_fmt); + asrc->asrc_format = (__force snd_pcm_format_t)asrc_fmt; if (ret) { ret = of_property_read_u32(np, "fsl,asrc-width", &width); if (ret) { @@ -1197,7 +1199,7 @@ static int fsl_asrc_probe(struct platform_device *pdev) } }
- if (!(FSL_ASRC_FORMATS & (1ULL << asrc->asrc_format))) { + if (!(FSL_ASRC_FORMATS & pcm_format_to_bits(asrc->asrc_format))) { dev_warn(&pdev->dev, "unsupported width, use default S24_LE\n"); asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE; }
From: Shengjiu Wang shengjiu.wang@nxp.com
[ Upstream commit 6c7b077dad62178c33f9a3ae17f90d6b0bf6e2e5 ]
Fix sparse warning: sound/soc/fsl/fsl-asoc-card.c:833:45: sparse: warning: incorrect type in argument 3 (different base types) sound/soc/fsl/fsl-asoc-card.c:833:45: sparse: expected unsigned int [usertype] *out_value sound/soc/fsl/fsl-asoc-card.c:833:45: sparse: got restricted snd_pcm_format_t *
Fixes: 859e364302c5 ("ASoC: fsl-asoc-card: Support new property fsl, asrc-format") Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com Link: https://lore.kernel.org/r/1658399393-28777-4-git-send-email-shengjiu.wang@nx... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/fsl-asoc-card.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index d9a0d4768c4d..c836848ef0a6 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -537,6 +537,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) struct device *codec_dev = NULL; const char *codec_dai_name; const char *codec_dev_name; + u32 asrc_fmt = 0; u32 width; int ret;
@@ -829,8 +830,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) goto asrc_fail; }
- ret = of_property_read_u32(asrc_np, "fsl,asrc-format", - &priv->asrc_format); + ret = of_property_read_u32(asrc_np, "fsl,asrc-format", &asrc_fmt); + priv->asrc_format = (__force snd_pcm_format_t)asrc_fmt; if (ret) { /* Fallback to old binding; translate to asrc_format */ ret = of_property_read_u32(asrc_np, "fsl,asrc-width",
From: Shengjiu Wang shengjiu.wang@nxp.com
[ Upstream commit de27216cf2d645c2fd14e513707bdcd54e5b1de4 ]
Fix sparse warning: sound/soc/fsl/fsl_easrc.c:562:33: sparse: warning: restricted snd_pcm_format_t degrades to integer sound/soc/fsl/fsl_easrc.c:563:34: sparse: warning: restricted snd_pcm_format_t degrades to integer sound/soc/fsl/fsl_easrc.c:565:38: sparse: warning: restricted snd_pcm_format_t degrades to integer sound/soc/fsl/fsl_easrc.c:566:39: sparse: warning: restricted snd_pcm_format_t degrades to integer sound/soc/fsl/fsl_easrc.c:608:33: sparse: warning: restricted snd_pcm_format_t degrades to integer sound/soc/fsl/fsl_easrc.c:609:34: sparse: warning: restricted snd_pcm_format_t degrades to integer sound/soc/fsl/fsl_easrc.c:615:40: sparse: warning: restricted snd_pcm_format_t degrades to integer sound/soc/fsl/fsl_easrc.c:616:41: sparse: warning: restricted snd_pcm_format_t degrades to integer
sound/soc/fsl/fsl_easrc.c:1465:51: sparse: warning: incorrect type in assignment (different base types) sound/soc/fsl/fsl_easrc.c:1465:51: sparse: expected unsigned int sample_format sound/soc/fsl/fsl_easrc.c:1465:51: sparse: got restricted snd_pcm_format_t [usertype] format sound/soc/fsl/fsl_easrc.c:1467:52: sparse: warning: incorrect type in assignment (different base types) sound/soc/fsl/fsl_easrc.c:1467:52: sparse: expected unsigned int sample_format sound/soc/fsl/fsl_easrc.c:1467:52: sparse: got restricted snd_pcm_format_t [usertype] asrc_format sound/soc/fsl/fsl_easrc.c:1470:52: sparse: warning: incorrect type in assignment (different base types) sound/soc/fsl/fsl_easrc.c:1470:52: sparse: expected unsigned int sample_format sound/soc/fsl/fsl_easrc.c:1470:52: sparse: got restricted snd_pcm_format_t [usertype] format sound/soc/fsl/fsl_easrc.c:1472:51: sparse: warning: incorrect type in assignment (different base types) sound/soc/fsl/fsl_easrc.c:1472:51: sparse: expected unsigned int sample_format sound/soc/fsl/fsl_easrc.c:1472:51: sparse: got restricted snd_pcm_format_t [usertype] asrc_format sound/soc/fsl/fsl_easrc.c:1484:41: sparse: warning: incorrect type in argument 2 (different base types) sound/soc/fsl/fsl_easrc.c:1484:41: sparse: expected restricted snd_pcm_format_t [usertype] *in_raw_format sound/soc/fsl/fsl_easrc.c:1484:41: sparse: got unsigned int * sound/soc/fsl/fsl_easrc.c:1485:41: sparse: warning: incorrect type in argument 3 (different base types) sound/soc/fsl/fsl_easrc.c:1485:41: sparse: expected restricted snd_pcm_format_t [usertype] *out_raw_format sound/soc/fsl/fsl_easrc.c:1485:41: sparse: got unsigned int * sound/soc/fsl/fsl_easrc.c:1937:60: sparse: warning: incorrect type in argument 3 (different base types) sound/soc/fsl/fsl_easrc.c:1937:60: sparse: expected unsigned int [usertype] *out_value sound/soc/fsl/fsl_easrc.c:1937:60: sparse: got restricted snd_pcm_format_t * sound/soc/fsl/fsl_easrc.c:1943:49: sparse: warning: restricted snd_pcm_format_t degrades to integer
Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers") Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com Link: https://lore.kernel.org/r/1658399393-28777-5-git-send-email-shengjiu.wang@nx... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/fsl_easrc.c | 9 ++++++--- sound/soc/fsl/fsl_easrc.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index be14f84796cb..cf0e10d17dbe 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -476,7 +476,8 @@ static int fsl_easrc_prefilter_config(struct fsl_asrc *easrc, struct fsl_asrc_pair *ctx; struct device *dev; u32 inrate, outrate, offset = 0; - u32 in_s_rate, out_s_rate, in_s_fmt, out_s_fmt; + u32 in_s_rate, out_s_rate; + snd_pcm_format_t in_s_fmt, out_s_fmt; int ret, i;
if (!easrc) @@ -1873,6 +1874,7 @@ static int fsl_easrc_probe(struct platform_device *pdev) struct resource *res; struct device_node *np; void __iomem *regs; + u32 asrc_fmt = 0; int ret, irq;
easrc = devm_kzalloc(dev, sizeof(*easrc), GFP_KERNEL); @@ -1933,13 +1935,14 @@ static int fsl_easrc_probe(struct platform_device *pdev) return ret; }
- ret = of_property_read_u32(np, "fsl,asrc-format", &easrc->asrc_format); + ret = of_property_read_u32(np, "fsl,asrc-format", &asrc_fmt); + easrc->asrc_format = (__force snd_pcm_format_t)asrc_fmt; if (ret) { dev_err(dev, "failed to asrc format\n"); return ret; }
- if (!(FSL_EASRC_FORMATS & (1ULL << easrc->asrc_format))) { + if (!(FSL_EASRC_FORMATS & (pcm_format_to_bits(easrc->asrc_format)))) { dev_warn(dev, "unsupported format, switching to S24_LE\n"); easrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE; } diff --git a/sound/soc/fsl/fsl_easrc.h b/sound/soc/fsl/fsl_easrc.h index 86d5c360d4f5..7c70dac52713 100644 --- a/sound/soc/fsl/fsl_easrc.h +++ b/sound/soc/fsl/fsl_easrc.h @@ -569,7 +569,7 @@ struct fsl_easrc_io_params { unsigned int access_len; unsigned int fifo_wtmk; unsigned int sample_rate; - unsigned int sample_format; + snd_pcm_format_t sample_format; unsigned int norm_rate; };
From: Shengjiu Wang shengjiu.wang@nxp.com
[ Upstream commit 409a8652e909e323c715f3088e6c3133e37c8881 ]
Fix sparse warning: sound/soc/fsl/imx-card.c:653:59: sparse: warning: incorrect type in assignment (different base types) sound/soc/fsl/imx-card.c:653:59: sparse: expected unsigned int [usertype] asrc_format sound/soc/fsl/imx-card.c:653:59: sparse: got restricted snd_pcm_format_t [usertype] sound/soc/fsl/imx-card.c:655:59: sparse: warning: incorrect type in assignment (different base types) sound/soc/fsl/imx-card.c:655:59: sparse: expected unsigned int [usertype] asrc_format sound/soc/fsl/imx-card.c:655:59: sparse: got restricted snd_pcm_format_t [usertype]
Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver") Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com Link: https://lore.kernel.org/r/1658399393-28777-6-git-send-email-shengjiu.wang@nx... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/imx-card.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c index c0eb218a254b..4a8609b0d700 100644 --- a/sound/soc/fsl/imx-card.c +++ b/sound/soc/fsl/imx-card.c @@ -118,7 +118,7 @@ struct imx_card_data { struct snd_soc_card card; int num_dapm_routes; u32 asrc_rate; - u32 asrc_format; + snd_pcm_format_t asrc_format; };
static struct imx_akcodec_fs_mul ak4458_fs_mul[] = { @@ -474,7 +474,7 @@ static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); snd_mask_none(mask); - snd_mask_set(mask, data->asrc_format); + snd_mask_set(mask, (__force unsigned int)data->asrc_format);
return 0; } @@ -493,6 +493,7 @@ static int imx_card_parse_of(struct imx_card_data *data) struct dai_link_data *link_data; struct of_phandle_args args; int ret, num_links; + u32 asrc_fmt = 0; u32 width;
ret = snd_soc_of_parse_card_name(card, "model"); @@ -639,7 +640,8 @@ static int imx_card_parse_of(struct imx_card_data *data) goto err; }
- ret = of_property_read_u32(args.np, "fsl,asrc-format", &data->asrc_format); + ret = of_property_read_u32(args.np, "fsl,asrc-format", &asrc_fmt); + data->asrc_format = (__force snd_pcm_format_t)asrc_fmt; if (ret) { /* Fallback to old binding; translate to asrc_format */ ret = of_property_read_u32(args.np, "fsl,asrc-width", &width);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 673f58f62ca6fc98979d1cf3fe89c3ff33f29b2e ]
find_first_zero_bit() returns MAX_COPPS_PER_PORT at max here. So 'idx' should be tested with ">=" or the test can't match.
Fixes: 7b20b2be51e1 ("ASoC: qdsp6: q6adm: Add q6adm driver") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/0fca3271649736053eb9649d87e1ca01b056be40.165839412... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/qcom/qdsp6/q6adm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c index 72c5719f1d25..a0678e8cf20a 100644 --- a/sound/soc/qcom/qdsp6/q6adm.c +++ b/sound/soc/qcom/qdsp6/q6adm.c @@ -217,7 +217,7 @@ static struct q6copp *q6adm_alloc_copp(struct q6adm *adm, int port_idx) idx = find_first_zero_bit(&adm->copp_bitmap[port_idx], MAX_COPPS_PER_PORT);
- if (idx > MAX_COPPS_PER_PORT) + if (idx >= MAX_COPPS_PER_PORT) return ERR_PTR(-EBUSY);
c = kzalloc(sizeof(*c), GFP_ATOMIC);
From: Xie Yongji xieyongji@bytedance.com
[ Upstream commit c64797809a64c73497082aa05e401a062ec1af34 ]
The commit 15c8e72e88e0 ("fuse: allow skipping control interface and forced unmount") tries to remove the control interface for virtio-fs since it does not support aborting requests which are being processed. But it doesn't work now.
This patch fixes it by skipping creating the control interface if fuse_conn->no_control is set.
Fixes: 15c8e72e88e0 ("fuse: allow skipping control interface and forced unmount") Signed-off-by: Xie Yongji xieyongji@bytedance.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/fuse/control.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 7cede9a3bc96..247ef4f76761 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -258,7 +258,7 @@ int fuse_ctl_add_conn(struct fuse_conn *fc) struct dentry *parent; char name[32];
- if (!fuse_control_sb) + if (!fuse_control_sb || fc->no_control) return 0;
parent = fuse_control_sb->s_root; @@ -296,7 +296,7 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc) { int i;
- if (!fuse_control_sb) + if (!fuse_control_sb || fc->no_control) return;
for (i = fc->ctl_ndents - 1; i >= 0; i--) {
From: Liang He windhl@126.com
[ Upstream commit 65fb8e2ef3531a6e950060fca6e551c923fb0f0e ]
In asoc_simple_parse_dai(), we should call of_node_put() for the reference returned by of_graph_get_port_parent() in fail path.
Fixes: ae30a694da4c ("ASoC: simple-card-utils: add asoc_simple_card_parse_dai()") Signed-off-by: Liang He windhl@126.com Link: https://lore.kernel.org/r/20220721144308.1301587-1-windhl@126.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/generic/audio-graph-card.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 2b598af8feef..b327372f2e4a 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -158,8 +158,10 @@ static int asoc_simple_parse_dai(struct device_node *ep, * if he unbinded CPU or Codec. */ ret = snd_soc_get_dai_name(&args, &dlc->dai_name); - if (ret < 0) + if (ret < 0) { + of_node_put(node); return ret; + }
dlc->of_node = node;
From: Liang He windhl@126.com
[ Upstream commit 8ebc4dd8250fd1cb5da2869c0fe6ae3686fe41e9 ]
In asoc_simple_parse_dai(), we should call of_node_put() for the reference returned by of_graph_get_port_parent() in fail path.
Fixes: 6e5f68fe3f2d ("ASoC: add Audio Graph Card2 driver") Signed-off-by: Liang He windhl@126.com Link: https://lore.kernel.org/r/20220722141801.1304854-1-windhl@126.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/generic/audio-graph-card2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 5dba7c89007d..a7144defb8fb 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -445,8 +445,10 @@ static int asoc_simple_parse_dai(struct device_node *ep, * if he unbinded CPU or Codec. */ ret = snd_soc_get_dai_name(&args, &dlc->dai_name); - if (ret < 0) + if (ret < 0) { + of_node_put(node); return ret; + }
dlc->of_node = node;
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit 97d5ec548150764946f38632e62e79759832b54b ]
As platform_driver_register() could fail, it should be better to deal with the return value in order to maintain the code consisitency.
Fixes: 27e0fe00a5c6 ("watchdog: f71808e_wdt: refactor to platform device/driver pair") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Reviewed-by: Guenter Roeck linux@roeck-us.net https://lore.kernel.org/r/20220526080303.1005063-1-jiasheng@iscas.ac.cn Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Wim Van Sebroeck wim@linux-watchdog.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/watchdog/f71808e_wdt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c index 7f59c680de25..6a16d3d0bb1e 100644 --- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c @@ -634,7 +634,9 @@ static int __init fintek_wdt_init(void)
pdata.type = ret;
- platform_driver_register(&fintek_wdt_driver); + ret = platform_driver_register(&fintek_wdt_driver); + if (ret) + return ret;
wdt_res.name = "superio port"; wdt_res.flags = IORESOURCE_IO;
linux-stable-mirror@lists.linaro.org